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() {