--- old/src/share/vm/classfile/classLoaderData.cpp 2017-08-29 09:39:42.998261458 -0400 +++ new/src/share/vm/classfile/classLoaderData.cpp 2017-08-29 09:39:42.621496618 -0400 @@ -75,6 +75,9 @@ #include "utilities/growableArray.hpp" #include "utilities/macros.hpp" #include "utilities/ostream.hpp" +#if INCLUDE_ALL_GCS +#include "gc/g1/g1SATBCardTableModRefBS.hpp" +#endif // INCLUDE_ALL_GCS #if INCLUDE_TRACE #include "trace/tracing.hpp" #endif @@ -764,6 +767,25 @@ return OopHandle(_handles.add(h())); } +void ClassLoaderData::remove_handle(OopHandle h) { + oop* ptr = h.ptr_raw(); + if (ptr != NULL) { + assert(_handles.contains(ptr), "Got unexpected handle " PTR_FORMAT, p2i(ptr)); +#if INCLUDE_ALL_GCS + // This barrier is used by G1 to remember the old oop values, so + // that we don't forget any objects that were live at the snapshot at + // the beginning. + if (UseG1GC) { + oop obj = *ptr; + if (obj != NULL) { + G1SATBCardTableModRefBS::enqueue(obj); + } + } +#endif + *ptr = NULL; + } +} + void ClassLoaderData::init_handle_locked(OopHandle& dest, Handle h) { MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag); if (dest.resolve() != NULL) { --- old/src/share/vm/classfile/classLoaderData.hpp 2017-08-29 09:39:51.361072401 -0400 +++ new/src/share/vm/classfile/classLoaderData.hpp 2017-08-29 09:39:51.120480250 -0400 @@ -364,6 +364,7 @@ const char* loader_name(); OopHandle add_handle(Handle h); + void remove_handle(OopHandle h); void init_handle_locked(OopHandle& pd, Handle h); // used for concurrent access to ModuleEntry::_pd field void add_class(Klass* k, bool publicize = true); void remove_class(Klass* k); --- old/src/share/vm/oops/constantPool.cpp 2017-08-29 09:39:59.253503278 -0400 +++ new/src/share/vm/oops/constantPool.cpp 2017-08-29 09:39:58.849260733 -0400 @@ -89,8 +89,6 @@ void ConstantPool::deallocate_contents(ClassLoaderData* loader_data) { if (cache() != NULL) { - MetadataFactory::free_array(loader_data, reference_map()); - set_reference_map(NULL); MetadataFactory::free_metadata(loader_data, cache()); set_cache(NULL); } --- old/src/share/vm/oops/cpCache.cpp 2017-08-29 09:40:06.975507195 -0400 +++ new/src/share/vm/oops/cpCache.cpp 2017-08-29 09:40:06.716644195 -0400 @@ -26,6 +26,7 @@ #include "interpreter/interpreter.hpp" #include "interpreter/rewriter.hpp" #include "logging/log.hpp" +#include "memory/metadataFactory.hpp" #include "memory/metaspaceClosure.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.inline.hpp" @@ -608,6 +609,13 @@ } } +void ConstantPoolCache::deallocate_contents(ClassLoaderData* data) { + data->remove_handle(_resolved_references); + set_resolved_references(NULL); + MetadataFactory::free_array(data, _reference_map); + set_reference_map(NULL); +} + #if INCLUDE_CDS_JAVA_HEAP oop ConstantPoolCache::archived_references() { assert(UseSharedSpaces, "UseSharedSpaces expected."); --- old/src/share/vm/oops/cpCache.hpp 2017-08-29 09:40:15.353007064 -0400 +++ new/src/share/vm/oops/cpCache.hpp 2017-08-29 09:40:15.105657330 -0400 @@ -510,9 +510,9 @@ void dump_cache(); #endif // INCLUDE_JVMTI - // Deallocate - no fields to deallocate + // RedefineClasses support DEBUG_ONLY(bool on_stack() { return false; }) - void deallocate_contents(ClassLoaderData* data) {} + void deallocate_contents(ClassLoaderData* data); bool is_klass() const { return false; } // Printing --- old/src/share/vm/oops/oopHandle.hpp 2017-08-29 09:40:23.034361240 -0400 +++ new/src/share/vm/oops/oopHandle.hpp 2017-08-29 09:40:22.790213297 -0400 @@ -46,6 +46,9 @@ OopHandle(oop* w) : _obj(w) {} oop resolve() const { return (_obj == NULL) ? (oop)NULL : *_obj; } + + // Used only for removing handle. + oop* ptr_raw() { return _obj; } }; #endif // SHARE_VM_OOPS_OOPHANDLE_HPP