diff options
-rw-r--r-- | compiler/common_compiler_test.cc | 7 | ||||
-rw-r--r-- | dex2oat/driver/compiler_driver_test.cc | 7 | ||||
-rw-r--r-- | openjdkjvmti/events.cc | 2 | ||||
-rw-r--r-- | openjdkjvmti/ti_redefine.cc | 4 | ||||
-rw-r--r-- | runtime/class_linker.cc | 40 | ||||
-rw-r--r-- | runtime/common_runtime_test.cc | 2 | ||||
-rw-r--r-- | runtime/gc/heap.h | 3 | ||||
-rw-r--r-- | runtime/instrumentation-inl.h | 129 | ||||
-rw-r--r-- | runtime/instrumentation.cc | 39 | ||||
-rw-r--r-- | runtime/instrumentation.h | 21 | ||||
-rw-r--r-- | runtime/jit/jit_code_cache.cc | 10 | ||||
-rw-r--r-- | runtime/quick_exception_handler.cc | 3 | ||||
-rw-r--r-- | runtime/runtime.cc | 6 | ||||
-rw-r--r-- | runtime/runtime_callbacks_test.cc | 2 | ||||
-rw-r--r-- | test/common/runtime_state.cc | 2 |
15 files changed, 203 insertions, 74 deletions
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc index f24406e599..26800637fa 100644 --- a/compiler/common_compiler_test.cc +++ b/compiler/common_compiler_test.cc @@ -32,6 +32,7 @@ #include "driver/compiled_code_storage.h" #include "driver/compiler_options.h" #include "jni/java_vm_ext.h" +#include "instrumentation-inl.h" #include "interpreter/interpreter.h" #include "mirror/class-inl.h" #include "mirror/class_loader.h" @@ -306,7 +307,11 @@ void CommonCompilerTestImpl::CompileMethod(ArtMethod* method) { storage.GetStackMap(), storage.GetInstructionSet()); LOG(INFO) << "MakeExecutable " << method->PrettyMethod() << " code=" << method_code; - GetRuntime()->GetInstrumentation()->InitializeMethodsCode(method, /*aot_code=*/ method_code); + instrumentation::Instrumentation* instr = GetRuntime()->GetInstrumentation(); + const void* entrypoint = instr->GetInitialEntrypoint(method->GetAccessFlags(), method_code); + CHECK(!instr->IsForcedInterpretOnly()); + CHECK(!instr->EntryExitStubsInstalled()); + instr->UpdateMethodsCode(method, entrypoint); } } diff --git a/dex2oat/driver/compiler_driver_test.cc b/dex2oat/driver/compiler_driver_test.cc index 7d4c32b25c..5dc6589d53 100644 --- a/dex2oat/driver/compiler_driver_test.cc +++ b/dex2oat/driver/compiler_driver_test.cc @@ -31,6 +31,7 @@ #include "dex/dex_file_types.h" #include "gc/heap.h" #include "handle_scope-inl.h" +#include "instrumentation-inl.h" #include "mirror/class-inl.h" #include "mirror/class_loader.h" #include "mirror/dex_cache-inl.h" @@ -93,7 +94,11 @@ class CompilerDriverTest : public CommonCompilerDriverTest { LOG(INFO) << "MakeExecutable " << method->PrettyMethod() << " code=" << method_code; } } - runtime_->GetInstrumentation()->InitializeMethodsCode(method, /*aot_code=*/ method_code); + instrumentation::Instrumentation* instr = runtime_->GetInstrumentation(); + const void* entrypoint = instr->GetInitialEntrypoint(method->GetAccessFlags(), method_code); + CHECK(!instr->IsForcedInterpretOnly()); + CHECK(!instr->EntryExitStubsInstalled()); + instr->UpdateMethodsCode(method, entrypoint); } void MakeDexFileExecutable(jobject class_loader, const DexFile& dex_file) { diff --git a/openjdkjvmti/events.cc b/openjdkjvmti/events.cc index 31107d08a5..a1e9a3dcf4 100644 --- a/openjdkjvmti/events.cc +++ b/openjdkjvmti/events.cc @@ -1251,7 +1251,7 @@ void EventHandler::HandleLocalAccessCapabilityAdded() { continue; } else if (!runtime_->GetClassLinker()->IsQuickToInterpreterBridge(code) && !runtime_->IsAsyncDeoptimizeable(&m, reinterpret_cast<uintptr_t>(code))) { - runtime_->GetInstrumentation()->InitializeMethodsCode(&m, /*aot_code=*/ nullptr); + runtime_->GetInstrumentation()->ReinitializeMethodsCode(&m); } } return true; diff --git a/openjdkjvmti/ti_redefine.cc b/openjdkjvmti/ti_redefine.cc index db9ad2417b..8e7885a726 100644 --- a/openjdkjvmti/ti_redefine.cc +++ b/openjdkjvmti/ti_redefine.cc @@ -2135,7 +2135,7 @@ art::ObjPtr<art::mirror::Class> Redefiner::ClassRedefinition::AllocateNewClassOb } // Finish setting up methods. linked_class->VisitMethods([&](art::ArtMethod* m) REQUIRES_SHARED(art::Locks::mutator_lock_) { - driver_->runtime_->GetInstrumentation()->InitializeMethodsCode(m, /* aot_code= */ nullptr); + driver_->runtime_->GetInstrumentation()->ReinitializeMethodsCode(m); m->SetNotIntrinsic(); DCHECK(m->IsCopied() || m->GetDeclaringClass() == linked_class.Get()) << m->PrettyMethod() @@ -2573,7 +2573,7 @@ void Redefiner::ClassRedefinition::UpdateMethods(art::ObjPtr<art::mirror::Class> CHECK(method_id != nullptr); uint32_t dex_method_idx = dex_file_->GetIndexForMethodId(*method_id); method.SetDexMethodIndex(dex_method_idx); - driver_->runtime_->GetInstrumentation()->InitializeMethodsCode(&method, /*aot_code=*/ nullptr); + driver_->runtime_->GetInstrumentation()->ReinitializeMethodsCode(&method); if (method.HasCodeItem()) { method.SetCodeItem( dex_file_->GetCodeItem(dex_file_->FindCodeItemOffset(class_def, dex_method_idx))); diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 078a5c8383..6418c1a885 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -96,6 +96,7 @@ #include "hidden_api.h" #include "imt_conflict_table.h" #include "imtable-inl.h" +#include "instrumentation-inl.h" #include "intern_table-inl.h" #include "interpreter/interpreter.h" #include "interpreter/mterp/nterp.h" @@ -228,7 +229,7 @@ static void UpdateClassAfterVerification(Handle<mirror::Class> klass, if (interpreter::CanRuntimeUseNterp()) { for (ArtMethod& m : klass->GetMethods(pointer_size)) { if (class_linker->IsQuickToInterpreterBridge(m.GetEntryPointFromQuickCompiledCode())) { - runtime->GetInstrumentation()->InitializeMethodsCode(&m, /*aot_code=*/nullptr); + runtime->GetInstrumentation()->ReinitializeMethodsCode(&m); } } } @@ -3958,7 +3959,7 @@ class ClassLinker::LoadClassHelper { PointerSize pointer_size, LengthPrefixedArray<ArtField>* fields, LengthPrefixedArray<ArtMethod>* methods) - REQUIRES_SHARED(Locks::mutator_lock_); + REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Roles::uninterruptible_); uint32_t NumFields() const { return dchecked_integral_cast<uint32_t>(fields_.size()); @@ -4003,7 +4004,7 @@ class ClassLinker::LoadClassHelper { template <PointerSize kPointerSize> ALWAYS_INLINE void FillMethods(ObjPtr<mirror::Class> klass, /*out*/ LengthPrefixedArray<ArtMethod>* methods) - REQUIRES_SHARED(Locks::mutator_lock_); + REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Roles::uninterruptible_); Runtime* const runtime_; const DexFile& dex_file_; @@ -4135,28 +4136,29 @@ inline void ClassLinker::LoadClassHelper::LinkCode(ArtMethodData* method, // Method shouldn't have already been linked. DCHECK_EQ(method->entrypoint, nullptr); - if (!ArtMethod::IsInvokable(method->access_flags)) { + uint32_t access_flags = method->access_flags; + if (!ArtMethod::IsInvokable(access_flags)) { method->entrypoint = GetQuickToInterpreterBridge(); occi->SkipAbstract(class_def_method_index); return; } const void* quick_code = occi->GetAndAdvance(class_def_method_index); - if (ArtMethod::IsNative(method->access_flags) && quick_code == nullptr) { + if (ArtMethod::IsNative(access_flags) && quick_code == nullptr) { std::string_view shorty = dex_file_.GetMethodShortyView(method->dex_method_index); - const void* boot_jni_stub = - runtime_->GetClassLinker()->FindBootJniStub(method->access_flags, shorty); + const void* boot_jni_stub = runtime_->GetClassLinker()->FindBootJniStub(access_flags, shorty); if (boot_jni_stub != nullptr) { // Use boot JNI stub if found. quick_code = boot_jni_stub; } } - method->entrypoint = quick_code; + method->entrypoint = + runtime_->GetInstrumentation()->GetInitialEntrypoint(access_flags, quick_code); - if (ArtMethod::IsNative(method->access_flags)) { + if (ArtMethod::IsNative(access_flags)) { // Set up the dlsym lookup stub. Do not go through `UnregisterNative()` // as the extra processing for @CriticalNative is not needed yet. - method->data = ArtMethod::IsCriticalNative(method->access_flags) + method->data = ArtMethod::IsCriticalNative(access_flags) ? GetJniDlsymLookupCriticalStub() : GetJniDlsymLookupStub(); } @@ -4278,8 +4280,12 @@ void ClassLinker::LoadClassHelper::FillMethods(ObjPtr<mirror::Class> klass, DCHECK_EQ(methods_.size(), (methods != nullptr) ? methods->size() : 0u); static constexpr size_t kMethodAlignment = ArtMethod::Alignment(kPointerSize); static constexpr size_t kMethodSize = ArtMethod::Size(kPointerSize); - instrumentation::Instrumentation* instr = - is_aot_compiler_ ? nullptr : runtime_->GetInstrumentation(); + instrumentation::Instrumentation* instr = nullptr; + bool use_stubs = false; + if (!is_aot_compiler_) { + instr = runtime_->GetInstrumentation(); + use_stubs = instr->InitialEntrypointNeedsInstrumentationStubs(); + } for (size_t i = 0, size = methods_.size(); i != size; ++i) { const ArtMethodData& src = methods_[i]; ArtMethod* dst = &methods->At(i, kMethodSize, kMethodAlignment); @@ -4305,12 +4311,12 @@ void ClassLinker::LoadClassHelper::FillMethods(ObjPtr<mirror::Class> klass, dst->SetDataPtrSize(src.data, kPointerSize); if (instr != nullptr) { DCHECK_IMPLIES(dst->IsNative(), dst->GetEntryPointFromJniPtrSize(kPointerSize) == src.data); - if (ArtMethod::IsInvokable(access_flags)) { - instr->InitializeMethodsCode(dst, src.entrypoint); - } else { - DCHECK_EQ(src.entrypoint, GetQuickToInterpreterBridge()); - dst->SetEntryPointFromQuickCompiledCodePtrSize(src.entrypoint, kPointerSize); + const void* entrypoint = src.entrypoint; + if (UNLIKELY(use_stubs)) { + bool is_native = ArtMethod::IsNative(access_flags); + entrypoint = is_native ? GetQuickGenericJniStub() : GetQuickToInterpreterBridge(); } + instr->InitializeMethodsCode(dst, entrypoint, kPointerSize); } } } diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc index ab7ddbcb25..fba0f1c758 100644 --- a/runtime/common_runtime_test.cc +++ b/runtime/common_runtime_test.cc @@ -412,7 +412,7 @@ void CommonRuntimeTestImpl::SetUpRuntimeOptionsForFillHeap(RuntimeOptions *optio void CommonRuntimeTestImpl::MakeInterpreted(ObjPtr<mirror::Class> klass) { PointerSize pointer_size = class_linker_->GetImagePointerSize(); for (ArtMethod& method : klass->GetMethods(pointer_size)) { - Runtime::Current()->GetInstrumentation()->InitializeMethodsCode(&method, /*aot_code=*/ nullptr); + Runtime::Current()->GetInstrumentation()->ReinitializeMethodsCode(&method); } } diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h index 5d9fb1b647..7e30c3d14e 100644 --- a/runtime/gc/heap.h +++ b/runtime/gc/heap.h @@ -722,8 +722,7 @@ class Heap { EXPORT bool ObjectIsInBootImageSpace(ObjPtr<mirror::Object> obj) const REQUIRES_SHARED(Locks::mutator_lock_); - bool IsInBootImageOatFile(const void* p) const - REQUIRES_SHARED(Locks::mutator_lock_); + bool IsInBootImageOatFile(const void* p) const; // Get the start address of the boot images if any; otherwise returns 0. uint32_t GetBootImagesStartAddress() const { diff --git a/runtime/instrumentation-inl.h b/runtime/instrumentation-inl.h new file mode 100644 index 0000000000..3b035ea71b --- /dev/null +++ b/runtime/instrumentation-inl.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_RUNTIME_INSTRUMENTATION_INL_H_ +#define ART_RUNTIME_INSTRUMENTATION_INL_H_ + +#include "instrumentation.h" + +#include "art_method-inl.h" +#include "entrypoints/runtime_asm_entrypoints.h" +#include "gc/heap.h" +#include "jit/jit.h" +#include "runtime.h" + +namespace art HIDDEN { +namespace instrumentation { + +inline bool Instrumentation::CanUseAotCode(const void* quick_code) { + if (quick_code == nullptr) { + return false; + } + Runtime* runtime = Runtime::Current(); + // For simplicity, we never use AOT code for debuggable. + if (runtime->IsJavaDebuggable()) { + return false; + } + + if (runtime->IsNativeDebuggable()) { + DCHECK(runtime->UseJitCompilation() && runtime->GetJit()->JitAtFirstUse()); + // If we are doing native debugging, ignore application's AOT code, + // since we want to JIT it (at first use) with extra stackmaps for native + // debugging. We keep however all AOT code from the boot image, + // since the JIT-at-first-use is blocking and would result in non-negligible + // startup performance impact. + return runtime->GetHeap()->IsInBootImageOatFile(quick_code); + } + + return true; +} + +inline const void* Instrumentation::GetInitialEntrypoint(uint32_t method_access_flags, + const void* aot_code) { + if (!ArtMethod::IsInvokable(method_access_flags)) { + return GetQuickToInterpreterBridge(); + } + + // Special case if we need an initialization check. + if (ArtMethod::NeedsClinitCheckBeforeCall(method_access_flags)) { + // If we have code but the method needs a class initialization check before calling that code, + // install the resolution stub that will perform the check. It will be replaced by the proper + // entry point by `ClassLinker::FixupStaticTrampolines()` after initializing class. + // Note: This mimics the logic in image_writer.cc that installs the resolution stub only + // if we have compiled code or we can execute nterp, and the method needs a class + // initialization check. + return (aot_code != nullptr || ArtMethod::IsNative(method_access_flags)) + ? GetQuickResolutionStub() + : GetQuickToInterpreterBridge(); + } + + // Use the provided AOT code if possible. + if (CanUseAotCode(aot_code)) { + return aot_code; + } + + // Use default entrypoints. + return ArtMethod::IsNative(method_access_flags) ? GetQuickGenericJniStub() + : GetQuickToInterpreterBridge(); +} + + +inline bool Instrumentation::InitialEntrypointNeedsInstrumentationStubs() { + return IsForcedInterpretOnly() || EntryExitStubsInstalled(); +} + +inline void Instrumentation::InitializeMethodsCode(ArtMethod* method, + const void* entrypoint, + PointerSize pointer_size) { + if (kIsDebugBuild) { + // Entrypoint should be uninitialized. + CHECK(method->GetEntryPointFromQuickCompiledCodePtrSize(pointer_size) == nullptr) + << method->PrettyMethod(); + // We initialize the entrypoint while loading the class, well before the class + // is verified and Nterp entrypoint is allowed. We prefer to check for resolved + // because a verified class may lose its "verified" status (by becoming erroneous) + // but the resolved status is always kept (as "resolved erroneous" if needed). + CHECK(!method->GetDeclaringClass()->IsResolved()); + CHECK_NE(entrypoint, interpreter::GetNterpEntryPoint()) << method->PrettyMethod(); + if (InitialEntrypointNeedsInstrumentationStubs()) { + const void* expected = + method->IsNative() ? GetQuickGenericJniStub() : GetQuickToInterpreterBridge(); + CHECK_EQ(entrypoint, expected) << method->PrettyMethod() << " " << method->IsNative(); + } else if (method->NeedsClinitCheckBeforeCall()) { + if (method->IsNative()) { + CHECK_EQ(entrypoint, GetQuickResolutionStub()); + } else { + // We do not have the original `aot_code` to determine which entrypoint to expect. + CHECK(entrypoint == GetQuickResolutionStub() || + entrypoint == GetQuickToInterpreterBridge()); + } + } else { + bool is_stub = (entrypoint == GetQuickToInterpreterBridge()) || + (entrypoint == GetQuickGenericJniStub()) || + (entrypoint == GetQuickResolutionStub()); + const void* aot_code = is_stub ? nullptr : entrypoint; + const void* initial = GetInitialEntrypoint(method->GetAccessFlags(), aot_code); + CHECK_EQ(initial, entrypoint) + << method->PrettyMethod() << " 0x" << std::hex << method->GetAccessFlags(); + } + } + method->SetEntryPointFromQuickCompiledCodePtrSize(entrypoint, pointer_size); +} + +} // namespace instrumentation +} // namespace art + +#endif // ART_RUNTIME_INSTRUMENTATION_INL_H_ diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc index ce740da1a8..28c4f35db3 100644 --- a/runtime/instrumentation.cc +++ b/runtime/instrumentation.cc @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "instrumentation.h" +#include "instrumentation-inl.h" #include <functional> #include <optional> @@ -315,37 +315,13 @@ bool Instrumentation::InterpretOnly(ArtMethod* method) REQUIRES_SHARED(Locks::mu return InterpretOnly() || IsDeoptimized(method); } -static bool CanUseAotCode(const void* quick_code) - REQUIRES_SHARED(Locks::mutator_lock_) { - if (quick_code == nullptr) { - return false; - } - Runtime* runtime = Runtime::Current(); - // For simplicity, we never use AOT code for debuggable. - if (runtime->IsJavaDebuggable()) { - return false; - } - - if (runtime->IsNativeDebuggable()) { - DCHECK(runtime->UseJitCompilation() && runtime->GetJit()->JitAtFirstUse()); - // If we are doing native debugging, ignore application's AOT code, - // since we want to JIT it (at first use) with extra stackmaps for native - // debugging. We keep however all AOT code from the boot image, - // since the JIT-at-first-use is blocking and would result in non-negligible - // startup performance impact. - return runtime->GetHeap()->IsInBootImageOatFile(quick_code); - } - - return true; -} - static bool CanUseNterp(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) { return interpreter::CanRuntimeUseNterp() && CanMethodUseNterp(method) && method->IsDeclaringClassVerifiedMayBeDead(); } -static const void* GetOptimizedCodeFor(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) { +const void* Instrumentation::GetOptimizedCodeFor(ArtMethod* method) { DCHECK(!Runtime::Current()->GetInstrumentation()->InterpretOnly(method)); CHECK(method->IsInvokable()) << method->PrettyMethod(); if (method->IsProxyMethod()) { @@ -378,8 +354,7 @@ static const void* GetOptimizedCodeFor(ArtMethod* method) REQUIRES_SHARED(Locks: return method->IsNative() ? GetQuickGenericJniStub() : GetQuickToInterpreterBridge(); } -void Instrumentation::InitializeMethodsCode(ArtMethod* method, const void* aot_code) - REQUIRES_SHARED(Locks::mutator_lock_) { +void Instrumentation::ReinitializeMethodsCode(ArtMethod* method) { if (!method->IsInvokable()) { DCHECK(method->GetEntryPointFromQuickCompiledCode() == nullptr || Runtime::Current()->GetClassLinker()->IsQuickToInterpreterBridge( @@ -405,7 +380,7 @@ void Instrumentation::InitializeMethodsCode(ArtMethod* method, const void* aot_c // Note: this mimics the logic in image_writer.cc that installs the resolution // stub only if we have compiled code or we can execute nterp, and the method needs a class // initialization check. - if (aot_code != nullptr || method->IsNative() || CanUseNterp(method)) { + if (method->IsNative() || CanUseNterp(method)) { if (kIsDebugBuild && CanUseNterp(method)) { // Adds some test coverage for the nterp clinit entrypoint. UpdateEntryPoints(method, interpreter::GetNterpWithClinitEntryPoint()); @@ -418,12 +393,6 @@ void Instrumentation::InitializeMethodsCode(ArtMethod* method, const void* aot_c return; } - // Use the provided AOT code if possible. - if (CanUseAotCode(aot_code)) { - UpdateEntryPoints(method, aot_code); - return; - } - // We check if the class is verified as we need the slow interpreter for lock verification. // If the class is not verified, This will be updated in // ClassLinker::UpdateClassAfterVerification. diff --git a/runtime/instrumentation.h b/runtime/instrumentation.h index 59e6b29b90..5112f0e789 100644 --- a/runtime/instrumentation.h +++ b/runtime/instrumentation.h @@ -322,8 +322,22 @@ class Instrumentation { // Returns a string representation of the given entry point. static std::string EntryPointString(const void* code); - // Initialize the entrypoint of the method .`aot_code` is the AOT code. - EXPORT void InitializeMethodsCode(ArtMethod* method, const void* aot_code) + // Return the best initial entrypoint of a method, assuming that stubs are not in use. + // This function can be called while the thread is suspended. + const void* GetInitialEntrypoint(uint32_t method_access_flags, const void* aot_code); + + // Check if the best initial entrypoint needs to be overridden with stubs. + bool InitialEntrypointNeedsInstrumentationStubs() + REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Roles::uninterruptible_); + + // Initialize the method's entrypoint with aot code or runtime stub. + // The caller must check and apply `InitialEntrypointNeedsInstrumentationStubs()` + // in the same `Roles::uninterruptible_` section of code. + void InitializeMethodsCode(ArtMethod* method, const void* entrypoint, PointerSize pointer_size) + REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Roles::uninterruptible_); + + // Reinitialize the entrypoint of the method. + EXPORT void ReinitializeMethodsCode(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_); // Update the code of a method respecting any installed stubs. @@ -601,6 +615,9 @@ class Instrumentation { REQUIRES_SHARED(Locks::mutator_lock_); private: + static bool CanUseAotCode(const void* quick_code); + static const void* GetOptimizedCodeFor(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_); + // Update the current instrumentation_level_. void UpdateInstrumentationLevel(InstrumentationLevel level); diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc index a8a03d4fdd..022532a54d 100644 --- a/runtime/jit/jit_code_cache.cc +++ b/runtime/jit/jit_code_cache.cc @@ -871,7 +871,7 @@ bool JitCodeCache::RemoveMethod(ArtMethod* method, bool release_memory) { return false; } - Runtime::Current()->GetInstrumentation()->InitializeMethodsCode(method, /*aot_code=*/ nullptr); + Runtime::Current()->GetInstrumentation()->ReinitializeMethodsCode(method); return true; } @@ -1779,7 +1779,7 @@ void JitCodeCache::InvalidateAllCompiledCode() { OatQuickMethodHeader::FromCodePointer(data.GetCode()); for (ArtMethod* method : data.GetMethods()) { if (method->GetEntryPointFromQuickCompiledCode() == method_header->GetEntryPoint()) { - instr->InitializeMethodsCode(method, /*aot_code=*/ nullptr); + instr->ReinitializeMethodsCode(method); } } } @@ -1789,7 +1789,7 @@ void JitCodeCache::InvalidateAllCompiledCode() { if (UNLIKELY(meth->IsObsolete())) { linker->SetEntryPointsForObsoleteMethod(meth); } else { - instr->InitializeMethodsCode(meth, /*aot_code=*/ nullptr); + instr->ReinitializeMethodsCode(meth); } } osr_code_map_.clear(); @@ -1803,7 +1803,7 @@ void JitCodeCache::InvalidateAllCompiledCode() { if (entry.method->IsPreCompiled()) { entry.method->ClearPreCompiled(); } - instr->InitializeMethodsCode(entry.method, /*aot_code=*/nullptr); + instr->ReinitializeMethodsCode(entry.method); } } @@ -1816,7 +1816,7 @@ void JitCodeCache::InvalidateCompiledCodeFor(ArtMethod* method, // the future. if (method_entrypoint == header->GetEntryPoint()) { // The entrypoint is the one to invalidate, so we just update it to the interpreter entry point. - Runtime::Current()->GetInstrumentation()->InitializeMethodsCode(method, /*aot_code=*/ nullptr); + Runtime::Current()->GetInstrumentation()->ReinitializeMethodsCode(method); } else { Thread* self = Thread::Current(); ScopedDebugDisallowReadBarriers sddrb(self); diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc index 09bbb2ab9e..365a63459d 100644 --- a/runtime/quick_exception_handler.cc +++ b/runtime/quick_exception_handler.cc @@ -745,8 +745,7 @@ void QuickExceptionHandler::DeoptimizeSingleFrame(DeoptimizationKind kind) { runtime->GetJit()->GetCodeCache()->InvalidateCompiledCodeFor( deopt_method, visitor.GetSingleFrameDeoptQuickMethodHeader()); } else { - runtime->GetInstrumentation()->InitializeMethodsCode( - deopt_method, /*aot_code=*/ nullptr); + runtime->GetInstrumentation()->ReinitializeMethodsCode(deopt_method); } // If the deoptimization is due to an inline cache, update it with the type diff --git a/runtime/runtime.cc b/runtime/runtime.cc index e2c30d619c..d4677d5b86 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -3213,21 +3213,21 @@ class DeoptimizeBootImageClassVisitor : public ClassVisitor { if (Runtime::Current()->GetHeap()->IsInBootImageOatFile(code) && (!m.IsNative() || deoptimize_native_methods) && !m.IsProxyMethod()) { - instrumentation_->InitializeMethodsCode(&m, /*aot_code=*/ nullptr); + instrumentation_->ReinitializeMethodsCode(&m); } if (Runtime::Current()->GetJit() != nullptr && Runtime::Current()->GetJit()->GetCodeCache()->IsInZygoteExecSpace(code) && (!m.IsNative() || deoptimize_native_methods)) { DCHECK(!m.IsProxyMethod()); - instrumentation_->InitializeMethodsCode(&m, /*aot_code=*/ nullptr); + instrumentation_->ReinitializeMethodsCode(&m); } if (m.IsPreCompiled()) { // Precompilation is incompatible with debuggable, so clear the flag // and update the entrypoint in case it has been compiled. m.ClearPreCompiled(); - instrumentation_->InitializeMethodsCode(&m, /*aot_code=*/ nullptr); + instrumentation_->ReinitializeMethodsCode(&m); } // Clear MemorySharedAccessFlags so the boot class methods can be JITed better. diff --git a/runtime/runtime_callbacks_test.cc b/runtime/runtime_callbacks_test.cc index 053d4eaaf5..f63b2f4096 100644 --- a/runtime/runtime_callbacks_test.cc +++ b/runtime/runtime_callbacks_test.cc @@ -80,7 +80,7 @@ class RuntimeCallbacksTest : public CommonRuntimeTest { PointerSize pointer_size = class_linker_->GetImagePointerSize(); for (auto& m : klass->GetMethods(pointer_size)) { if (!m.IsAbstract()) { - Runtime::Current()->GetInstrumentation()->InitializeMethodsCode(&m, /*aot_code=*/ nullptr); + Runtime::Current()->GetInstrumentation()->ReinitializeMethodsCode(&m); } } } diff --git a/test/common/runtime_state.cc b/test/common/runtime_state.cc index 6ff27f98f4..465e2f6850 100644 --- a/test/common/runtime_state.cc +++ b/test/common/runtime_state.cc @@ -457,7 +457,7 @@ extern "C" JNIEXPORT void JNICALL Java_Main_deoptimizeNativeMethod(JNIEnv* env, ScopedUtfChars chars(env, method_name); ArtMethod* method = GetMethod(soa, cls, chars); CHECK(method->IsNative()); - Runtime::Current()->GetInstrumentation()->InitializeMethodsCode(method, /*aot_code=*/ nullptr); + Runtime::Current()->GetInstrumentation()->ReinitializeMethodsCode(method); } extern "C" JNIEXPORT jboolean JNICALL Java_Main_isDebuggable(JNIEnv*, jclass) { |