Fix go/lem breakages on baseline configs

- Don't collect profiling info for now, as compiled code reference
  them directly.
- Only compile optimized after reaching baseline hotness threshold if
  tiered JIT is enabled.

Test: test.py, go/lem benchmarks.
Change-Id: I0d21d5f77825a710588ef5a7c11288a5b9757907
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index 04e8d39..945600a 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -1119,18 +1119,24 @@
 
       // Start polling the liveness of compiled code to prepare for the next full collection.
       if (next_collection_will_be_full) {
-        // Save the entry point of methods we have compiled, and update the entry
-        // point of those methods to the interpreter. If the method is invoked, the
-        // interpreter will update its entry point to the compiled code and call it.
-        for (ProfilingInfo* info : profiling_infos_) {
-          const void* entry_point = info->GetMethod()->GetEntryPointFromQuickCompiledCode();
-          if (!IsInZygoteDataSpace(info) && ContainsPc(entry_point)) {
-            info->SetSavedEntryPoint(entry_point);
-            // Don't call Instrumentation::UpdateMethodsCode(), as it can check the declaring
-            // class of the method. We may be concurrently running a GC which makes accessing
-            // the class unsafe. We know it is OK to bypass the instrumentation as we've just
-            // checked that the current entry point is JIT compiled code.
-            info->GetMethod()->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge());
+        if (Runtime::Current()->GetJITOptions()->CanCompileBaseline()) {
+          for (ProfilingInfo* info : profiling_infos_) {
+            info->SetBaselineHotnessCount(0);
+          }
+        } else {
+          // Save the entry point of methods we have compiled, and update the entry
+          // point of those methods to the interpreter. If the method is invoked, the
+          // interpreter will update its entry point to the compiled code and call it.
+          for (ProfilingInfo* info : profiling_infos_) {
+            const void* entry_point = info->GetMethod()->GetEntryPointFromQuickCompiledCode();
+            if (!IsInZygoteDataSpace(info) && ContainsPc(entry_point)) {
+              info->SetSavedEntryPoint(entry_point);
+              // Don't call Instrumentation::UpdateMethodsCode(), as it can check the declaring
+              // class of the method. We may be concurrently running a GC which makes accessing
+              // the class unsafe. We know it is OK to bypass the instrumentation as we've just
+              // checked that the current entry point is JIT compiled code.
+              info->GetMethod()->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge());
+            }
           }
         }
 
@@ -1219,28 +1225,50 @@
   ScopedTrace trace(__FUNCTION__);
   {
     MutexLock mu(self, *Locks::jit_lock_);
-    if (collect_profiling_info) {
-      // Clear the profiling info of methods that do not have compiled code as entrypoint.
-      // Also remove the saved entry point from the ProfilingInfo objects.
-      for (ProfilingInfo* info : profiling_infos_) {
-        const void* ptr = info->GetMethod()->GetEntryPointFromQuickCompiledCode();
-        if (!ContainsPc(ptr) && !info->IsInUseByCompiler() && !IsInZygoteDataSpace(info)) {
-          info->GetMethod()->SetProfilingInfo(nullptr);
-        }
 
-        if (info->GetSavedEntryPoint() != nullptr) {
-          info->SetSavedEntryPoint(nullptr);
-          // We are going to move this method back to interpreter. Clear the counter now to
-          // give it a chance to be hot again.
-          ClearMethodCounter(info->GetMethod(), /*was_warm=*/ true);
+    if (Runtime::Current()->GetJITOptions()->CanCompileBaseline()) {
+      // Update to interpreter the methods that have baseline entrypoints and whose baseline
+      // hotness count is zero.
+      // Note that these methods may be in thread stack or concurrently revived
+      // between. That's OK, as the thread executing it will mark it.
+      for (ProfilingInfo* info : profiling_infos_) {
+        if (info->GetBaselineHotnessCount() == 0) {
+          const void* entry_point = info->GetMethod()->GetEntryPointFromQuickCompiledCode();
+          if (ContainsPc(entry_point)) {
+            OatQuickMethodHeader* method_header =
+                OatQuickMethodHeader::FromEntryPoint(entry_point);
+            if (CodeInfo::IsBaseline(method_header->GetOptimizedCodeInfoPtr())) {
+              info->GetMethod()->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge());
+            }
+          }
         }
       }
-    } else if (kIsDebugBuild) {
-      // Sanity check that the profiling infos do not have a dangling entry point.
-      for (ProfilingInfo* info : profiling_infos_) {
-        DCHECK(!Runtime::Current()->IsZygote());
-        const void* entry_point = info->GetSavedEntryPoint();
-        DCHECK(entry_point == nullptr || IsInZygoteExecSpace(entry_point));
+      // TODO: collect profiling info
+      // TODO: collect optimized code?
+    } else {
+      if (collect_profiling_info) {
+        // Clear the profiling info of methods that do not have compiled code as entrypoint.
+        // Also remove the saved entry point from the ProfilingInfo objects.
+        for (ProfilingInfo* info : profiling_infos_) {
+          const void* ptr = info->GetMethod()->GetEntryPointFromQuickCompiledCode();
+          if (!ContainsPc(ptr) && !info->IsInUseByCompiler() && !IsInZygoteDataSpace(info)) {
+            info->GetMethod()->SetProfilingInfo(nullptr);
+          }
+
+          if (info->GetSavedEntryPoint() != nullptr) {
+            info->SetSavedEntryPoint(nullptr);
+            // We are going to move this method back to interpreter. Clear the counter now to
+            // give it a chance to be hot again.
+            ClearMethodCounter(info->GetMethod(), /*was_warm=*/ true);
+          }
+        }
+      } else if (kIsDebugBuild) {
+        // Sanity check that the profiling infos do not have a dangling entry point.
+        for (ProfilingInfo* info : profiling_infos_) {
+          DCHECK(!Runtime::Current()->IsZygote());
+          const void* entry_point = info->GetSavedEntryPoint();
+          DCHECK(entry_point == nullptr || IsInZygoteExecSpace(entry_point));
+        }
       }
     }
 
@@ -1622,6 +1650,12 @@
     return new_compilation;
   } else {
     ProfilingInfo* info = method->GetProfilingInfo(kRuntimePointerSize);
+    if (CanAllocateProfilingInfo() && baseline && info == nullptr) {
+      // We can retry allocation here as we're the JIT thread.
+      if (ProfilingInfo::Create(self, method, /* retry_allocation= */ true)) {
+        info = method->GetProfilingInfo(kRuntimePointerSize);
+      }
+    }
     if (info == nullptr) {
       // When prejitting, we don't allocate a profiling info.
       if (!prejit && !IsSharedRegion(*region)) {