src/hotspot/share/code/codeCache.cpp
changeset 50416 ef980b9ac191
parent 50113 caf115bb98ad
child 50515 1ce463f497ad
--- a/src/hotspot/share/code/codeCache.cpp	Tue Jun 05 23:10:54 2018 +0530
+++ b/src/hotspot/share/code/codeCache.cpp	Wed May 02 11:28:49 2018 -0400
@@ -685,8 +685,15 @@
   assert_locked_or_safepoint(CodeCache_lock);
   CompiledMethodIterator iter;
   while(iter.next_alive()) {
-    iter.method()->do_unloading(is_alive, unloading_occurred);
+    iter.method()->do_unloading(is_alive);
   }
+
+  // Now that all the unloaded nmethods are known, cleanup caches
+  // before CLDG is purged.
+  // This is another code cache walk but it is moved from gc_epilogue.
+  // G1 does a parallel walk of the nmethods so cleans them up
+  // as it goes and doesn't call this.
+  do_unloading_nmethod_caches(unloading_occurred);
 }
 
 void CodeCache::blobs_do(CodeBlobClosure* f) {
@@ -720,8 +727,11 @@
     assert(cur->on_scavenge_root_list(), "else shouldn't be on this list");
 
     bool is_live = (!cur->is_zombie() && !cur->is_unloaded());
-    if (TraceScavenge) {
-      cur->print_on(tty, is_live ? "scavenge root" : "dead scavenge root"); tty->cr();
+    LogTarget(Trace, gc, nmethod) lt;
+    if (lt.is_enabled()) {
+      LogStream ls(lt);
+      CompileTask::print(&ls, cur,
+        is_live ? "scavenge root " : "dead scavenge root", /*short_form:*/ true);
     }
     if (is_live) {
       // Perform cur->oops_do(f), maybe just once per nmethod.
@@ -892,18 +902,26 @@
 #endif
 }
 
-void CodeCache::gc_prologue() {
+void CodeCache::gc_prologue() { }
+
+void CodeCache::gc_epilogue() {
+  prune_scavenge_root_nmethods();
 }
 
-void CodeCache::gc_epilogue() {
+
+void CodeCache::do_unloading_nmethod_caches(bool class_unloading_occurred) {
   assert_locked_or_safepoint(CodeCache_lock);
-  NOT_DEBUG(if (needs_cache_clean())) {
+  // Even if classes are not unloaded, there may have been some nmethods that are
+  // unloaded because oops in them are no longer reachable.
+  NOT_DEBUG(if (needs_cache_clean() || class_unloading_occurred)) {
     CompiledMethodIterator iter;
     while(iter.next_alive()) {
       CompiledMethod* cm = iter.method();
       assert(!cm->is_unloaded(), "Tautology");
-      DEBUG_ONLY(if (needs_cache_clean())) {
-        cm->cleanup_inline_caches();
+      DEBUG_ONLY(if (needs_cache_clean() || class_unloading_occurred)) {
+        // Clean up both unloaded klasses from nmethods and unloaded nmethods
+        // from inline caches.
+        cm->unload_nmethod_caches(/*parallel*/false, class_unloading_occurred);
       }
       DEBUG_ONLY(cm->verify());
       DEBUG_ONLY(cm->verify_oop_relocations());
@@ -911,8 +929,6 @@
   }
 
   set_needs_cache_clean(false);
-  prune_scavenge_root_nmethods();
-
   verify_icholder_relocations();
 }