Mercurial > hg > graal-compiler
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(); |