# HG changeset patch # User jmasa # Date 1231254305 28800 # Node ID e9be0e04635a5503bdcea7bd137de267678157b2 # Parent ca7d4823604813d7d8310b5885f21a9ea466d950 6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off Summary: Added safe_object_iterate() for use by JMapPerm. Reviewed-by: tonyp diff -r ca7d48236048 -r e9be0e04635a src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Sat Dec 20 00:45:18 2008 -0800 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Tue Jan 06 07:05:05 2009 -0800 @@ -706,6 +706,30 @@ } } +// Apply the given closure to each live object in the space +// The usage of CompactibleFreeListSpace +// by the ConcurrentMarkSweepGeneration for concurrent GC's allows +// objects in the space with references to objects that are no longer +// valid. For example, an object may reference another object +// that has already been sweep up (collected). This method uses +// obj_is_alive() to determine whether it is safe to apply the closure to +// an object. See obj_is_alive() for details on how liveness of an +// object is decided. + +void CompactibleFreeListSpace::safe_object_iterate(ObjectClosure* blk) { + assert_lock_strong(freelistLock()); + NOT_PRODUCT(verify_objects_initialized()); + HeapWord *cur, *limit; + size_t curSize; + for (cur = bottom(), limit = end(); cur < limit; + cur += curSize) { + curSize = block_size(cur); + if (block_is_obj(cur) && obj_is_alive(cur)) { + blk->do_object(oop(cur)); + } + } +} + void CompactibleFreeListSpace::object_iterate_mem(MemRegion mr, UpwardsObjectClosure* cl) { assert_locked(); diff -r ca7d48236048 -r e9be0e04635a src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Sat Dec 20 00:45:18 2008 -0800 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Tue Jan 06 07:05:05 2009 -0800 @@ -481,6 +481,15 @@ void oop_iterate(OopClosure* cl); void object_iterate(ObjectClosure* blk); + // Apply the closure to each object in the space whose references + // point to objects in the heap. The usage of CompactibleFreeListSpace + // by the ConcurrentMarkSweepGeneration for concurrent GC's allows + // objects in the space with references to objects that are no longer + // valid. For example, an object may reference another object + // that has already been sweep up (collected). This method uses + // obj_is_alive() to determine whether it is safe to iterate of + // an object. + void safe_object_iterate(ObjectClosure* blk); void object_iterate_mem(MemRegion mr, UpwardsObjectClosure* cl); // Requires that "mr" be entirely within the space. diff -r ca7d48236048 -r e9be0e04635a src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Sat Dec 20 00:45:18 2008 -0800 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Tue Jan 06 07:05:05 2009 -0800 @@ -3018,6 +3018,16 @@ } void +ConcurrentMarkSweepGeneration::safe_object_iterate(ObjectClosure* cl) { + if (freelistLock()->owned_by_self()) { + Generation::safe_object_iterate(cl); + } else { + MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag); + Generation::safe_object_iterate(cl); + } +} + +void ConcurrentMarkSweepGeneration::pre_adjust_pointers() { } @@ -7001,7 +7011,6 @@ _mut->clear_range(mr); } DEBUG_ONLY(}) - // Note: the finger doesn't advance while we drain // the stack below. PushOrMarkClosure pushOrMarkClosure(_collector, diff -r ca7d48236048 -r e9be0e04635a src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Sat Dec 20 00:45:18 2008 -0800 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Tue Jan 06 07:05:05 2009 -0800 @@ -1212,6 +1212,7 @@ // More iteration support virtual void oop_iterate(MemRegion mr, OopClosure* cl); virtual void oop_iterate(OopClosure* cl); + virtual void safe_object_iterate(ObjectClosure* cl); virtual void object_iterate(ObjectClosure* cl); // Need to declare the full complement of closures, whether we'll diff -r ca7d48236048 -r e9be0e04635a src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Sat Dec 20 00:45:18 2008 -0800 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Tue Jan 06 07:05:05 2009 -0800 @@ -850,6 +850,7 @@ // Iterate over all objects, calling "cl.do_object" on each. virtual void object_iterate(ObjectClosure* cl); + virtual void safe_object_iterate(ObjectClosure* cl) { object_iterate(cl); } // Iterate over all objects allocated since the last collection, calling // "cl.do_object" on each. The heap must have been initialized properly diff -r ca7d48236048 -r e9be0e04635a src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp --- a/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Sat Dec 20 00:45:18 2008 -0800 +++ b/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Tue Jan 06 07:05:05 2009 -0800 @@ -200,6 +200,7 @@ void oop_iterate(OopClosure* cl); void object_iterate(ObjectClosure* cl); + void safe_object_iterate(ObjectClosure* cl) { object_iterate(cl); } void permanent_oop_iterate(OopClosure* cl); void permanent_object_iterate(ObjectClosure* cl); diff -r ca7d48236048 -r e9be0e04635a src/share/vm/gc_interface/collectedHeap.hpp --- a/src/share/vm/gc_interface/collectedHeap.hpp Sat Dec 20 00:45:18 2008 -0800 +++ b/src/share/vm/gc_interface/collectedHeap.hpp Tue Jan 06 07:05:05 2009 -0800 @@ -466,6 +466,10 @@ // This includes objects in permanent memory. virtual void object_iterate(ObjectClosure* cl) = 0; + // Similar to object_iterate() except iterates only + // over live objects. + virtual void safe_object_iterate(ObjectClosure* cl) = 0; + // Behaves the same as oop_iterate, except only traverses // interior pointers contained in permanent memory. If there // is no permanent memory, does nothing. diff -r ca7d48236048 -r e9be0e04635a src/share/vm/memory/genCollectedHeap.cpp --- a/src/share/vm/memory/genCollectedHeap.cpp Sat Dec 20 00:45:18 2008 -0800 +++ b/src/share/vm/memory/genCollectedHeap.cpp Tue Jan 06 07:05:05 2009 -0800 @@ -910,6 +910,13 @@ perm_gen()->object_iterate(cl); } +void GenCollectedHeap::safe_object_iterate(ObjectClosure* cl) { + for (int i = 0; i < _n_gens; i++) { + _gens[i]->safe_object_iterate(cl); + } + perm_gen()->safe_object_iterate(cl); +} + void GenCollectedHeap::object_iterate_since_last_GC(ObjectClosure* cl) { for (int i = 0; i < _n_gens; i++) { _gens[i]->object_iterate_since_last_GC(cl); diff -r ca7d48236048 -r e9be0e04635a src/share/vm/memory/genCollectedHeap.hpp --- a/src/share/vm/memory/genCollectedHeap.hpp Sat Dec 20 00:45:18 2008 -0800 +++ b/src/share/vm/memory/genCollectedHeap.hpp Tue Jan 06 07:05:05 2009 -0800 @@ -215,6 +215,7 @@ void oop_iterate(OopClosure* cl); void oop_iterate(MemRegion mr, OopClosure* cl); void object_iterate(ObjectClosure* cl); + void safe_object_iterate(ObjectClosure* cl); void object_iterate_since_last_GC(ObjectClosure* cl); Space* space_containing(const void* addr) const; diff -r ca7d48236048 -r e9be0e04635a src/share/vm/memory/generation.cpp --- a/src/share/vm/memory/generation.cpp Sat Dec 20 00:45:18 2008 -0800 +++ b/src/share/vm/memory/generation.cpp Tue Jan 06 07:05:05 2009 -0800 @@ -319,6 +319,21 @@ space_iterate(&blk); } +class GenerationSafeObjIterateClosure : public SpaceClosure { + private: + ObjectClosure* _cl; + public: + virtual void do_space(Space* s) { + s->safe_object_iterate(_cl); + } + GenerationSafeObjIterateClosure(ObjectClosure* cl) : _cl(cl) {} +}; + +void Generation::safe_object_iterate(ObjectClosure* cl) { + GenerationSafeObjIterateClosure blk(cl); + space_iterate(&blk); +} + void Generation::prepare_for_compaction(CompactPoint* cp) { // Generic implementation, can be specialized CompactibleSpace* space = first_compaction_space(); diff -r ca7d48236048 -r e9be0e04635a src/share/vm/memory/generation.hpp --- a/src/share/vm/memory/generation.hpp Sat Dec 20 00:45:18 2008 -0800 +++ b/src/share/vm/memory/generation.hpp Tue Jan 06 07:05:05 2009 -0800 @@ -518,6 +518,11 @@ // each. virtual void object_iterate(ObjectClosure* cl); + // Iterate over all safe objects in the generation, calling "cl.do_object" on + // each. An object is safe if its references point to other objects in + // the heap. This defaults to object_iterate() unless overridden. + virtual void safe_object_iterate(ObjectClosure* cl); + // Iterate over all objects allocated in the generation since the last // collection, calling "cl.do_object" on each. The generation must have // been initialized properly to support this function, or else this call diff -r ca7d48236048 -r e9be0e04635a src/share/vm/memory/heapInspection.cpp --- a/src/share/vm/memory/heapInspection.cpp Sat Dec 20 00:45:18 2008 -0800 +++ b/src/share/vm/memory/heapInspection.cpp Tue Jan 06 07:05:05 2009 -0800 @@ -263,6 +263,9 @@ if (!cit.allocation_failed()) { // Iterate over objects in the heap RecordInstanceClosure ric(&cit); + // If this operation encounters a bad object when using CMS, + // consider using safe_object_iterate() which avoids perm gen + // objects that may contain bad references. Universe::heap()->object_iterate(&ric); // Report if certain classes are not counted because of @@ -317,5 +320,8 @@ // Iterate over objects in the heap FindInstanceClosure fic(k, result); + // If this operation encounters a bad object when using CMS, + // consider using safe_object_iterate() which avoids perm gen + // objects that may contain bad references. Universe::heap()->object_iterate(&fic); } diff -r ca7d48236048 -r e9be0e04635a src/share/vm/memory/space.cpp --- a/src/share/vm/memory/space.cpp Sat Dec 20 00:45:18 2008 -0800 +++ b/src/share/vm/memory/space.cpp Tue Jan 06 07:05:05 2009 -0800 @@ -705,6 +705,12 @@ object_iterate_from(bm, blk); } +// For a continguous space object_iterate() and safe_object_iterate() +// are the same. +void ContiguousSpace::safe_object_iterate(ObjectClosure* blk) { + object_iterate(blk); +} + void ContiguousSpace::object_iterate_from(WaterMark mark, ObjectClosure* blk) { assert(mark.space() == this, "Mark does not match space"); HeapWord* p = mark.point(); diff -r ca7d48236048 -r e9be0e04635a src/share/vm/memory/space.hpp --- a/src/share/vm/memory/space.hpp Sat Dec 20 00:45:18 2008 -0800 +++ b/src/share/vm/memory/space.hpp Tue Jan 06 07:05:05 2009 -0800 @@ -193,6 +193,9 @@ // each. Objects allocated by applications of the closure are not // included in the iteration. virtual void object_iterate(ObjectClosure* blk) = 0; + // Similar to object_iterate() except only iterates over + // objects whose internal references point to objects in the space. + virtual void safe_object_iterate(ObjectClosure* blk) = 0; // Iterate over all objects that intersect with mr, calling "cl->do_object" // on each. There is an exception to this: if this closure has already @@ -843,6 +846,9 @@ void oop_iterate(OopClosure* cl); void oop_iterate(MemRegion mr, OopClosure* cl); void object_iterate(ObjectClosure* blk); + // For contiguous spaces this method will iterate safely over objects + // in the space (i.e., between bottom and top) when at a safepoint. + void safe_object_iterate(ObjectClosure* blk); void object_iterate_mem(MemRegion mr, UpwardsObjectClosure* cl); // iterates on objects up to the safe limit HeapWord* object_iterate_careful(ObjectClosureCareful* cl); diff -r ca7d48236048 -r e9be0e04635a src/share/vm/prims/jvmtiTagMap.cpp --- a/src/share/vm/prims/jvmtiTagMap.cpp Sat Dec 20 00:45:18 2008 -0800 +++ b/src/share/vm/prims/jvmtiTagMap.cpp Tue Jan 06 07:05:05 2009 -0800 @@ -1320,6 +1320,9 @@ } // do the iteration + // If this operation encounters a bad object when using CMS, + // consider using safe_object_iterate() which avoids perm gen + // objects that may contain bad references. Universe::heap()->object_iterate(_blk); // when sharing is enabled we must iterate over the shared spaces diff -r ca7d48236048 -r e9be0e04635a src/share/vm/services/heapDumper.cpp --- a/src/share/vm/services/heapDumper.cpp Sat Dec 20 00:45:18 2008 -0800 +++ b/src/share/vm/services/heapDumper.cpp Tue Jan 06 07:05:05 2009 -0800 @@ -1700,7 +1700,7 @@ // The HPROF_GC_CLASS_DUMP and HPROF_GC_INSTANCE_DUMP are the vast bulk // of the heap dump. HeapObjectDumper obj_dumper(this, writer()); - Universe::heap()->object_iterate(&obj_dumper); + Universe::heap()->safe_object_iterate(&obj_dumper); // HPROF_GC_ROOT_THREAD_OBJ + frames + jni locals do_threads();