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
--- 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();