diff options
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r-- | runtime/class_linker.cc | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 57dbd6d259..5a94f57bb6 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -408,6 +408,15 @@ void ClassLinker::ForceClassInitialized(Thread* self, Handle<mirror::Class> klas MakeInitializedClassesVisiblyInitialized(self, /*wait=*/true); } +const void* ClassLinker::FindBootJniStub(JniStubKey key) { + auto it = boot_image_jni_stubs_.find(key); + if (it == boot_image_jni_stubs_.end()) { + return nullptr; + } else { + return it->second; + } +} + ClassLinker::VisiblyInitializedCallback* ClassLinker::MarkClassInitialized( Thread* self, Handle<mirror::Class> klass) { if (kRuntimeISA == InstructionSet::kX86 || kRuntimeISA == InstructionSet::kX86_64) { @@ -616,6 +625,8 @@ ClassLinker::ClassLinker(InternTable* intern_table, bool fast_class_not_found_ex visibly_initialize_classes_with_membarier_(RegisterMemBarrierForClassInitialization()), critical_native_code_with_clinit_check_lock_("critical native code with clinit check lock"), critical_native_code_with_clinit_check_(), + boot_image_jni_stubs_(JniStubKeyHash(Runtime::Current()->GetInstructionSet()), + JniStubKeyEquals(Runtime::Current()->GetInstructionSet())), cha_(Runtime::Current()->IsAotCompiler() ? nullptr : new ClassHierarchyAnalysis()) { // For CHA disabled during Aot, see b/34193647. @@ -1437,6 +1448,16 @@ bool ClassLinker::InitFromBootImage(std::string* error_msg) { error_msg)) { return false; } + for (gc::space::ImageSpace* space : spaces) { + const ImageHeader& header = space->GetImageHeader(); + header.VisitJniStubMethods([&](ArtMethod* method) + REQUIRES_SHARED(Locks::mutator_lock_) { + const void* stub = method->GetOatMethodQuickCode(image_pointer_size_); + boot_image_jni_stubs_.Put(std::make_pair(JniStubKey(method), stub)); + return method; + }, space->Begin(), image_pointer_size_); + } + InitializeObjectVirtualMethodHashes(GetClassRoot<mirror::Object>(this), image_pointer_size_, ArrayRef<uint32_t>(object_virtual_method_hashes_)); @@ -3678,7 +3699,15 @@ void ClassLinker::FixupStaticTrampolines(Thread* self, ObjPtr<mirror::Class> kla for (size_t method_index = 0; method_index < num_direct_methods; ++method_index) { ArtMethod* method = klass->GetDirectMethod(method_index, pointer_size); if (method->NeedsClinitCheckBeforeCall()) { - instrumentation->UpdateMethodsCode(method, instrumentation->GetCodeForInvoke(method)); + const void* quick_code = instrumentation->GetCodeForInvoke(method); + if (method->IsNative() && IsQuickGenericJniStub(quick_code)) { + const void* boot_jni_stub = FindBootJniStub(method); + if (boot_jni_stub != nullptr) { + // Use boot JNI stub if found. + quick_code = boot_jni_stub; + } + } + instrumentation->UpdateMethodsCode(method, quick_code); } } // Ignore virtual methods on the iterator. @@ -3722,6 +3751,13 @@ static void LinkCode(ClassLinker* class_linker, const OatFile::OatMethod oat_method = oat_class->GetOatMethod(class_def_method_index); quick_code = oat_method.GetQuickCode(); } + if (method->IsNative() && quick_code == nullptr) { + const void* boot_jni_stub = class_linker->FindBootJniStub(method); + if (boot_jni_stub != nullptr) { + // Use boot JNI stub if found. + quick_code = boot_jni_stub; + } + } runtime->GetInstrumentation()->InitializeMethodsCode(method, quick_code); if (method->IsNative()) { |