8162553: Crash in class unloading due to null CLD having a zero _keep_alive value
authorlfoltan
Thu, 11 Aug 2016 11:41:11 -0400
changeset 40358 48774f26918a
parent 40356 df5e8cabdf10
child 40359 206583c1caaa
8162553: Crash in class unloading due to null CLD having a zero _keep_alive value Summary: Correct the refcounting of ClassLoaderData::_keep_alive for anonymous classes. Reviewed-by: acorn, coleenp, dholmes, jiangli
hotspot/src/share/vm/classfile/classLoaderData.cpp
hotspot/src/share/vm/classfile/classLoaderData.hpp
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp	Wed Aug 10 21:02:14 2016 -0400
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp	Thu Aug 11 11:41:11 2016 -0400
@@ -126,13 +126,17 @@
 // ClassLoaderData, no other non-GC thread has knowledge of the anonymous class while
 // it is being defined, therefore _keep_alive is not volatile or atomic.
 void ClassLoaderData::inc_keep_alive() {
-  assert(_keep_alive >= 0, "Invalid keep alive count");
-  _keep_alive++;
+  if (is_anonymous()) {
+    assert(_keep_alive >= 0, "Invalid keep alive increment count");
+    _keep_alive++;
+  }
 }
 
 void ClassLoaderData::dec_keep_alive() {
-  assert(_keep_alive > 0, "Invalid keep alive count");
-  _keep_alive--;
+  if (is_anonymous()) {
+    assert(_keep_alive > 0, "Invalid keep alive decrement count");
+    _keep_alive--;
+  }
 }
 
 void ClassLoaderData::oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) {
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp	Wed Aug 10 21:02:14 2016 -0400
+++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp	Thu Aug 11 11:41:11 2016 -0400
@@ -176,9 +176,9 @@
   Mutex* _metaspace_lock;  // Locks the metaspace for allocations and setup.
   bool _unloading;         // true if this class loader goes away
   bool _is_anonymous;      // if this CLD is for an anonymous class
-  int _keep_alive;         // if this CLD is kept alive without a keep_alive_object().
-                           // Currently used solely for anonymous classes.
-                           // _keep_alive does not need to be volatile or
+  s2 _keep_alive;          // if this CLD is kept alive without a keep_alive_object().
+                           // Used for anonymous classes and the boot class
+                           // loader. _keep_alive does not need to be volatile or
                            // atomic since there is one unique CLD per anonymous class.
   volatile int _claimed;   // true if claimed, for example during GC traces.
                            // To avoid applying oop closure more than once.
@@ -289,6 +289,8 @@
     return _unloading;
   }
 
+  // Used to refcount an anonymous class's CLD in order to
+  // indicate their aliveness without a keep_alive_object().
   void inc_keep_alive();
   void dec_keep_alive();