diff --git a/src/share/vm/classfile/classLoaderData.cpp b/src/share/vm/classfile/classLoaderData.cpp index e20de3c252a2fca888f6ced39cf6e974718ea70e..6cafd76c8522b525cf835b297ad51088d7f357dd 100644 --- a/src/share/vm/classfile/classLoaderData.cpp +++ b/src/share/vm/classfile/classLoaderData.cpp @@ -277,6 +277,9 @@ void ClassLoaderData::remove_class(Klass* scratch_class) { 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 @@ bool ClassLoaderData::is_alive(BoolObjectClosure* is_alive_closure) const { 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 --git a/src/share/vm/classfile/dictionary.cpp b/src/share/vm/classfile/dictionary.cpp index f400a0c0e3f7e2d1bdd188b09ea1cc012eb74cdf..92d9fb438fe6e3b54bcbf55fa2f18f110ea653dd 100644 --- a/src/share/vm/classfile/dictionary.cpp +++ b/src/share/vm/classfile/dictionary.cpp @@ -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 @@ bool Dictionary::do_unloading() { 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 --git a/src/share/vm/oops/instanceKlass.cpp b/src/share/vm/oops/instanceKlass.cpp index fa4a8077d5aa5b61a16f02b7411a4390673b03ec..6f27606714a0197a81d591619e80b616d746a08e 100644 --- a/src/share/vm/oops/instanceKlass.cpp +++ b/src/share/vm/oops/instanceKlass.cpp @@ -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 @@ static void clear_all_breakpoints(Method* m) { 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 --git a/src/share/vm/oops/instanceKlass.hpp b/src/share/vm/oops/instanceKlass.hpp index 8c557a9ea07ba53b0881bce860e1bd213e29b94b..62e195769de40d28bb848d08783f4f34a14874dc 100644 --- a/src/share/vm/oops/instanceKlass.hpp +++ b/src/share/vm/oops/instanceKlass.hpp @@ -236,7 +236,7 @@ class InstanceKlass: public Klass { _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 @@ class InstanceKlass: public Klass { // 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 @@ private: // 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();