summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r--runtime/class_linker.cc38
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()) {