diff options
author | 2016-07-29 09:51:58 -0700 | |
---|---|---|
committer | 2016-08-16 20:19:36 +0000 | |
commit | 9d4b6da934934c322536ee3309b63ce402740f49 (patch) | |
tree | 9e7ee5023d6036b98e0560411bb0527efdedca01 /compiler/driver/compiler_driver.cc | |
parent | 2af1aa066e3d20edd8fea5d5b6dbbbad73102d52 (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.cc | 35 |
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); } |