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);
+    }
   }
 }