# HG changeset patch # User coleenp # Date 1366834775 14400 # Node ID d587a5c30bd8cbee9b5038a751c4922162d2ca21 # Parent cc70cbbd422edb11ac72523440154101c6acdd4f 8011803: release_C_heap_structures is never called for anonymous classes. Summary: Call this function from the ClassLoaderData destructor instead of the system dictionary walk. Reviewed-by: stefank, mgerdin diff -r cc70cbbd422e -r d587a5c30bd8 src/share/vm/classfile/classLoaderData.cpp --- a/src/share/vm/classfile/classLoaderData.cpp Wed Apr 24 09:00:04 2013 -0400 +++ b/src/share/vm/classfile/classLoaderData.cpp Wed Apr 24 16:19:35 2013 -0400 @@ -277,6 +277,9 @@ void ClassLoaderData::unload() { _unloading = true; + // Tell serviceability tools these classes are unloading + classes_do(InstanceKlass::notify_unload_class); + if (TraceClassLoaderData) { ResourceMark rm; tty->print("[ClassLoaderData: unload loader data "PTR_FORMAT, this); @@ -300,6 +303,9 @@ ClassLoaderData::~ClassLoaderData() { + // Release C heap structures for all the classes. + classes_do(InstanceKlass::release_C_heap_structures); + Metaspace *m = _metaspace; if (m != NULL) { _metaspace = NULL; diff -r cc70cbbd422e -r d587a5c30bd8 src/share/vm/classfile/dictionary.cpp --- a/src/share/vm/classfile/dictionary.cpp Wed Apr 24 09:00:04 2013 -0400 +++ b/src/share/vm/classfile/dictionary.cpp Wed Apr 24 16:19:35 2013 -0400 @@ -27,7 +27,6 @@ #include "classfile/systemDictionary.hpp" #include "oops/oop.inline.hpp" #include "prims/jvmtiRedefineClassesTrace.hpp" -#include "services/classLoadingService.hpp" #include "utilities/hashtable.inline.hpp" @@ -156,19 +155,7 @@ if (k_def_class_loader_data == loader_data) { // This is the defining entry, so the referred class is about // to be unloaded. - // Notify the debugger and clean up the class. class_was_unloaded = true; - // notify the debugger - if (JvmtiExport::should_post_class_unload()) { - JvmtiExport::post_class_unload(ik); - } - - // notify ClassLoadingService of class unload - ClassLoadingService::notify_class_unloaded(ik); - - // Clean up C heap - ik->release_C_heap_structures(); - ik->constants()->release_C_heap_structures(); } // Also remove this system dictionary entry. purge_entry = true; diff -r cc70cbbd422e -r d587a5c30bd8 src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Wed Apr 24 09:00:04 2013 -0400 +++ b/src/share/vm/oops/instanceKlass.cpp Wed Apr 24 16:19:35 2013 -0400 @@ -54,6 +54,7 @@ #include "runtime/javaCalls.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/thread.inline.hpp" +#include "services/classLoadingService.hpp" #include "services/threadService.hpp" #include "utilities/dtrace.hpp" #include "utilities/macros.hpp" @@ -2312,7 +2313,29 @@ m->clear_all_breakpoints(); } + +void InstanceKlass::notify_unload_class(InstanceKlass* ik) { + // notify the debugger + if (JvmtiExport::should_post_class_unload()) { + JvmtiExport::post_class_unload(ik); + } + + // notify ClassLoadingService of class unload + ClassLoadingService::notify_class_unloaded(ik); +} + +void InstanceKlass::release_C_heap_structures(InstanceKlass* ik) { + // Clean up C heap + ik->release_C_heap_structures(); + ik->constants()->release_C_heap_structures(); +} + void InstanceKlass::release_C_heap_structures() { + + // Can't release the constant pool here because the constant pool can be + // deallocated separately from the InstanceKlass for default methods and + // redefine classes. + // Deallocate oop map cache if (_oop_map_cache != NULL) { delete _oop_map_cache; diff -r cc70cbbd422e -r d587a5c30bd8 src/share/vm/oops/instanceKlass.hpp --- a/src/share/vm/oops/instanceKlass.hpp Wed Apr 24 09:00:04 2013 -0400 +++ b/src/share/vm/oops/instanceKlass.hpp Wed Apr 24 16:19:35 2013 -0400 @@ -236,7 +236,7 @@ _misc_rewritten = 1 << 0, // methods rewritten. _misc_has_nonstatic_fields = 1 << 1, // for sizing with UseCompressedOops _misc_should_verify_class = 1 << 2, // allow caching of preverification - _misc_is_anonymous = 1 << 3, // has embedded _inner_classes field + _misc_is_anonymous = 1 << 3, // has embedded _host_klass field _misc_is_contended = 1 << 4, // marked with contended annotation _misc_has_default_methods = 1 << 5 // class/superclass/implemented interfaces has default methods }; @@ -934,7 +934,9 @@ // referenced by handles. bool on_stack() const { return _constants->on_stack(); } - void release_C_heap_structures(); + // callbacks for actions during class unloading + static void notify_unload_class(InstanceKlass* ik); + static void release_C_heap_structures(InstanceKlass* ik); // Parallel Scavenge and Parallel Old PARALLEL_GC_DECLS @@ -1022,6 +1024,8 @@ // Returns the array class with this class as element type Klass* array_klass_impl(bool or_null, TRAPS); + // Free CHeap allocated fields. + void release_C_heap_structures(); public: // CDS support - remove and restore oops from metadata. Oops are not shared. virtual void remove_unshareable_info();