Adjust JitCodeCache::TransitionToDebuggable.
Only clear the precompiled flag if the method has it. Also added some
comments.
Bug: 144947842
Test: atest CtsJvmtiRunTest1982HostTestCases
Test: 689-zygote-jit-deopt
Change-Id: I8b2856823f359076c41240f463902eb57c1f7603
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index c43fe11..7ad4700 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -884,25 +884,38 @@
}
void JitCodeCache::TransitionToDebuggable() {
+ // We want to discard JIT compiled methods that are non-debuggable. These are:
+ // - Methods compiled by the zygote (where the compiled code is in the zygote exec
+ // space)
+ // - Methods that are precompiled in the method_code_map_.
+ //
+ // Also, we want to clear the precompiled flag to clear the effects of
+ // GetSavedEntryPointOfPreCompiledMethod.
{
MutexLock mu(Thread::Current(), *Locks::jit_lock_);
for (const auto& it : method_code_map_) {
ArtMethod* method = it.second;
- if (IsInZygoteExecSpace(method->GetEntryPointFromQuickCompiledCode())) {
+ if (IsInZygoteExecSpace(method->GetEntryPointFromQuickCompiledCode()) ||
+ method->IsPreCompiled()) {
method->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge());
}
- // We don't want any pre-compiled data being selected.
- method->ClearPreCompiled();
+ if (method->IsPreCompiled()) {
+ method->ClearPreCompiled();
+ }
}
+ // Not strictly necessary, but this map is useless now.
+ saved_compiled_methods_map_.clear();
}
for (const auto& entry : zygote_map_) {
ArtMethod* method = entry.method;
- if (ContainsPc(method->GetEntryPointFromQuickCompiledCode())) {
- DCHECK(IsInZygoteExecSpace(method->GetEntryPointFromQuickCompiledCode()));
- DCHECK(method->IsPreCompiled());
+ if (IsInZygoteExecSpace(method->GetEntryPointFromQuickCompiledCode())) {
method->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge());
}
- method->ClearPreCompiled();
+ // We check if it's precompiled instead of DCHECKing it to support
+ // TransitionToDebuggable being called multiple times.
+ if (method->IsPreCompiled()) {
+ method->ClearPreCompiled();
+ }
}
}