1.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Tue Sep 28 09:51:37 2010 -0700 1.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Tue Sep 28 15:56:15 2010 -0700 1.3 @@ -34,9 +34,10 @@ 1.4 int PSScavenge::_tenuring_threshold = 0; 1.5 HeapWord* PSScavenge::_young_generation_boundary = NULL; 1.6 elapsedTimer PSScavenge::_accumulated_time; 1.7 -GrowableArray<markOop>* PSScavenge::_preserved_mark_stack = NULL; 1.8 -GrowableArray<oop>* PSScavenge::_preserved_oop_stack = NULL; 1.9 +Stack<markOop> PSScavenge::_preserved_mark_stack; 1.10 +Stack<oop> PSScavenge::_preserved_oop_stack; 1.11 CollectorCounters* PSScavenge::_counters = NULL; 1.12 +bool PSScavenge::_promotion_failed = false; 1.13 1.14 // Define before use 1.15 class PSIsAliveClosure: public BoolObjectClosure { 1.16 @@ -223,6 +224,9 @@ 1.17 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); 1.18 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); 1.19 1.20 + assert(_preserved_mark_stack.is_empty(), "should be empty"); 1.21 + assert(_preserved_oop_stack.is_empty(), "should be empty"); 1.22 + 1.23 TimeStamp scavenge_entry; 1.24 TimeStamp scavenge_midpoint; 1.25 TimeStamp scavenge_exit; 1.26 @@ -636,24 +640,20 @@ 1.27 young_gen->object_iterate(&unforward_closure); 1.28 1.29 if (PrintGC && Verbose) { 1.30 - gclog_or_tty->print_cr("Restoring %d marks", 1.31 - _preserved_oop_stack->length()); 1.32 + gclog_or_tty->print_cr("Restoring %d marks", _preserved_oop_stack.size()); 1.33 } 1.34 1.35 // Restore any saved marks. 1.36 - for (int i=0; i < _preserved_oop_stack->length(); i++) { 1.37 - oop obj = _preserved_oop_stack->at(i); 1.38 - markOop mark = _preserved_mark_stack->at(i); 1.39 + while (!_preserved_oop_stack.is_empty()) { 1.40 + oop obj = _preserved_oop_stack.pop(); 1.41 + markOop mark = _preserved_mark_stack.pop(); 1.42 obj->set_mark(mark); 1.43 } 1.44 1.45 - // Deallocate the preserved mark and oop stacks. 1.46 - // The stacks were allocated as CHeap objects, so 1.47 - // we must call delete to prevent mem leaks. 1.48 - delete _preserved_mark_stack; 1.49 - _preserved_mark_stack = NULL; 1.50 - delete _preserved_oop_stack; 1.51 - _preserved_oop_stack = NULL; 1.52 + // Clear the preserved mark and oop stack caches. 1.53 + _preserved_mark_stack.clear(true); 1.54 + _preserved_oop_stack.clear(true); 1.55 + _promotion_failed = false; 1.56 } 1.57 1.58 // Reset the PromotionFailureALot counters. 1.59 @@ -661,27 +661,16 @@ 1.60 } 1.61 1.62 // This method is called whenever an attempt to promote an object 1.63 -// fails. Some markOops will need preserving, some will not. Note 1.64 +// fails. Some markOops will need preservation, some will not. Note 1.65 // that the entire eden is traversed after a failed promotion, with 1.66 // all forwarded headers replaced by the default markOop. This means 1.67 // it is not neccessary to preserve most markOops. 1.68 void PSScavenge::oop_promotion_failed(oop obj, markOop obj_mark) { 1.69 - if (_preserved_mark_stack == NULL) { 1.70 - ThreadCritical tc; // Lock and retest 1.71 - if (_preserved_mark_stack == NULL) { 1.72 - assert(_preserved_oop_stack == NULL, "Sanity"); 1.73 - _preserved_mark_stack = new (ResourceObj::C_HEAP) GrowableArray<markOop>(40, true); 1.74 - _preserved_oop_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(40, true); 1.75 - } 1.76 - } 1.77 - 1.78 - // Because we must hold the ThreadCritical lock before using 1.79 - // the stacks, we should be safe from observing partial allocations, 1.80 - // which are also guarded by the ThreadCritical lock. 1.81 + _promotion_failed = true; 1.82 if (obj_mark->must_be_preserved_for_promotion_failure(obj)) { 1.83 ThreadCritical tc; 1.84 - _preserved_oop_stack->push(obj); 1.85 - _preserved_mark_stack->push(obj_mark); 1.86 + _preserved_oop_stack.push(obj); 1.87 + _preserved_mark_stack.push(obj_mark); 1.88 } 1.89 } 1.90