Remove requirement of a ProfilingInfo for jitted code.
When pre-jitting (zygote or system server in jit zygote mode),
the profiling info is just memory overhead. Remove the need to have
one.
Bug: 119800099
Test: boot, testrunner.py --jit
Change-Id: Ie74d870eebef72c903225542e9b41dfe98132419
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index 65e6d9d..2505111 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -1127,12 +1127,15 @@
// This situation currently only occurs in the jit-zygote mode.
DCHECK(Runtime::Current()->IsZygote());
DCHECK(Runtime::Current()->IsUsingApexBootImageLocation());
- DCHECK(method->GetProfilingInfo(kRuntimePointerSize) != nullptr);
DCHECK(method->GetDeclaringClass()->GetClassLoader() == nullptr);
- // Save the entrypoint, so it can be fethed later once the class is
- // initialized.
- method->GetProfilingInfo(kRuntimePointerSize)->SetSavedEntryPoint(
- method_header->GetEntryPoint());
+ // TODO(ngeoffray): In most cases, the zygote will not have a profiling
+ // info for a compiled method. Use a map instead.
+ if (method->GetProfilingInfo(kRuntimePointerSize) != nullptr) {
+ // Save the entrypoint, so it can be fetched later once the class is
+ // initialized.
+ method->GetProfilingInfo(kRuntimePointerSize)->SetSavedEntryPoint(
+ method_header->GetEntryPoint());
+ }
} else {
Runtime::Current()->GetInstrumentation()->UpdateMethodsCode(
method, method_header->GetEntryPoint());
@@ -1564,8 +1567,6 @@
}
}
- DCHECK(CheckLiveCompiledCodeHasProfilingInfo());
-
// Change entry points of native methods back to the GenericJNI entrypoint.
for (const auto& entry : jni_stubs_map_) {
const JniStubData& data = entry.second;
@@ -1743,30 +1744,9 @@
return false;
});
profiling_infos_.erase(profiling_kept_end, profiling_infos_.end());
- DCHECK(CheckLiveCompiledCodeHasProfilingInfo());
}
}
-bool JitCodeCache::CheckLiveCompiledCodeHasProfilingInfo() {
- ScopedTrace trace(__FUNCTION__);
- // Check that methods we have compiled do have a ProfilingInfo object. We would
- // have memory leaks of compiled code otherwise.
- for (const auto& it : method_code_map_) {
- ArtMethod* method = it.second;
- if (method->GetProfilingInfo(kRuntimePointerSize) == nullptr) {
- const void* code_ptr = it.first;
- const OatQuickMethodHeader* method_header = OatQuickMethodHeader::FromCodePointer(code_ptr);
- if (method_header->GetEntryPoint() == method->GetEntryPointFromQuickCompiledCode()) {
- // If the code is not dead, then we have a problem. Note that this can even
- // happen just after a collection, as mutator threads are running in parallel
- // and could deoptimize an existing compiled code.
- return false;
- }
- }
- }
- return true;
-}
-
OatQuickMethodHeader* JitCodeCache::LookupMethodHeader(uintptr_t pc, ArtMethod* method) {
static_assert(kRuntimeISA != InstructionSet::kThumb2, "kThumb2 cannot be a runtime ISA");
if (kRuntimeISA == InstructionSet::kArm) {
@@ -2003,16 +1983,16 @@
return osr_code_map_.find(method) != osr_code_map_.end();
}
-bool JitCodeCache::NotifyCompilationOf(ArtMethod* method, Thread* self, bool osr) {
+bool JitCodeCache::NotifyCompilationOf(ArtMethod* method, Thread* self, bool osr, bool prejit) {
if (!osr && ContainsPc(method->GetEntryPointFromQuickCompiledCode())) {
return false;
}
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
if (class_linker->IsQuickResolutionStub(method->GetEntryPointFromQuickCompiledCode())) {
- if (!Runtime::Current()->IsUsingApexBootImageLocation() || !Runtime::Current()->IsZygote()) {
- // Unless we're running as zygote in the jitzygote experiment, we currently don't save
- // the JIT compiled code if we cannot update the entrypoint due to having the resolution stub.
+ if (!prejit) {
+ // Unless we're pre-jitting, we currently don't save the JIT compiled code if we cannot
+ // update the entrypoint due to having the resolution stub.
VLOG(jit) << "Not compiling "
<< method->PrettyMethod()
<< " because it has the resolution stub";
@@ -2064,18 +2044,20 @@
} else {
ProfilingInfo* info = method->GetProfilingInfo(kRuntimePointerSize);
if (info == nullptr) {
- VLOG(jit) << method->PrettyMethod() << " needs a ProfilingInfo to be compiled";
- // Because the counter is not atomic, there are some rare cases where we may not hit the
- // threshold for creating the ProfilingInfo. Reset the counter now to "correct" this.
- ClearMethodCounter(method, /*was_warm=*/ false);
- return false;
+ // When prejitting, we don't allocate a profiling info.
+ if (!prejit) {
+ VLOG(jit) << method->PrettyMethod() << " needs a ProfilingInfo to be compiled";
+ // Because the counter is not atomic, there are some rare cases where we may not hit the
+ // threshold for creating the ProfilingInfo. Reset the counter now to "correct" this.
+ ClearMethodCounter(method, /*was_warm=*/ false);
+ return false;
+ }
+ } else {
+ if (info->IsMethodBeingCompiled(osr)) {
+ return false;
+ }
+ info->SetIsMethodBeingCompiled(true, osr);
}
-
- if (info->IsMethodBeingCompiled(osr)) {
- return false;
- }
-
- info->SetIsMethodBeingCompiled(true, osr);
return true;
}
}
@@ -2113,8 +2095,10 @@
} // else CommitCodeInternal() updated entrypoints of all methods in the JniStubData.
} else {
ProfilingInfo* info = method->GetProfilingInfo(kRuntimePointerSize);
- DCHECK(info->IsMethodBeingCompiled(osr));
- info->SetIsMethodBeingCompiled(false, osr);
+ if (info != nullptr) {
+ DCHECK(info->IsMethodBeingCompiled(osr));
+ info->SetIsMethodBeingCompiled(false, osr);
+ }
}
}