Put the deletion of profiling info under a GC critical section.

Otherwise the GC could see dangling pointers.

bug:30033802

(cherry picked from commit cf48fa030780c3185f225d558b704c396f7713cc)

Change-Id: I2c43e973878f50dc147aa0af81551ecc942a790d
diff --git a/runtime/gc/collector_type.h b/runtime/gc/collector_type.h
index a06ccbe..f14d086 100644
--- a/runtime/gc/collector_type.h
+++ b/runtime/gc/collector_type.h
@@ -49,6 +49,8 @@
   kCollectorTypeHomogeneousSpaceCompact,
   // Class linker fake collector.
   kCollectorTypeClassLinker,
+  // JIT Code cache fake collector.
+  kCollectorTypeJitCodeCache,
 };
 std::ostream& operator<<(std::ostream& os, const CollectorType& collector_type);
 
diff --git a/runtime/gc/gc_cause.cc b/runtime/gc/gc_cause.cc
index 1b03460..cf765f5 100644
--- a/runtime/gc/gc_cause.cc
+++ b/runtime/gc/gc_cause.cc
@@ -36,6 +36,7 @@
     case kGcCauseInstrumentation: return "Instrumentation";
     case kGcCauseAddRemoveAppImageSpace: return "AddRemoveAppImageSpace";
     case kGcCauseClassLinker: return "ClassLinker";
+    case kGcCauseJitCodeCache: return "JitCodeCache";
     default:
       LOG(FATAL) << "Unreachable";
       UNREACHABLE();
diff --git a/runtime/gc/gc_cause.h b/runtime/gc/gc_cause.h
index df3aba9..7d2cc4f 100644
--- a/runtime/gc/gc_cause.h
+++ b/runtime/gc/gc_cause.h
@@ -47,6 +47,8 @@
   kGcCauseHomogeneousSpaceCompact,
   // Class linker cause, used to guard filling art methods with special values.
   kGcCauseClassLinker,
+  // Not a real GC cause, used to implement exclusion between code cache metadata and GC.
+  kGcCauseJitCodeCache,
 };
 
 const char* PrettyCause(GcCause cause);
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index cdd5f2e..03b7713 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -2709,7 +2709,8 @@
   }
 
   // It's time to clear all inline caches, in case some classes can be unloaded.
-  if ((gc_type == collector::kGcTypeFull) && (runtime->GetJit() != nullptr)) {
+  if (((gc_type == collector::kGcTypeFull) || (gc_type == collector::kGcTypePartial)) &&
+      (runtime->GetJit() != nullptr)) {
     runtime->GetJit()->GetCodeCache()->ClearGcRootsInInlineCaches(self);
   }
 
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index 6b6f5a5..8c1d776 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -25,6 +25,7 @@
 #include "debugger_interface.h"
 #include "entrypoints/runtime_asm_entrypoints.h"
 #include "gc/accounting/bitmap-inl.h"
+#include "gc/scoped_gc_critical_section.h"
 #include "jit/jit.h"
 #include "jit/profiling_info.h"
 #include "linear_alloc.h"
@@ -727,6 +728,9 @@
   RemoveUnmarkedCode(self);
 
   if (collect_profiling_info) {
+    ScopedThreadSuspension sts(self, kSuspended);
+    gc::ScopedGCCriticalSection gcs(
+        self, gc::kGcCauseJitCodeCache, gc::kCollectorTypeJitCodeCache);
     MutexLock mu(self, lock_);
     // Free all profiling infos of methods not compiled nor being compiled.
     auto profiling_kept_end = std::remove_if(profiling_infos_.begin(), profiling_infos_.end(),
diff --git a/runtime/jit/jit_code_cache.h b/runtime/jit/jit_code_cache.h
index 4df6762..6dc1578 100644
--- a/runtime/jit/jit_code_cache.h
+++ b/runtime/jit/jit_code_cache.h
@@ -255,8 +255,7 @@
       SHARED_REQUIRES(Locks::mutator_lock_);
 
   bool CheckLiveCompiledCodeHasProfilingInfo()
-      REQUIRES(lock_)
-      SHARED_REQUIRES(Locks::mutator_lock_);
+      REQUIRES(lock_);
 
   void FreeCode(uint8_t* code) REQUIRES(lock_);
   uint8_t* AllocateCode(size_t code_size) REQUIRES(lock_);