# HG changeset patch # User lfoltan # Date 1470930071 14400 # Node ID 48774f26918a61cee448601eca3276c44ff6aa76 # Parent df5e8cabdf10592b85002141b537bfbf0aad5aa1 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 diff -r df5e8cabdf10 -r 48774f26918a hotspot/src/share/vm/classfile/classLoaderData.cpp --- 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) { diff -r df5e8cabdf10 -r 48774f26918a hotspot/src/share/vm/classfile/classLoaderData.hpp --- 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();