6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
Added safe_object_iterate() for use by JMapPerm. Reviewed-by: tonyp
This commit is contained in:
parent
34c4172bfe
commit
3474623106
@ -706,6 +706,30 @@ void CompactibleFreeListSpace::object_iterate(ObjectClosure* blk) {
|
||||
}
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
@ -481,6 +481,15 @@ class CompactibleFreeListSpace: public CompactibleSpace {
|
||||
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.
|
||||
|
@ -3017,6 +3017,16 @@ ConcurrentMarkSweepGeneration::object_iterate(ObjectClosure* cl) {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ void MarkFromRootsClosure::scanOopsInOop(HeapWord* ptr) {
|
||||
_mut->clear_range(mr);
|
||||
}
|
||||
DEBUG_ONLY(})
|
||||
|
||||
// Note: the finger doesn't advance while we drain
|
||||
// the stack below.
|
||||
PushOrMarkClosure pushOrMarkClosure(_collector,
|
||||
|
@ -1212,6 +1212,7 @@ class ConcurrentMarkSweepGeneration: public CardGeneration {
|
||||
// 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
|
||||
|
@ -850,6 +850,7 @@ public:
|
||||
|
||||
// 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
|
||||
|
@ -200,6 +200,7 @@ class ParallelScavengeHeap : public CollectedHeap {
|
||||
|
||||
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);
|
||||
|
||||
|
@ -466,6 +466,10 @@ class CollectedHeap : public CHeapObj {
|
||||
// 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.
|
||||
|
@ -910,6 +910,13 @@ void GenCollectedHeap::object_iterate(ObjectClosure* cl) {
|
||||
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);
|
||||
|
@ -215,6 +215,7 @@ public:
|
||||
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;
|
||||
|
||||
|
@ -319,6 +319,21 @@ void Generation::object_iterate(ObjectClosure* cl) {
|
||||
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();
|
||||
|
@ -518,6 +518,11 @@ class Generation: public CHeapObj {
|
||||
// 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
|
||||
|
@ -263,6 +263,9 @@ void HeapInspection::heap_inspection(outputStream* st) {
|
||||
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 @@ void HeapInspection::find_instances_at_safepoint(klassOop k, GrowableArray<oop>*
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
@ -705,6 +705,12 @@ void ContiguousSpace::object_iterate(ObjectClosure* blk) {
|
||||
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();
|
||||
|
@ -193,6 +193,9 @@ class Space: public CHeapObj {
|
||||
// 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 @@ class ContiguousSpace: public CompactibleSpace {
|
||||
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);
|
||||
|
@ -1320,6 +1320,9 @@ class VM_HeapIterateOperation: public VM_Operation {
|
||||
}
|
||||
|
||||
// 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
|
||||
|
@ -1700,7 +1700,7 @@ void VM_HeapDumper::doit() {
|
||||
// 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();
|
||||
|
Loading…
Reference in New Issue
Block a user