Clear inline caches if a ProfilingInfo gets revived.

This avoids stalled class references.

Bug: 27398183
Bug: 23128949
Bug: 26846185
Change-Id: I9539215241708e26fef887e02201ce1feabc2d1a
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index e8a7189..e041a42 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -705,9 +705,17 @@
     auto profiling_kept_end = std::remove_if(profiling_infos_.begin(), profiling_infos_.end(),
       [this] (ProfilingInfo* info) NO_THREAD_SAFETY_ANALYSIS {
         const void* ptr = info->GetMethod()->GetEntryPointFromQuickCompiledCode();
+        // We have previously cleared the ProfilingInfo pointer in the ArtMethod in the hope
+        // that the compiled code would not get revived. As mutator threads run concurrently,
+        // they may have revived the compiled code, and now we are in the situation where
+        // a method has compiled code but no ProfilingInfo.
+        // We make sure compiled methods have a ProfilingInfo object. It is needed for
+        // code cache collection.
         if (ContainsPc(ptr) && info->GetMethod()->GetProfilingInfo(sizeof(void*)) == nullptr) {
-          // Make sure compiled methods have a ProfilingInfo object. It is needed for
-          // code cache collection.
+          // We clear the inline caches as classes in it might be stalled.
+          info->ClearInlineCaches();
+          // Do a fence to make sure the clearing is seen before attaching to the method.
+          QuasiAtomic::ThreadFenceRelease();
           info->GetMethod()->SetProfilingInfo(info);
         } else if (info->GetMethod()->GetProfilingInfo(sizeof(void*)) != info) {
           // No need for this ProfilingInfo object anymore.