diff options
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r-- | runtime/class_linker.cc | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 62dd4d2110..d2ab81e7cf 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -201,6 +201,22 @@ static void HandleEarlierErroneousStateError(Thread* self, self->AssertPendingException(); } +static void ChangeInterpreterBridgeToNterp(ArtMethod* method, ClassLinker* class_linker) + REQUIRES_SHARED(Locks::mutator_lock_) { + Runtime* runtime = Runtime::Current(); + if (class_linker->IsQuickToInterpreterBridge(method->GetEntryPointFromQuickCompiledCode()) && + CanMethodUseNterp(method)) { + if (method->GetDeclaringClass()->IsVisiblyInitialized() || + !NeedsClinitCheckBeforeCall(method)) { + runtime->GetInstrumentation()->UpdateMethodsCode(method, interpreter::GetNterpEntryPoint()); + } else { + // Put the resolution stub, which will initialize the class and then + // call the method with nterp. + runtime->GetInstrumentation()->UpdateMethodsCode(method, GetQuickResolutionStub()); + } + } +} + static void UpdateClassAfterVerification(Handle<mirror::Class> klass, PointerSize pointer_size, verifier::FailureKind failure_kind) @@ -215,9 +231,7 @@ static void UpdateClassAfterVerification(Handle<mirror::Class> klass, // to methods that currently use the switch interpreter. if (interpreter::CanRuntimeUseNterp()) { for (ArtMethod& m : klass->GetMethods(pointer_size)) { - if (class_linker->IsQuickToInterpreterBridge(m.GetEntryPointFromQuickCompiledCode())) { - runtime->GetInstrumentation()->InitializeMethodsCode(&m, /*aot_code=*/nullptr); - } + ChangeInterpreterBridgeToNterp(&m, class_linker); } } } @@ -1959,11 +1973,10 @@ bool ClassLinker::AddImageSpace( // reset it with the runtime value. method.ResetCounter(hotness_threshold); } + // Set image methods' entry point that point to the interpreter bridge to the + // nterp entry point. if (method.GetEntryPointFromQuickCompiledCode() == nterp_trampoline_) { if (can_use_nterp) { - // Set image methods' entry point that point to the nterp trampoline to the - // nterp entry point. This allows taking the fast path when doing a - // nterp->nterp call. DCHECK(!NeedsClinitCheckBeforeCall(&method) || method.GetDeclaringClass()->IsVisiblyInitialized()); method.SetEntryPointFromQuickCompiledCode(interpreter::GetNterpEntryPoint()); @@ -3340,7 +3353,6 @@ void ClassLinker::FixupStaticTrampolines(Thread* self, ObjPtr<mirror::Class> kla return; } - instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); // Link the code of methods skipped by LinkCode. for (size_t method_index = 0; method_index < num_direct_methods; ++method_index) { ArtMethod* method = klass->GetDirectMethod(method_index, pointer_size); @@ -3348,6 +3360,7 @@ void ClassLinker::FixupStaticTrampolines(Thread* self, ObjPtr<mirror::Class> kla // Only update static methods. continue; } + instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation(); instrumentation->UpdateMethodsCode(method, instrumentation->GetCodeForInvoke(method)); } // Ignore virtual methods on the iterator. @@ -9643,6 +9656,14 @@ const void* ClassLinker::GetRuntimeQuickGenericJniStub() const { return GetQuickGenericJniStub(); } +void ClassLinker::SetEntryPointsToInterpreter(ArtMethod* method) const { + if (!method->IsNative()) { + method->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge()); + } else { + method->SetEntryPointFromQuickCompiledCode(GetQuickGenericJniStub()); + } +} + void ClassLinker::SetEntryPointsForObsoleteMethod(ArtMethod* method) const { DCHECK(method->IsObsolete()); // We cannot mess with the entrypoints of native methods because they are used to determine how |