Mercurial > hg > graal-jvmci-8
diff src/share/vm/memory/compactingPermGenGen.cpp @ 47:2c106685d6d0
6497639: 4/3 Profiling Swing application caused JVM crash
Summary: Make RedefineClasses() interoperate better with class sharing.
Reviewed-by: sspitsyn, jmasa
author | dcubed |
---|---|
date | Wed, 12 Mar 2008 18:06:50 -0700 |
parents | a61af66fc99e |
children | ba764ed4b6f2 |
line wrap: on
line diff
--- a/src/share/vm/memory/compactingPermGenGen.cpp Fri Feb 29 20:03:58 2008 -0800 +++ b/src/share/vm/memory/compactingPermGenGen.cpp Wed Mar 12 18:06:50 2008 -0700 @@ -26,9 +26,27 @@ #include "incls/_compactingPermGenGen.cpp.incl" -// Recursively adjust all pointers in an object and all objects by -// referenced it. Clear marks on objects in order to prevent visiting -// any object twice. +// An ObjectClosure helper: Recursively adjust all pointers in an object +// and all objects by referenced it. Clear marks on objects in order to +// prevent visiting any object twice. This helper is used when the +// RedefineClasses() API has been called. + +class AdjustSharedObjectClosure : public ObjectClosure { +public: + void do_object(oop obj) { + if (obj->is_shared_readwrite()) { + if (obj->mark()->is_marked()) { + obj->init_mark(); // Don't revisit this object. + obj->adjust_pointers(); // Adjust this object's references. + } + } + } +}; + + +// An OopClosure helper: Recursively adjust all pointers in an object +// and all objects by referenced it. Clear marks on objects in order +// to prevent visiting any object twice. class RecursiveAdjustSharedObjectClosure : public OopClosure { public: @@ -274,15 +292,34 @@ // objects in the space will page in more objects than we need. // Instead, use the system dictionary as strong roots into the read // write space. +// +// If a RedefineClasses() call has been made, then we have to iterate +// over the entire shared read-write space in order to find all the +// objects that need to be forwarded. For example, it is possible for +// an nmethod to be found and marked in GC phase-1 only for the nmethod +// to be freed by the time we reach GC phase-3. The underlying method +// is still marked, but we can't (easily) find it in GC phase-3 so we +// blow up in GC phase-4. With RedefineClasses() we want replaced code +// (EMCP or obsolete) to go away (i.e., be collectible) once it is no +// longer being executed by any thread so we keep minimal attachments +// to the replaced code. However, we can't guarantee when those EMCP +// or obsolete methods will be collected so they may still be out there +// even after we've severed our minimal attachments. void CompactingPermGenGen::pre_adjust_pointers() { if (spec()->enable_shared_spaces()) { - RecursiveAdjustSharedObjectClosure blk; - Universe::oops_do(&blk); - StringTable::oops_do(&blk); - SystemDictionary::always_strong_classes_do(&blk); - TraversePlaceholdersClosure tpc; - SystemDictionary::placeholders_do(&tpc); + if (JvmtiExport::has_redefined_a_class()) { + // RedefineClasses() requires a brute force approach + AdjustSharedObjectClosure blk; + rw_space()->object_iterate(&blk); + } else { + RecursiveAdjustSharedObjectClosure blk; + Universe::oops_do(&blk); + StringTable::oops_do(&blk); + SystemDictionary::always_strong_classes_do(&blk); + TraversePlaceholdersClosure tpc; + SystemDictionary::placeholders_do(&tpc); + } } }