comparison 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
comparison
equal deleted inserted replaced
1835:4805b9f4779e 1836:894b1d7c7e01
32 CardTableExtension* PSScavenge::_card_table = NULL; 32 CardTableExtension* PSScavenge::_card_table = NULL;
33 bool PSScavenge::_survivor_overflow = false; 33 bool PSScavenge::_survivor_overflow = false;
34 int PSScavenge::_tenuring_threshold = 0; 34 int PSScavenge::_tenuring_threshold = 0;
35 HeapWord* PSScavenge::_young_generation_boundary = NULL; 35 HeapWord* PSScavenge::_young_generation_boundary = NULL;
36 elapsedTimer PSScavenge::_accumulated_time; 36 elapsedTimer PSScavenge::_accumulated_time;
37 GrowableArray<markOop>* PSScavenge::_preserved_mark_stack = NULL; 37 Stack<markOop> PSScavenge::_preserved_mark_stack;
38 GrowableArray<oop>* PSScavenge::_preserved_oop_stack = NULL; 38 Stack<oop> PSScavenge::_preserved_oop_stack;
39 CollectorCounters* PSScavenge::_counters = NULL; 39 CollectorCounters* PSScavenge::_counters = NULL;
40 bool PSScavenge::_promotion_failed = false;
40 41
41 // Define before use 42 // Define before use
42 class PSIsAliveClosure: public BoolObjectClosure { 43 class PSIsAliveClosure: public BoolObjectClosure {
43 public: 44 public:
44 void do_object(oop p) { 45 void do_object(oop p) {
220 // This method contains no policy. You should probably 221 // This method contains no policy. You should probably
221 // be calling invoke() instead. 222 // be calling invoke() instead.
222 bool PSScavenge::invoke_no_policy() { 223 bool PSScavenge::invoke_no_policy() {
223 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); 224 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
224 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); 225 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread");
226
227 assert(_preserved_mark_stack.is_empty(), "should be empty");
228 assert(_preserved_oop_stack.is_empty(), "should be empty");
225 229
226 TimeStamp scavenge_entry; 230 TimeStamp scavenge_entry;
227 TimeStamp scavenge_midpoint; 231 TimeStamp scavenge_midpoint;
228 TimeStamp scavenge_exit; 232 TimeStamp scavenge_exit;
229 233
634 // Unforward all pointers in the young gen. 638 // Unforward all pointers in the young gen.
635 PSPromotionFailedClosure unforward_closure; 639 PSPromotionFailedClosure unforward_closure;
636 young_gen->object_iterate(&unforward_closure); 640 young_gen->object_iterate(&unforward_closure);
637 641
638 if (PrintGC && Verbose) { 642 if (PrintGC && Verbose) {
639 gclog_or_tty->print_cr("Restoring %d marks", 643 gclog_or_tty->print_cr("Restoring %d marks", _preserved_oop_stack.size());
640 _preserved_oop_stack->length());
641 } 644 }
642 645
643 // Restore any saved marks. 646 // Restore any saved marks.
644 for (int i=0; i < _preserved_oop_stack->length(); i++) { 647 while (!_preserved_oop_stack.is_empty()) {
645 oop obj = _preserved_oop_stack->at(i); 648 oop obj = _preserved_oop_stack.pop();
646 markOop mark = _preserved_mark_stack->at(i); 649 markOop mark = _preserved_mark_stack.pop();
647 obj->set_mark(mark); 650 obj->set_mark(mark);
648 } 651 }
649 652
650 // Deallocate the preserved mark and oop stacks. 653 // Clear the preserved mark and oop stack caches.
651 // The stacks were allocated as CHeap objects, so 654 _preserved_mark_stack.clear(true);
652 // we must call delete to prevent mem leaks. 655 _preserved_oop_stack.clear(true);
653 delete _preserved_mark_stack; 656 _promotion_failed = false;
654 _preserved_mark_stack = NULL;
655 delete _preserved_oop_stack;
656 _preserved_oop_stack = NULL;
657 } 657 }
658 658
659 // Reset the PromotionFailureALot counters. 659 // Reset the PromotionFailureALot counters.
660 NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();) 660 NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();)
661 } 661 }
662 662
663 // This method is called whenever an attempt to promote an object 663 // This method is called whenever an attempt to promote an object
664 // fails. Some markOops will need preserving, some will not. Note 664 // fails. Some markOops will need preservation, some will not. Note
665 // that the entire eden is traversed after a failed promotion, with 665 // that the entire eden is traversed after a failed promotion, with
666 // all forwarded headers replaced by the default markOop. This means 666 // all forwarded headers replaced by the default markOop. This means
667 // it is not neccessary to preserve most markOops. 667 // it is not neccessary to preserve most markOops.
668 void PSScavenge::oop_promotion_failed(oop obj, markOop obj_mark) { 668 void PSScavenge::oop_promotion_failed(oop obj, markOop obj_mark) {
669 if (_preserved_mark_stack == NULL) { 669 _promotion_failed = true;
670 ThreadCritical tc; // Lock and retest
671 if (_preserved_mark_stack == NULL) {
672 assert(_preserved_oop_stack == NULL, "Sanity");
673 _preserved_mark_stack = new (ResourceObj::C_HEAP) GrowableArray<markOop>(40, true);
674 _preserved_oop_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(40, true);
675 }
676 }
677
678 // Because we must hold the ThreadCritical lock before using
679 // the stacks, we should be safe from observing partial allocations,
680 // which are also guarded by the ThreadCritical lock.
681 if (obj_mark->must_be_preserved_for_promotion_failure(obj)) { 670 if (obj_mark->must_be_preserved_for_promotion_failure(obj)) {
682 ThreadCritical tc; 671 ThreadCritical tc;
683 _preserved_oop_stack->push(obj); 672 _preserved_oop_stack.push(obj);
684 _preserved_mark_stack->push(obj_mark); 673 _preserved_mark_stack.push(obj_mark);
685 } 674 }
686 } 675 }
687 676
688 bool PSScavenge::should_attempt_scavenge() { 677 bool PSScavenge::should_attempt_scavenge() {
689 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); 678 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();