Mercurial > hg > truffle
diff src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp @ 1836:894b1d7c7e01
6423256: GC stacks should use a better data structure
6942771: SEGV in ParScanThreadState::take_from_overflow_stack
Reviewed-by: apetrusenko, ysr, pbk
author | jcoomes |
---|---|
date | Tue, 28 Sep 2010 15:56:15 -0700 |
parents | 9d7a8ab3736b |
children | f95d63e2154a |
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Tue Sep 28 09:51:37 2010 -0700 +++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Tue Sep 28 15:56:15 2010 -0700 @@ -34,9 +34,10 @@ int PSScavenge::_tenuring_threshold = 0; HeapWord* PSScavenge::_young_generation_boundary = NULL; elapsedTimer PSScavenge::_accumulated_time; -GrowableArray<markOop>* PSScavenge::_preserved_mark_stack = NULL; -GrowableArray<oop>* PSScavenge::_preserved_oop_stack = NULL; +Stack<markOop> PSScavenge::_preserved_mark_stack; +Stack<oop> PSScavenge::_preserved_oop_stack; CollectorCounters* PSScavenge::_counters = NULL; +bool PSScavenge::_promotion_failed = false; // Define before use class PSIsAliveClosure: public BoolObjectClosure { @@ -223,6 +224,9 @@ assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); + assert(_preserved_mark_stack.is_empty(), "should be empty"); + assert(_preserved_oop_stack.is_empty(), "should be empty"); + TimeStamp scavenge_entry; TimeStamp scavenge_midpoint; TimeStamp scavenge_exit; @@ -636,24 +640,20 @@ young_gen->object_iterate(&unforward_closure); if (PrintGC && Verbose) { - gclog_or_tty->print_cr("Restoring %d marks", - _preserved_oop_stack->length()); + gclog_or_tty->print_cr("Restoring %d marks", _preserved_oop_stack.size()); } // Restore any saved marks. - for (int i=0; i < _preserved_oop_stack->length(); i++) { - oop obj = _preserved_oop_stack->at(i); - markOop mark = _preserved_mark_stack->at(i); + while (!_preserved_oop_stack.is_empty()) { + oop obj = _preserved_oop_stack.pop(); + markOop mark = _preserved_mark_stack.pop(); obj->set_mark(mark); } - // Deallocate the preserved mark and oop stacks. - // The stacks were allocated as CHeap objects, so - // we must call delete to prevent mem leaks. - delete _preserved_mark_stack; - _preserved_mark_stack = NULL; - delete _preserved_oop_stack; - _preserved_oop_stack = NULL; + // Clear the preserved mark and oop stack caches. + _preserved_mark_stack.clear(true); + _preserved_oop_stack.clear(true); + _promotion_failed = false; } // Reset the PromotionFailureALot counters. @@ -661,27 +661,16 @@ } // This method is called whenever an attempt to promote an object -// fails. Some markOops will need preserving, some will not. Note +// fails. Some markOops will need preservation, some will not. Note // that the entire eden is traversed after a failed promotion, with // all forwarded headers replaced by the default markOop. This means // it is not neccessary to preserve most markOops. void PSScavenge::oop_promotion_failed(oop obj, markOop obj_mark) { - if (_preserved_mark_stack == NULL) { - ThreadCritical tc; // Lock and retest - if (_preserved_mark_stack == NULL) { - assert(_preserved_oop_stack == NULL, "Sanity"); - _preserved_mark_stack = new (ResourceObj::C_HEAP) GrowableArray<markOop>(40, true); - _preserved_oop_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(40, true); - } - } - - // Because we must hold the ThreadCritical lock before using - // the stacks, we should be safe from observing partial allocations, - // which are also guarded by the ThreadCritical lock. + _promotion_failed = true; if (obj_mark->must_be_preserved_for_promotion_failure(obj)) { ThreadCritical tc; - _preserved_oop_stack->push(obj); - _preserved_mark_stack->push(obj_mark); + _preserved_oop_stack.push(obj); + _preserved_mark_stack.push(obj_mark); } }