Clear PreCompiled when we transition to debuggable after zygote fork

We were leaving the PreCompiled bits set on method objects. This meant
that in some circumstances non-debuggable compiled code could be
reattached to methods after the switch to debuggable with the zygote
fork.

Bug: 144947842
Test: atest CtsJvmtiRunTest1982HostTestCases
Change-Id: I1f642f6da441c4f023ec1cbd873c05914c73dd7e
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index fb11a05..2415a9f 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -879,13 +879,26 @@
   }
 }
 
-void JitCodeCache::ClearEntryPointsInZygoteExecSpace() {
-  MutexLock mu(Thread::Current(), *Locks::jit_lock_);
-  for (const auto& it : method_code_map_) {
-    ArtMethod* method = it.second;
-    if (IsInZygoteExecSpace(method->GetEntryPointFromQuickCompiledCode())) {
+void JitCodeCache::TransitionToDebuggable() {
+  {
+    MutexLock mu(Thread::Current(), *Locks::jit_lock_);
+    for (const auto& it : method_code_map_) {
+      ArtMethod* method = it.second;
+      if (IsInZygoteExecSpace(method->GetEntryPointFromQuickCompiledCode())) {
+        method->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge());
+      }
+      // We don't want any pre-compiled data being selected.
+      method->ClearPreCompiled();
+    }
+  }
+  for (const auto& entry : zygote_map_) {
+    ArtMethod* method = entry.method;
+    if (ContainsPc(method->GetEntryPointFromQuickCompiledCode())) {
+      DCHECK(IsInZygoteExecSpace(method->GetEntryPointFromQuickCompiledCode()));
+      DCHECK(method->IsPreCompiled());
       method->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge());
     }
+    method->ClearPreCompiled();
   }
 }
 
diff --git a/runtime/jit/jit_code_cache.h b/runtime/jit/jit_code_cache.h
index 61fee34..22b43cc 100644
--- a/runtime/jit/jit_code_cache.h
+++ b/runtime/jit/jit_code_cache.h
@@ -104,6 +104,14 @@
 // This map is writable only by the zygote, and readable by all children.
 class ZygoteMap {
  public:
+  struct Entry {
+    ArtMethod* method;
+    // Note we currently only allocate code in the low 4g, so we could just reserve 4 bytes
+    // for the code pointer. For simplicity and in the case we move to 64bit
+    // addresses for code, just keep it void* for now.
+    const void* code_ptr;
+  };
+
   explicit ZygoteMap(JitMemoryRegion* region)
       : map_(), region_(region), compilation_state_(nullptr) {}
 
@@ -140,15 +148,20 @@
            *compilation_state_ == ZygoteCompilationState::kNotifiedOk;
   }
 
- private:
-  struct Entry {
-    ArtMethod* method;
-    // Note we currently only allocate code in the low 4g, so we could just reserve 4 bytes
-    // for the code pointer. For simplicity and in the case we move to 64bit
-    // addresses for code, just keep it void* for now.
-    const void* code_ptr;
-  };
+  ArrayRef<const Entry>::const_iterator cbegin() const {
+    return map_.cbegin();
+  }
+  ArrayRef<const Entry>::iterator begin() {
+    return map_.begin();
+  }
+  ArrayRef<const Entry>::const_iterator cend() const {
+    return map_.cend();
+  }
+  ArrayRef<const Entry>::iterator end() {
+    return map_.end();
+  }
 
+ private:
   // The map allocated with `region_`.
   ArrayRef<const Entry> map_;
 
@@ -370,8 +383,9 @@
 
   // Clear the entrypoints of JIT compiled methods that belong in the zygote space.
   // This is used for removing non-debuggable JIT code at the point we realize the runtime
-  // is debuggable.
-  void ClearEntryPointsInZygoteExecSpace() REQUIRES(!Locks::jit_lock_) REQUIRES(Locks::mutator_lock_);
+  // is debuggable. Also clear the Precompiled flag from all methods so the non-debuggable code
+  // doesn't come back.
+  void TransitionToDebuggable() REQUIRES(!Locks::jit_lock_) REQUIRES(Locks::mutator_lock_);
 
   JitMemoryRegion* GetCurrentRegion();
   bool IsSharedRegion(const JitMemoryRegion& region) const { return &region == &shared_region_; }
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index df9245e..8607991 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -2851,8 +2851,8 @@
     GetClassLinker()->VisitClasses(&visitor);
     jit::Jit* jit = GetJit();
     if (jit != nullptr) {
-      // Code JITted by the zygote is not compiled debuggable.
-      jit->GetCodeCache()->ClearEntryPointsInZygoteExecSpace();
+      // Code previously compiled may not be compiled debuggable.
+      jit->GetCodeCache()->TransitionToDebuggable();
     }
   }
   // Also de-quicken all -quick opcodes. We do this for both BCP and non-bcp so if we are swapping