8201537: Remove is_alive closure from Klass::is_loader_alive()
authorcoleenp
Wed, 18 Apr 2018 13:37:39 -0400
changeset 49821 02c08e20d66c
parent 49820 663f5d90f0e8
child 49822 53aae0c219e6
8201537: Remove is_alive closure from Klass::is_loader_alive() Summary: remove is_alive closure from callers of Klass::is_loader_alive so that cleaning metadata doesn't require GC closure. Reviewed-by: adinn, stefank
src/hotspot/share/classfile/loaderConstraints.cpp
src/hotspot/share/classfile/resolutionErrors.cpp
src/hotspot/share/code/compiledMethod.cpp
src/hotspot/share/code/compiledMethod.hpp
src/hotspot/share/code/nmethod.cpp
src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp
src/hotspot/share/gc/g1/g1CollectedHeap.cpp
src/hotspot/share/gc/parallel/psMarkSweep.cpp
src/hotspot/share/gc/parallel/psParallelCompact.cpp
src/hotspot/share/gc/serial/genMarkSweep.cpp
src/hotspot/share/oops/compiledICHolder.hpp
src/hotspot/share/oops/instanceKlass.cpp
src/hotspot/share/oops/instanceKlass.hpp
src/hotspot/share/oops/klass.cpp
src/hotspot/share/oops/klass.hpp
src/hotspot/share/oops/methodData.cpp
src/hotspot/share/oops/methodData.hpp
src/hotspot/share/prims/whitebox.cpp
--- a/src/hotspot/share/classfile/loaderConstraints.cpp	Wed Apr 18 10:03:49 2018 -0700
+++ b/src/hotspot/share/classfile/loaderConstraints.cpp	Wed Apr 18 13:37:39 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -99,7 +99,7 @@
       InstanceKlass* klass = probe->klass();
       // Remove klass that is no longer alive
       if (klass != NULL &&
-          klass->class_loader_data()->is_unloading()) {
+          !klass->is_loader_alive()) {
         probe->set_klass(NULL);
         if (lt.is_enabled()) {
           ResourceMark rm;
@@ -116,31 +116,31 @@
       int n = 0;
       while (n < probe->num_loaders()) {
         if (probe->loader_data(n)->is_unloading()) {
-            if (lt.is_enabled()) {
-              ResourceMark rm;
-              lt.print("purging loader %s from constraint for name %s",
-                            probe->loader_data(n)->loader_name(),
-                            probe->name()->as_C_string()
-                            );
-            }
+          if (lt.is_enabled()) {
+            ResourceMark rm;
+            lt.print("purging loader %s from constraint for name %s",
+                     probe->loader_data(n)->loader_name(),
+                     probe->name()->as_C_string()
+                     );
+          }
 
-            // Compact array
-            int num = probe->num_loaders() - 1;
-            probe->set_num_loaders(num);
+          // Compact array
+          int num = probe->num_loaders() - 1;
+          probe->set_num_loaders(num);
           probe->set_loader_data(n, probe->loader_data(num));
           probe->set_loader_data(num, NULL);
 
-            if (lt.is_enabled()) {
-              ResourceMark rm;
-              lt.print("new loader list:");
-              for (int i = 0; i < probe->num_loaders(); i++) {
-                lt.print("    [%d]: %s", i,
-                              probe->loader_data(i)->loader_name());
-              }
+          if (lt.is_enabled()) {
+            ResourceMark rm;
+            lt.print("new loader list:");
+            for (int i = 0; i < probe->num_loaders(); i++) {
+              lt.print("    [%d]: %s", i,
+                            probe->loader_data(i)->loader_name());
             }
+          }
 
-            continue;  // current element replaced, so restart without
-                       // incrementing n
+          continue;  // current element replaced, so restart without
+                     // incrementing n
           }
         n++;
       }
@@ -159,9 +159,7 @@
       } else {
 #ifdef ASSERT
         if (probe->klass() != NULL) {
-          ClassLoaderData* loader_data =
-            probe->klass()->class_loader_data();
-          assert(!loader_data->is_unloading(), "klass should be live");
+          assert(probe->klass()->is_loader_alive(), "klass should be live");
         }
 #endif
         // Go to next entry
--- a/src/hotspot/share/classfile/resolutionErrors.cpp	Wed Apr 18 10:03:49 2018 -0700
+++ b/src/hotspot/share/classfile/resolutionErrors.cpp	Wed Apr 18 13:37:39 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -125,9 +125,8 @@
       assert(entry->pool() != (ConstantPool*)NULL, "resolution error table is corrupt");
       ConstantPool* pool = entry->pool();
       assert(pool->pool_holder() != NULL, "Constant pool without a class?");
-      ClassLoaderData* loader_data =
-              pool->pool_holder()->class_loader_data();
-      if (!loader_data->is_unloading()) {
+
+      if (pool->pool_holder()->is_loader_alive()) {
         p = entry->next_addr();
       } else {
         *p = entry->next();
--- a/src/hotspot/share/code/compiledMethod.cpp	Wed Apr 18 10:03:49 2018 -0700
+++ b/src/hotspot/share/code/compiledMethod.cpp	Wed Apr 18 13:37:39 2018 -0400
@@ -99,7 +99,7 @@
   release_set_exception_cache(new_entry);
 }
 
-void CompiledMethod::clean_exception_cache(BoolObjectClosure* is_alive) {
+void CompiledMethod::clean_exception_cache() {
   ExceptionCache* prev = NULL;
   ExceptionCache* curr = exception_cache();
 
@@ -107,7 +107,7 @@
     ExceptionCache* next = curr->next();
 
     Klass* ex_klass = curr->exception_type();
-    if (ex_klass != NULL && !ex_klass->is_loader_alive(is_alive)) {
+    if (ex_klass != NULL && !ex_klass->is_loader_alive()) {
       if (prev == NULL) {
         set_exception_cache(next);
       } else {
@@ -369,56 +369,42 @@
 }
 
 #ifdef ASSERT
-
-class CheckClass : AllStatic {
-  static BoolObjectClosure* _is_alive;
-
-  // Check class_loader is alive for this bit of metadata.
-  static void check_class(Metadata* md) {
-    Klass* klass = NULL;
-    if (md->is_klass()) {
-      klass = ((Klass*)md);
-    } else if (md->is_method()) {
-      klass = ((Method*)md)->method_holder();
-    } else if (md->is_methodData()) {
-      klass = ((MethodData*)md)->method()->method_holder();
-    } else {
-      md->print();
-      ShouldNotReachHere();
-    }
-    assert(klass->is_loader_alive(_is_alive), "must be alive");
-  }
- public:
-  static void do_check_class(BoolObjectClosure* is_alive, CompiledMethod* nm) {
-    assert(SafepointSynchronize::is_at_safepoint(), "this is only ok at safepoint");
-    _is_alive = is_alive;
-    nm->metadata_do(check_class);
-  }
-};
-
-// This is called during a safepoint so can use static data
-BoolObjectClosure* CheckClass::_is_alive = NULL;
+// Check class_loader is alive for this bit of metadata.
+static void check_class(Metadata* md) {
+   Klass* klass = NULL;
+   if (md->is_klass()) {
+     klass = ((Klass*)md);
+   } else if (md->is_method()) {
+     klass = ((Method*)md)->method_holder();
+   } else if (md->is_methodData()) {
+     klass = ((MethodData*)md)->method()->method_holder();
+   } else {
+     md->print();
+     ShouldNotReachHere();
+   }
+   assert(klass->is_loader_alive(), "must be alive");
+}
 #endif // ASSERT
 
 
-void CompiledMethod::clean_ic_if_metadata_is_dead(CompiledIC *ic, BoolObjectClosure *is_alive) {
+void CompiledMethod::clean_ic_if_metadata_is_dead(CompiledIC *ic) {
   if (ic->is_icholder_call()) {
     // The only exception is compiledICHolder oops which may
     // yet be marked below. (We check this further below).
     CompiledICHolder* cichk_oop = ic->cached_icholder();
 
-    if (cichk_oop->is_loader_alive(is_alive)) {
+    if (cichk_oop->is_loader_alive()) {
       return;
     }
   } else {
     Metadata* ic_oop = ic->cached_metadata();
     if (ic_oop != NULL) {
       if (ic_oop->is_klass()) {
-        if (((Klass*)ic_oop)->is_loader_alive(is_alive)) {
+        if (((Klass*)ic_oop)->is_loader_alive()) {
           return;
         }
       } else if (ic_oop->is_method()) {
-        if (((Method*)ic_oop)->method_holder()->is_loader_alive(is_alive)) {
+        if (((Method*)ic_oop)->method_holder()->is_loader_alive()) {
           return;
         }
       } else {
@@ -453,7 +439,7 @@
 // all strong references alive.  Any weak references should have been
 // cleared as well.  Visit all the metadata and ensure that it's
 // really alive.
-void CompiledMethod::verify_metadata_loaders(address low_boundary, BoolObjectClosure* is_alive) {
+void CompiledMethod::verify_metadata_loaders(address low_boundary) {
 #ifdef ASSERT
     RelocIterator iter(this, low_boundary);
     while (iter.next()) {
@@ -483,7 +469,7 @@
     }
   }
   // Check that the metadata embedded in the nmethod is alive
-  CheckClass::do_check_class(is_alive, this);
+  metadata_do(check_class);
 #endif
 }
 
@@ -518,7 +504,7 @@
   }
 
   // Exception cache
-  clean_exception_cache(is_alive);
+  clean_exception_cache();
 
   // If class unloading occurred we first iterate over all inline caches and
   // clear ICs where the cached oop is referring to an unloaded klass or method.
@@ -529,7 +515,7 @@
     while(iter.next()) {
       if (iter.type() == relocInfo::virtual_call_type) {
         CompiledIC *ic = CompiledIC_at(&iter);
-        clean_ic_if_metadata_is_dead(ic, is_alive);
+        clean_ic_if_metadata_is_dead(ic);
       }
     }
   }
@@ -545,7 +531,7 @@
 #endif
 
   // Ensure that all metadata is still alive
-  verify_metadata_loaders(low_boundary, is_alive);
+  verify_metadata_loaders(low_boundary);
 }
 
 template <class CompiledICorStaticCall>
@@ -606,7 +592,7 @@
   }
 
   // Exception cache
-  clean_exception_cache(is_alive);
+  clean_exception_cache();
 
   bool postponed = false;
 
@@ -619,7 +605,7 @@
       if (unloading_occurred) {
         // If class unloading occurred we first iterate over all inline caches and
         // clear ICs where the cached oop is referring to an unloaded klass or method.
-        clean_ic_if_metadata_is_dead(CompiledIC_at(&iter), is_alive);
+        clean_ic_if_metadata_is_dead(CompiledIC_at(&iter));
       }
 
       postponed |= clean_if_nmethod_is_unloaded(CompiledIC_at(&iter), is_alive, this);
@@ -656,7 +642,7 @@
 #endif
 
   // Ensure that all metadata is still alive
-  verify_metadata_loaders(low_boundary, is_alive);
+  verify_metadata_loaders(low_boundary);
 
   return postponed;
 }
--- a/src/hotspot/share/code/compiledMethod.hpp	Wed Apr 18 10:03:49 2018 -0700
+++ b/src/hotspot/share/code/compiledMethod.hpp	Wed Apr 18 13:37:39 2018 -0400
@@ -295,7 +295,7 @@
   void release_set_exception_cache(ExceptionCache *ec);
   address handler_for_exception_and_pc(Handle exception, address pc);
   void add_handler_for_exception_and_pc(Handle exception, address pc, address handler);
-  void clean_exception_cache(BoolObjectClosure* is_alive);
+  void clean_exception_cache();
 
   void add_exception_cache_entry(ExceptionCache* new_entry);
   ExceptionCache* exception_cache_entry_for_exception(Handle exception);
@@ -364,10 +364,10 @@
   void set_unloading_next(CompiledMethod* next) { _unloading_next = next; }
   CompiledMethod* unloading_next()              { return _unloading_next; }
 
-  void static clean_ic_if_metadata_is_dead(CompiledIC *ic, BoolObjectClosure *is_alive);
+  void static clean_ic_if_metadata_is_dead(CompiledIC *ic);
 
   // Check that all metadata is still alive
-  void verify_metadata_loaders(address low_boundary, BoolObjectClosure* is_alive);
+  void verify_metadata_loaders(address low_boundary);
 
   virtual void do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred);
   //  The parallel versions are used by G1.
--- a/src/hotspot/share/code/nmethod.cpp	Wed Apr 18 10:03:49 2018 -0700
+++ b/src/hotspot/share/code/nmethod.cpp	Wed Apr 18 13:37:39 2018 -0400
@@ -1365,7 +1365,7 @@
         }
         // During GC the is_alive closure is non-NULL, and is used to
         // determine liveness of dependees that need to be updated.
-        if (is_alive == NULL || klass->is_loader_alive(is_alive)) {
+        if (is_alive == NULL || klass->is_loader_alive()) {
           // The GC defers deletion of this entry, since there might be multiple threads
           // iterating over the _dependencies graph. Other call paths are single-threaded
           // and may delete it immediately.
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Wed Apr 18 10:03:49 2018 -0700
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Wed Apr 18 13:37:39 2018 -0400
@@ -5244,7 +5244,7 @@
       CodeCache::do_unloading(&_is_alive_closure, purged_class);
 
       // Prune dead klasses from subklass/sibling/implementor lists.
-      Klass::clean_weak_klass_links(&_is_alive_closure);
+      Klass::clean_weak_klass_links();
     }
 
     {
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Wed Apr 18 10:03:49 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Wed Apr 18 13:37:39 2018 -0400
@@ -3457,13 +3457,11 @@
 Monitor* G1CodeCacheUnloadingTask::_lock = new Monitor(Mutex::leaf, "Code Cache Unload lock", false, Monitor::_safepoint_check_never);
 
 class G1KlassCleaningTask : public StackObj {
-  BoolObjectClosure*                      _is_alive;
   volatile int                            _clean_klass_tree_claimed;
   ClassLoaderDataGraphKlassIteratorAtomic _klass_iterator;
 
  public:
-  G1KlassCleaningTask(BoolObjectClosure* is_alive) :
-      _is_alive(is_alive),
+  G1KlassCleaningTask() :
       _clean_klass_tree_claimed(0),
       _klass_iterator() {
   }
@@ -3490,7 +3488,7 @@
 public:
 
   void clean_klass(InstanceKlass* ik) {
-    ik->clean_weak_instanceklass_links(_is_alive);
+    ik->clean_weak_instanceklass_links();
   }
 
   void work() {
@@ -3498,7 +3496,7 @@
 
     // One worker will clean the subklass/sibling klass tree.
     if (claim_clean_klass_tree_task()) {
-      Klass::clean_subklass_tree(_is_alive);
+      Klass::clean_subklass_tree();
     }
 
     // All workers will help cleaning the classes,
@@ -3545,7 +3543,7 @@
       AbstractGangTask("Parallel Cleaning"),
       _string_symbol_task(is_alive, true, true, G1StringDedup::is_enabled()),
       _code_cache_task(num_workers, is_alive, unloading_occurred),
-      _klass_cleaning_task(is_alive),
+      _klass_cleaning_task(),
       _resolved_method_cleaning_task() {
   }
 
--- a/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Wed Apr 18 10:03:49 2018 -0700
+++ b/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Wed Apr 18 13:37:39 2018 -0400
@@ -562,7 +562,7 @@
     CodeCache::do_unloading(is_alive_closure(), purged_class);
 
     // Prune dead klasses from subklass/sibling/implementor lists.
-    Klass::clean_weak_klass_links(is_alive_closure());
+    Klass::clean_weak_klass_links();
   }
 
   {
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Wed Apr 18 10:03:49 2018 -0700
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Wed Apr 18 13:37:39 2018 -0400
@@ -2139,7 +2139,7 @@
     CodeCache::do_unloading(is_alive_closure(), purged_class);
 
     // Prune dead klasses from subklass/sibling/implementor lists.
-    Klass::clean_weak_klass_links(is_alive_closure());
+    Klass::clean_weak_klass_links();
   }
 
   {
--- a/src/hotspot/share/gc/serial/genMarkSweep.cpp	Wed Apr 18 10:03:49 2018 -0700
+++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp	Wed Apr 18 13:37:39 2018 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -234,7 +234,7 @@
     CodeCache::do_unloading(&is_alive, purged_class);
 
     // Prune dead klasses from subklass/sibling/implementor lists.
-    Klass::clean_weak_klass_links(&is_alive);
+    Klass::clean_weak_klass_links();
   }
 
   {
--- a/src/hotspot/share/oops/compiledICHolder.hpp	Wed Apr 18 10:03:49 2018 -0700
+++ b/src/hotspot/share/oops/compiledICHolder.hpp	Wed Apr 18 13:37:39 2018 -0400
@@ -74,12 +74,12 @@
   CompiledICHolder* next()     { return _next; }
   void set_next(CompiledICHolder* n) { _next = n; }
 
-  inline bool is_loader_alive(BoolObjectClosure* is_alive) {
+  inline bool is_loader_alive() {
     Klass* k = _is_metadata_method ? ((Method*)_holder_metadata)->method_holder() : (Klass*)_holder_metadata;
-    if (!k->is_loader_alive(is_alive)) {
+    if (!k->is_loader_alive()) {
       return false;
     }
-    if (!_holder_klass->is_loader_alive(is_alive)) {
+    if (!_holder_klass->is_loader_alive()) {
       return false;
     }
     return true;
--- a/src/hotspot/share/oops/instanceKlass.cpp	Wed Apr 18 10:03:49 2018 -0700
+++ b/src/hotspot/share/oops/instanceKlass.cpp	Wed Apr 18 13:37:39 2018 -0400
@@ -1891,22 +1891,22 @@
 }
 #endif //PRODUCT
 
-void InstanceKlass::clean_weak_instanceklass_links(BoolObjectClosure* is_alive) {
-  clean_implementors_list(is_alive);
-  clean_method_data(is_alive);
+void InstanceKlass::clean_weak_instanceklass_links() {
+  clean_implementors_list();
+  clean_method_data();
 
   // Since GC iterates InstanceKlasses sequentially, it is safe to remove stale entries here.
   DependencyContext dep_context(&_dep_context);
   dep_context.expunge_stale_entries();
 }
 
-void InstanceKlass::clean_implementors_list(BoolObjectClosure* is_alive) {
-  assert(class_loader_data()->is_alive(), "this klass should be live");
+void InstanceKlass::clean_implementors_list() {
+  assert(is_loader_alive(), "this klass should be live");
   if (is_interface()) {
     if (ClassUnloading) {
       Klass* impl = implementor();
       if (impl != NULL) {
-        if (!impl->is_loader_alive(is_alive)) {
+        if (!impl->is_loader_alive()) {
           // remove this guy
           Klass** klass = adr_implementor();
           assert(klass != NULL, "null klass");
@@ -1919,11 +1919,11 @@
   }
 }
 
-void InstanceKlass::clean_method_data(BoolObjectClosure* is_alive) {
+void InstanceKlass::clean_method_data() {
   for (int m = 0; m < methods()->length(); m++) {
     MethodData* mdo = methods()->at(m)->method_data();
     if (mdo != NULL) {
-      mdo->clean_method_data(is_alive);
+      mdo->clean_method_data(/*always_clean*/false);
     }
   }
 }
--- a/src/hotspot/share/oops/instanceKlass.hpp	Wed Apr 18 10:03:49 2018 -0700
+++ b/src/hotspot/share/oops/instanceKlass.hpp	Wed Apr 18 13:37:39 2018 -0400
@@ -1148,9 +1148,9 @@
   void adjust_default_methods(InstanceKlass* holder, bool* trace_name_printed);
 #endif // INCLUDE_JVMTI
 
-  void clean_weak_instanceklass_links(BoolObjectClosure* is_alive);
-  void clean_implementors_list(BoolObjectClosure* is_alive);
-  void clean_method_data(BoolObjectClosure* is_alive);
+  void clean_weak_instanceklass_links();
+  void clean_implementors_list();
+  void clean_method_data();
 
   // Explicit metaspace deallocation of fields
   // For RedefineClasses and class file parsing errors, we need to deallocate
--- a/src/hotspot/share/oops/klass.cpp	Wed Apr 18 10:03:49 2018 -0700
+++ b/src/hotspot/share/oops/klass.cpp	Wed Apr 18 13:37:39 2018 -0400
@@ -381,22 +381,7 @@
   debug_only(verify();)
 }
 
-bool Klass::is_loader_alive(BoolObjectClosure* is_alive) {
-#ifdef ASSERT
-  // The class is alive iff the class loader is alive.
-  oop loader = class_loader();
-  bool loader_alive = (loader == NULL) || is_alive->do_object_b(loader);
-#endif // ASSERT
-
-  // The class is alive if it's mirror is alive (which should be marked if the
-  // loader is alive) unless it's an anoymous class.
-  bool mirror_alive = is_alive->do_object_b(java_mirror());
-  assert(!mirror_alive || loader_alive, "loader must be alive if the mirror is"
-                        " but not the other way around with anonymous classes");
-  return mirror_alive;
-}
-
-void Klass::clean_weak_klass_links(BoolObjectClosure* is_alive, bool clean_alive_klasses) {
+void Klass::clean_weak_klass_links(bool clean_alive_klasses) {
   if (!ClassUnloading) {
     return;
   }
@@ -408,11 +393,11 @@
   while (!stack.is_empty()) {
     Klass* current = stack.pop();
 
-    assert(current->is_loader_alive(is_alive), "just checking, this should be live");
+    assert(current->is_loader_alive(), "just checking, this should be live");
 
     // Find and set the first alive subklass
     Klass* sub = current->subklass();
-    while (sub != NULL && !sub->is_loader_alive(is_alive)) {
+    while (sub != NULL && !sub->is_loader_alive()) {
 #ifndef PRODUCT
       if (log_is_enabled(Trace, class, unload)) {
         ResourceMark rm;
@@ -428,7 +413,7 @@
 
     // Find and set the first alive sibling
     Klass* sibling = current->next_sibling();
-    while (sibling != NULL && !sibling->is_loader_alive(is_alive)) {
+    while (sibling != NULL && !sibling->is_loader_alive()) {
       if (log_is_enabled(Trace, class, unload)) {
         ResourceMark rm;
         log_trace(class, unload)("[Unlinking class (sibling) %s]", sibling->external_name());
@@ -443,12 +428,12 @@
     // Clean the implementors list and method data.
     if (clean_alive_klasses && current->is_instance_klass()) {
       InstanceKlass* ik = InstanceKlass::cast(current);
-      ik->clean_weak_instanceklass_links(is_alive);
+      ik->clean_weak_instanceklass_links();
 
       // JVMTI RedefineClasses creates previous versions that are not in
       // the class hierarchy, so process them here.
       while ((ik = ik->previous_versions()) != NULL) {
-        ik->clean_weak_instanceklass_links(is_alive);
+        ik->clean_weak_instanceklass_links();
       }
     }
   }
--- a/src/hotspot/share/oops/klass.hpp	Wed Apr 18 10:03:49 2018 -0700
+++ b/src/hotspot/share/oops/klass.hpp	Wed Apr 18 13:37:39 2018 -0400
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_OOPS_KLASS_HPP
 #define SHARE_VM_OOPS_KLASS_HPP
 
+#include "classfile/classLoaderData.hpp"
 #include "gc/shared/specialized_oop_closures.hpp"
 #include "memory/iterator.hpp"
 #include "memory/memRegion.hpp"
@@ -52,7 +53,6 @@
 // Forward declarations.
 template <class T> class Array;
 template <class T> class GrowableArray;
-class ClassLoaderData;
 class fieldDescriptor;
 class KlassSizeStats;
 class klassVtable;
@@ -634,13 +634,12 @@
   virtual MetaspaceObj::Type type() const { return ClassType; }
 
   // Iff the class loader (or mirror for anonymous classes) is alive the
-  // Klass is considered alive.
-  // The is_alive closure passed in depends on the Garbage Collector used.
-  bool is_loader_alive(BoolObjectClosure* is_alive);
+  // Klass is considered alive.  Has already been marked as unloading.
+  bool is_loader_alive() const { return !class_loader_data()->is_unloading(); }
 
-  static void clean_weak_klass_links(BoolObjectClosure* is_alive, bool clean_alive_klasses = true);
-  static void clean_subklass_tree(BoolObjectClosure* is_alive) {
-    clean_weak_klass_links(is_alive, false /* clean_alive_klasses */);
+  static void clean_weak_klass_links(bool clean_alive_klasses = true);
+  static void clean_subklass_tree() {
+    clean_weak_klass_links(false /* clean_alive_klasses */);
   }
 
   // GC specific object visitors
--- a/src/hotspot/share/oops/methodData.cpp	Wed Apr 18 10:03:49 2018 -0700
+++ b/src/hotspot/share/oops/methodData.cpp	Wed Apr 18 13:37:39 2018 -0400
@@ -71,9 +71,9 @@
   }
 }
 
-void DataLayout::clean_weak_klass_links(BoolObjectClosure* cl) {
+void DataLayout::clean_weak_klass_links(bool always_clean) {
   ResourceMark m;
-  data_in()->clean_weak_klass_links(cl);
+  data_in()->clean_weak_klass_links(always_clean);
 }
 
 
@@ -315,23 +315,20 @@
   }
 }
 
-bool TypeEntries::is_loader_alive(BoolObjectClosure* is_alive_cl, intptr_t p) {
-  Klass* k = (Klass*)klass_part(p);
-  return k != NULL && k->is_loader_alive(is_alive_cl);
-}
-
-void TypeStackSlotEntries::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
+void TypeStackSlotEntries::clean_weak_klass_links(bool always_clean) {
   for (int i = 0; i < _number_of_entries; i++) {
     intptr_t p = type(i);
-    if (!is_loader_alive(is_alive_cl, p)) {
+    Klass* k = (Klass*)klass_part(p);
+    if (k != NULL && (always_clean || !k->is_loader_alive())) {
       set_type(i, with_status((Klass*)NULL, p));
     }
   }
 }
 
-void ReturnTypeEntry::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
+void ReturnTypeEntry::clean_weak_klass_links(bool always_clean) {
   intptr_t p = type();
-  if (!is_loader_alive(is_alive_cl, p)) {
+  Klass* k = (Klass*)klass_part(p);
+  if (k != NULL && (always_clean || !k->is_loader_alive())) {
     set_type(with_status((Klass*)NULL, p));
   }
 }
@@ -408,21 +405,21 @@
 // that the check is reached, and a series of (Klass*, count) pairs
 // which are used to store a type profile for the receiver of the check.
 
-void ReceiverTypeData::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
+void ReceiverTypeData::clean_weak_klass_links(bool always_clean) {
     for (uint row = 0; row < row_limit(); row++) {
     Klass* p = receiver(row);
-    if (p != NULL && !p->is_loader_alive(is_alive_cl)) {
+    if (p != NULL && (always_clean || !p->is_loader_alive())) {
       clear_row(row);
     }
   }
 }
 
 #if INCLUDE_JVMCI
-void VirtualCallData::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
-  ReceiverTypeData::clean_weak_klass_links(is_alive_cl);
+void VirtualCallData::clean_weak_klass_links(bool always_clean) {
+  ReceiverTypeData::clean_weak_klass_links(always_clean);
   for (uint row = 0; row < method_row_limit(); row++) {
     Method* p = method(row);
-    if (p != NULL && !p->method_holder()->is_loader_alive(is_alive_cl)) {
+    if (p != NULL && (always_clean || !p->method_holder()->is_loader_alive())) {
       clear_method_row(row);
     }
   }
@@ -1669,12 +1666,11 @@
 
 // Check for entries that reference an unloaded method
 class CleanExtraDataKlassClosure : public CleanExtraDataClosure {
-private:
-  BoolObjectClosure* _is_alive;
+  bool _always_clean;
 public:
-  CleanExtraDataKlassClosure(BoolObjectClosure* is_alive) : _is_alive(is_alive) {}
+  CleanExtraDataKlassClosure(bool always_clean) : _always_clean(always_clean) {}
   bool is_live(Method* m) {
-    return m->method_holder()->is_loader_alive(_is_alive);
+    return !(_always_clean) && m->method_holder()->is_loader_alive();
   }
 };
 
@@ -1757,19 +1753,19 @@
 #endif
 }
 
-void MethodData::clean_method_data(BoolObjectClosure* is_alive) {
+void MethodData::clean_method_data(bool always_clean) {
   ResourceMark rm;
   for (ProfileData* data = first_data();
        is_valid(data);
        data = next_data(data)) {
-    data->clean_weak_klass_links(is_alive);
+    data->clean_weak_klass_links(always_clean);
   }
   ParametersTypeData* parameters = parameters_type_data();
   if (parameters != NULL) {
-    parameters->clean_weak_klass_links(is_alive);
+    parameters->clean_weak_klass_links(always_clean);
   }
 
-  CleanExtraDataKlassClosure cl(is_alive);
+  CleanExtraDataKlassClosure cl(always_clean);
   clean_extra_data(&cl);
   verify_extra_data_clean(&cl);
 }
--- a/src/hotspot/share/oops/methodData.hpp	Wed Apr 18 10:03:49 2018 -0700
+++ b/src/hotspot/share/oops/methodData.hpp	Wed Apr 18 13:37:39 2018 -0400
@@ -254,7 +254,7 @@
   ProfileData* data_in();
 
   // GC support
-  void clean_weak_klass_links(BoolObjectClosure* cl);
+  void clean_weak_klass_links(bool always_clean);
 
   // Redefinition support
   void clean_weak_method_links();
@@ -505,7 +505,7 @@
   virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {}
 
   // GC support
-  virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {}
+  virtual void clean_weak_klass_links(bool always_clean) {}
 
   // Redefinition support
   virtual void clean_weak_method_links() {}
@@ -820,9 +820,6 @@
 
   static void print_klass(outputStream* st, intptr_t k);
 
-  // GC support
-  static bool is_loader_alive(BoolObjectClosure* is_alive_cl, intptr_t p);
-
 protected:
   // ProfileData object these entries are part of
   ProfileData* _pd;
@@ -930,7 +927,7 @@
   }
 
   // GC support
-  void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
+  void clean_weak_klass_links(bool always_clean);
 
   void print_data_on(outputStream* st) const;
 };
@@ -973,7 +970,7 @@
   }
 
   // GC support
-  void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
+  void clean_weak_klass_links(bool always_clean);
 
   void print_data_on(outputStream* st) const;
 };
@@ -1157,12 +1154,12 @@
   }
 
   // GC support
-  virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
+  virtual void clean_weak_klass_links(bool always_clean) {
     if (has_arguments()) {
-      _args.clean_weak_klass_links(is_alive_closure);
+      _args.clean_weak_klass_links(always_clean);
     }
     if (has_return()) {
-      _ret.clean_weak_klass_links(is_alive_closure);
+      _ret.clean_weak_klass_links(always_clean);
     }
   }
 
@@ -1303,7 +1300,7 @@
   }
 
   // GC support
-  virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
+  virtual void clean_weak_klass_links(bool always_clean);
 
 #ifdef CC_INTERP
   static int receiver_type_data_size_in_bytes() {
@@ -1433,7 +1430,7 @@
   }
 
   // GC support
-  virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
+  virtual void clean_weak_klass_links(bool always_clean);
 
   // Redefinition support
   virtual void clean_weak_method_links();
@@ -1562,13 +1559,13 @@
   }
 
   // GC support
-  virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
-    ReceiverTypeData::clean_weak_klass_links(is_alive_closure);
+  virtual void clean_weak_klass_links(bool always_clean) {
+    ReceiverTypeData::clean_weak_klass_links(always_clean);
     if (has_arguments()) {
-      _args.clean_weak_klass_links(is_alive_closure);
+      _args.clean_weak_klass_links(always_clean);
     }
     if (has_return()) {
-      _ret.clean_weak_klass_links(is_alive_closure);
+      _ret.clean_weak_klass_links(always_clean);
     }
   }
 
@@ -2021,8 +2018,8 @@
     _parameters.set_type(i, TypeEntries::with_status((intptr_t)k, current));
   }
 
-  virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
-    _parameters.clean_weak_klass_links(is_alive_closure);
+  virtual void clean_weak_klass_links(bool always_clean) {
+    _parameters.clean_weak_klass_links(always_clean);
   }
 
   virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
@@ -2610,7 +2607,7 @@
   static bool profile_parameters();
   static bool profile_return_jsr292_only();
 
-  void clean_method_data(BoolObjectClosure* is_alive);
+  void clean_method_data(bool always_clean);
   void clean_weak_method_links();
   DEBUG_ONLY(void verify_clean_weak_method_links();)
   Mutex* extra_data_lock() { return &_extra_data_lock; }
--- a/src/hotspot/share/prims/whitebox.cpp	Wed Apr 18 10:03:49 2018 -0700
+++ b/src/hotspot/share/prims/whitebox.cpp	Wed Apr 18 13:37:39 2018 -0400
@@ -933,8 +933,6 @@
   return result;
 WB_END
 
-static AlwaysFalseClosure always_false;
-
 WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method))
   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
   CHECK_JNI_EXCEPTION(env);
@@ -951,7 +949,7 @@
       mdo->set_arg_modified(i, 0);
     }
     MutexLockerEx mu(mdo->extra_data_lock());
-    mdo->clean_method_data(&always_false);
+    mdo->clean_method_data(/*always_clean*/true);
   }
 
   mh->clear_not_c1_compilable();