summaryrefslogtreecommitdiff
path: root/compiler/driver/compiler_driver.cc
diff options
context:
space:
mode:
author Igor Murashkin <iam@google.com> 2016-07-29 09:51:58 -0700
committer Igor Murashkin <iam@google.com> 2016-08-16 20:19:36 +0000
commit9d4b6da934934c322536ee3309b63ce402740f49 (patch)
tree9e7ee5023d6036b98e0560411bb0527efdedca01 /compiler/driver/compiler_driver.cc
parent2af1aa066e3d20edd8fea5d5b6dbbbad73102d52 (diff)
jni: Fast path for @FastNative annotated java methods
Adds a faster path for java methods annotated with dalvik.annotation.optimization.FastNative . Intended to replace usage of fast JNI (registering with "!(FOO)BAR" descriptors). Performance Microbenchmark Results (Angler): * Regular JNI cost in nanoseconds: 115 * Fast JNI cost in nanoseconds: 60 * @FastNative cost in nanoseconds: 36 Summary: Up to 67% faster (vs fast jni) JNI transition cost Change-Id: Ic23823ae0f232270c068ec999fd89aa993894b0e
Diffstat (limited to 'compiler/driver/compiler_driver.cc')
-rw-r--r--compiler/driver/compiler_driver.cc35
1 files changed, 33 insertions, 2 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index d0a8335a99..758cd936a2 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -599,7 +599,38 @@ static void CompileMethod(Thread* self,
InstructionSetHasGenericJniStub(driver->GetInstructionSet())) {
// Leaving this empty will trigger the generic JNI version
} else {
- compiled_method = driver->GetCompiler()->JniCompile(access_flags, method_idx, dex_file);
+ // Look-up the ArtMethod associated with this code_item (if any)
+ // -- It is later used to lookup any [optimization] annotations for this method.
+ ScopedObjectAccess soa(self);
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::ClassLoader> class_loader_handle(hs.NewHandle(
+ soa.Decode<mirror::ClassLoader*>(class_loader)));
+
+ // TODO: Lookup annotation from DexFile directly without resolving method.
+ ArtMethod* method =
+ Runtime::Current()->GetClassLinker()->ResolveMethod<ClassLinker::kNoICCECheckForCache>(
+ dex_file,
+ method_idx,
+ dex_cache,
+ class_loader_handle,
+ /* referrer */ nullptr,
+ invoke_type);
+
+ bool fast_native = false;
+ if (LIKELY(method != nullptr)) {
+ fast_native = method->IsAnnotatedWithFastNative();
+ } else {
+ // Failed method resolutions happen very rarely, e.g. ancestor class cannot be resolved.
+ DCHECK(self->IsExceptionPending());
+ self->ClearException();
+ }
+
+ Compiler::JniOptimizationFlags optimization_flags =
+ fast_native ? Compiler::kFastNative : Compiler::kNone;
+ compiled_method = driver->GetCompiler()->JniCompile(access_flags,
+ method_idx,
+ dex_file,
+ optimization_flags);
CHECK(compiled_method != nullptr);
}
} else if ((access_flags & kAccAbstract) != 0) {
@@ -2874,7 +2905,7 @@ bool CompilerDriver::IsStringTypeIndex(uint16_t type_index, const DexFile* dex_f
bool CompilerDriver::IsStringInit(uint32_t method_index, const DexFile* dex_file, int32_t* offset) {
DexFileMethodInliner* inliner = GetMethodInlinerMap()->GetMethodInliner(dex_file);
- PointerSize pointer_size = InstructionSetPointerSize(GetInstructionSet());
+ const PointerSize pointer_size = InstructionSetPointerSize(GetInstructionSet());
*offset = inliner->GetOffsetForStringInit(method_index, pointer_size);
return inliner->IsStringInitMethodIndex(method_index);
}