Mercurial > hg > graal-compiler
comparison src/share/vm/memory/defNewGeneration.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 | c18cbe5936b8 |
children | a7214d79fcf1 |
comparison
equal
deleted
inserted
replaced
1835:4805b9f4779e | 1836:894b1d7c7e01 |
---|---|
85 void DefNewGeneration::FastEvacuateFollowersClosure::do_void() { | 85 void DefNewGeneration::FastEvacuateFollowersClosure::do_void() { |
86 do { | 86 do { |
87 _gch->oop_since_save_marks_iterate(_level, _scan_cur_or_nonheap, | 87 _gch->oop_since_save_marks_iterate(_level, _scan_cur_or_nonheap, |
88 _scan_older); | 88 _scan_older); |
89 } while (!_gch->no_allocs_since_save_marks(_level)); | 89 } while (!_gch->no_allocs_since_save_marks(_level)); |
90 guarantee(_gen->promo_failure_scan_stack() == NULL | 90 guarantee(_gen->promo_failure_scan_is_complete(), "Failed to finish scan"); |
91 || _gen->promo_failure_scan_stack()->length() == 0, | |
92 "Failed to finish scan"); | |
93 } | 91 } |
94 | 92 |
95 ScanClosure::ScanClosure(DefNewGeneration* g, bool gc_barrier) : | 93 ScanClosure::ScanClosure(DefNewGeneration* g, bool gc_barrier) : |
96 OopsInGenClosure(g), _g(g), _gc_barrier(gc_barrier) | 94 OopsInGenClosure(g), _g(g), _gc_barrier(gc_barrier) |
97 { | 95 { |
128 DefNewGeneration::DefNewGeneration(ReservedSpace rs, | 126 DefNewGeneration::DefNewGeneration(ReservedSpace rs, |
129 size_t initial_size, | 127 size_t initial_size, |
130 int level, | 128 int level, |
131 const char* policy) | 129 const char* policy) |
132 : Generation(rs, initial_size, level), | 130 : Generation(rs, initial_size, level), |
133 _objs_with_preserved_marks(NULL), | |
134 _preserved_marks_of_objs(NULL), | |
135 _promo_failure_scan_stack(NULL), | |
136 _promo_failure_drain_in_progress(false), | 131 _promo_failure_drain_in_progress(false), |
137 _should_allocate_from_space(false) | 132 _should_allocate_from_space(false) |
138 { | 133 { |
139 MemRegion cmr((HeapWord*)_virtual_space.low(), | 134 MemRegion cmr((HeapWord*)_virtual_space.low(), |
140 (HeapWord*)_virtual_space.high()); | 135 (HeapWord*)_virtual_space.high()); |
602 gch->print_heap_change(gch_prev_used); | 597 gch->print_heap_change(gch_prev_used); |
603 } | 598 } |
604 } else { | 599 } else { |
605 assert(HandlePromotionFailure, | 600 assert(HandlePromotionFailure, |
606 "Should not be here unless promotion failure handling is on"); | 601 "Should not be here unless promotion failure handling is on"); |
607 assert(_promo_failure_scan_stack != NULL && | 602 assert(_promo_failure_scan_stack.is_empty(), "post condition"); |
608 _promo_failure_scan_stack->length() == 0, "post condition"); | 603 _promo_failure_scan_stack.clear(true); // Clear cached segments. |
609 | |
610 // deallocate stack and it's elements | |
611 delete _promo_failure_scan_stack; | |
612 _promo_failure_scan_stack = NULL; | |
613 | 604 |
614 remove_forwarding_pointers(); | 605 remove_forwarding_pointers(); |
615 if (PrintGCDetails) { | 606 if (PrintGCDetails) { |
616 gclog_or_tty->print(" (promotion failed) "); | 607 gclog_or_tty->print(" (promotion failed) "); |
617 } | 608 } |
618 // Add to-space to the list of space to compact | 609 // Add to-space to the list of space to compact |
619 // when a promotion failure has occurred. In that | 610 // when a promotion failure has occurred. In that |
620 // case there can be live objects in to-space | 611 // case there can be live objects in to-space |
621 // as a result of a partial evacuation of eden | 612 // as a result of a partial evacuation of eden |
622 // and from-space. | 613 // and from-space. |
623 swap_spaces(); // For the sake of uniformity wrt ParNewGeneration::collect(). | 614 swap_spaces(); // For uniformity wrt ParNewGeneration. |
624 from()->set_next_compaction_space(to()); | 615 from()->set_next_compaction_space(to()); |
625 gch->set_incremental_collection_will_fail(); | 616 gch->set_incremental_collection_will_fail(); |
626 | 617 |
627 // Inform the next generation that a promotion failure occurred. | 618 // Inform the next generation that a promotion failure occurred. |
628 _next_gen->promotion_failure_occurred(); | 619 _next_gen->promotion_failure_occurred(); |
651 | 642 |
652 void DefNewGeneration::remove_forwarding_pointers() { | 643 void DefNewGeneration::remove_forwarding_pointers() { |
653 RemoveForwardPointerClosure rspc; | 644 RemoveForwardPointerClosure rspc; |
654 eden()->object_iterate(&rspc); | 645 eden()->object_iterate(&rspc); |
655 from()->object_iterate(&rspc); | 646 from()->object_iterate(&rspc); |
647 | |
656 // Now restore saved marks, if any. | 648 // Now restore saved marks, if any. |
657 if (_objs_with_preserved_marks != NULL) { | 649 assert(_objs_with_preserved_marks.size() == _preserved_marks_of_objs.size(), |
658 assert(_preserved_marks_of_objs != NULL, "Both or none."); | 650 "should be the same"); |
659 assert(_objs_with_preserved_marks->length() == | 651 while (!_objs_with_preserved_marks.is_empty()) { |
660 _preserved_marks_of_objs->length(), "Both or none."); | 652 oop obj = _objs_with_preserved_marks.pop(); |
661 for (int i = 0; i < _objs_with_preserved_marks->length(); i++) { | 653 markOop m = _preserved_marks_of_objs.pop(); |
662 oop obj = _objs_with_preserved_marks->at(i); | 654 obj->set_mark(m); |
663 markOop m = _preserved_marks_of_objs->at(i); | 655 } |
664 obj->set_mark(m); | 656 _objs_with_preserved_marks.clear(true); |
665 } | 657 _preserved_marks_of_objs.clear(true); |
666 delete _objs_with_preserved_marks; | |
667 delete _preserved_marks_of_objs; | |
668 _objs_with_preserved_marks = NULL; | |
669 _preserved_marks_of_objs = NULL; | |
670 } | |
671 } | 658 } |
672 | 659 |
673 void DefNewGeneration::preserve_mark_if_necessary(oop obj, markOop m) { | 660 void DefNewGeneration::preserve_mark_if_necessary(oop obj, markOop m) { |
674 if (m->must_be_preserved_for_promotion_failure(obj)) { | 661 if (m->must_be_preserved_for_promotion_failure(obj)) { |
675 if (_objs_with_preserved_marks == NULL) { | 662 _objs_with_preserved_marks.push(obj); |
676 assert(_preserved_marks_of_objs == NULL, "Both or none."); | 663 _preserved_marks_of_objs.push(m); |
677 _objs_with_preserved_marks = new (ResourceObj::C_HEAP) | |
678 GrowableArray<oop>(PreserveMarkStackSize, true); | |
679 _preserved_marks_of_objs = new (ResourceObj::C_HEAP) | |
680 GrowableArray<markOop>(PreserveMarkStackSize, true); | |
681 } | |
682 _objs_with_preserved_marks->push(obj); | |
683 _preserved_marks_of_objs->push(m); | |
684 } | 664 } |
685 } | 665 } |
686 | 666 |
687 void DefNewGeneration::handle_promotion_failure(oop old) { | 667 void DefNewGeneration::handle_promotion_failure(oop old) { |
688 preserve_mark_if_necessary(old, old->mark()); | 668 preserve_mark_if_necessary(old, old->mark()); |
693 | 673 |
694 // forward to self | 674 // forward to self |
695 old->forward_to(old); | 675 old->forward_to(old); |
696 _promotion_failed = true; | 676 _promotion_failed = true; |
697 | 677 |
698 push_on_promo_failure_scan_stack(old); | 678 _promo_failure_scan_stack.push(old); |
699 | 679 |
700 if (!_promo_failure_drain_in_progress) { | 680 if (!_promo_failure_drain_in_progress) { |
701 // prevent recursion in copy_to_survivor_space() | 681 // prevent recursion in copy_to_survivor_space() |
702 _promo_failure_drain_in_progress = true; | 682 _promo_failure_drain_in_progress = true; |
703 drain_promo_failure_scan_stack(); | 683 drain_promo_failure_scan_stack(); |
746 old->forward_to(obj); | 726 old->forward_to(obj); |
747 | 727 |
748 return obj; | 728 return obj; |
749 } | 729 } |
750 | 730 |
751 void DefNewGeneration::push_on_promo_failure_scan_stack(oop obj) { | |
752 if (_promo_failure_scan_stack == NULL) { | |
753 _promo_failure_scan_stack = new (ResourceObj::C_HEAP) | |
754 GrowableArray<oop>(40, true); | |
755 } | |
756 | |
757 _promo_failure_scan_stack->push(obj); | |
758 } | |
759 | |
760 void DefNewGeneration::drain_promo_failure_scan_stack() { | 731 void DefNewGeneration::drain_promo_failure_scan_stack() { |
761 assert(_promo_failure_scan_stack != NULL, "precondition"); | 732 while (!_promo_failure_scan_stack.is_empty()) { |
762 | 733 oop obj = _promo_failure_scan_stack.pop(); |
763 while (_promo_failure_scan_stack->length() > 0) { | |
764 oop obj = _promo_failure_scan_stack->pop(); | |
765 obj->oop_iterate(_promo_failure_scan_stack_closure); | 734 obj->oop_iterate(_promo_failure_scan_stack_closure); |
766 } | 735 } |
767 } | 736 } |
768 | 737 |
769 void DefNewGeneration::save_marks() { | 738 void DefNewGeneration::save_marks() { |