comparison src/share/vm/gc_implementation/g1/heapRegion.cpp @ 1020:ff2402f6a50b

6882730: G1: parallel heap verification messes up region dump Summary: It tidies up the G1 heap verification a bit. In particular, when the verification is done in parallel and there is a failure, this is propagated to the top level and the heap is dumped at the end, not by every thread that encounters a failure. Reviewed-by: johnc, jmasa
author tonyp
date Fri, 02 Oct 2009 16:20:42 -0400
parents 2c79770d1f6e
children 7666957bc44d
comparison
equal deleted inserted replaced
1019:035d2e036a9b 1020:ff2402f6a50b
720 st->print(" "); 720 st->print(" ");
721 if (is_empty()) 721 if (is_empty())
722 st->print(" F"); 722 st->print(" F");
723 else 723 else
724 st->print(" "); 724 st->print(" ");
725 st->print(" %d", _gc_time_stamp); 725 st->print(" %5d", _gc_time_stamp);
726 G1OffsetTableContigSpace::print_on(st); 726 G1OffsetTableContigSpace::print_on(st);
727 } 727 }
728 728
729 void HeapRegion::verify(bool allow_dirty) const { 729 void HeapRegion::verify(bool allow_dirty) const {
730 verify(allow_dirty, /* use_prev_marking */ true); 730 bool dummy = false;
731 verify(allow_dirty, /* use_prev_marking */ true, /* failures */ &dummy);
731 } 732 }
732 733
733 #define OBJ_SAMPLE_INTERVAL 0 734 #define OBJ_SAMPLE_INTERVAL 0
734 #define BLOCK_SAMPLE_INTERVAL 100 735 #define BLOCK_SAMPLE_INTERVAL 100
735 736
736 // This really ought to be commoned up into OffsetTableContigSpace somehow. 737 // This really ought to be commoned up into OffsetTableContigSpace somehow.
737 // We would need a mechanism to make that code skip dead objects. 738 // We would need a mechanism to make that code skip dead objects.
738 739
739 void HeapRegion::verify(bool allow_dirty, bool use_prev_marking) const { 740 void HeapRegion::verify(bool allow_dirty,
741 bool use_prev_marking,
742 bool* failures) const {
740 G1CollectedHeap* g1 = G1CollectedHeap::heap(); 743 G1CollectedHeap* g1 = G1CollectedHeap::heap();
744 *failures = false;
741 HeapWord* p = bottom(); 745 HeapWord* p = bottom();
742 HeapWord* prev_p = NULL; 746 HeapWord* prev_p = NULL;
743 int objs = 0; 747 int objs = 0;
744 int blocks = 0; 748 int blocks = 0;
745 VerifyLiveClosure vl_cl(g1, use_prev_marking); 749 VerifyLiveClosure vl_cl(g1, use_prev_marking);
746 while (p < top()) { 750 while (p < top()) {
747 size_t size = oop(p)->size(); 751 size_t size = oop(p)->size();
748 if (blocks == BLOCK_SAMPLE_INTERVAL) { 752 if (blocks == BLOCK_SAMPLE_INTERVAL) {
749 guarantee(p == block_start_const(p + (size/2)), 753 HeapWord* res = block_start_const(p + (size/2));
750 "check offset computation"); 754 if (p != res) {
755 gclog_or_tty->print_cr("offset computation 1 for "PTR_FORMAT" and "
756 SIZE_FORMAT" returned "PTR_FORMAT,
757 p, size, res);
758 *failures = true;
759 return;
760 }
751 blocks = 0; 761 blocks = 0;
752 } else { 762 } else {
753 blocks++; 763 blocks++;
754 } 764 }
755 if (objs == OBJ_SAMPLE_INTERVAL) { 765 if (objs == OBJ_SAMPLE_INTERVAL) {
756 oop obj = oop(p); 766 oop obj = oop(p);
757 if (!g1->is_obj_dead_cond(obj, this, use_prev_marking)) { 767 if (!g1->is_obj_dead_cond(obj, this, use_prev_marking)) {
758 obj->verify(); 768 if (obj->is_oop()) {
759 vl_cl.set_containing_obj(obj); 769 klassOop klass = obj->klass();
760 obj->oop_iterate(&vl_cl); 770 if (!klass->is_perm()) {
761 if (G1MaxVerifyFailures >= 0 771 gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" "
762 && vl_cl.n_failures() >= G1MaxVerifyFailures) break; 772 "not in perm", klass, obj);
773 *failures = true;
774 return;
775 } else if (!klass->is_klass()) {
776 gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" "
777 "not a klass", klass, obj);
778 *failures = true;
779 return;
780 } else {
781 vl_cl.set_containing_obj(obj);
782 obj->oop_iterate(&vl_cl);
783 if (vl_cl.failures()) {
784 *failures = true;
785 }
786 if (G1MaxVerifyFailures >= 0 &&
787 vl_cl.n_failures() >= G1MaxVerifyFailures) {
788 return;
789 }
790 }
791 } else {
792 gclog_or_tty->print_cr(PTR_FORMAT" no an oop", obj);
793 *failures = true;
794 return;
795 }
763 } 796 }
764 objs = 0; 797 objs = 0;
765 } else { 798 } else {
766 objs++; 799 objs++;
767 } 800 }
769 p += size; 802 p += size;
770 } 803 }
771 HeapWord* rend = end(); 804 HeapWord* rend = end();
772 HeapWord* rtop = top(); 805 HeapWord* rtop = top();
773 if (rtop < rend) { 806 if (rtop < rend) {
774 guarantee(block_start_const(rtop + (rend - rtop) / 2) == rtop, 807 HeapWord* res = block_start_const(rtop + (rend - rtop) / 2);
775 "check offset computation"); 808 if (res != rtop) {
776 } 809 gclog_or_tty->print_cr("offset computation 2 for "PTR_FORMAT" and "
777 if (vl_cl.failures()) { 810 PTR_FORMAT" returned "PTR_FORMAT,
778 gclog_or_tty->print_cr("Heap:"); 811 rtop, rend, res);
779 G1CollectedHeap::heap()->print_on(gclog_or_tty, true /* extended */); 812 *failures = true;
780 gclog_or_tty->print_cr(""); 813 return;
781 } 814 }
782 if (VerifyDuringGC && 815 }
783 G1VerifyConcMarkPrintReachable && 816
784 vl_cl.failures()) { 817 if (p != top()) {
785 g1->concurrent_mark()->print_prev_bitmap_reachable(); 818 gclog_or_tty->print_cr("end of last object "PTR_FORMAT" "
786 } 819 "does not match top "PTR_FORMAT, p, top());
787 guarantee(!vl_cl.failures(), "region verification failed"); 820 *failures = true;
788 guarantee(p == top(), "end of last object must match end of space"); 821 return;
822 }
789 } 823 }
790 824
791 // G1OffsetTableContigSpace code; copied from space.cpp. Hope this can go 825 // G1OffsetTableContigSpace code; copied from space.cpp. Hope this can go
792 // away eventually. 826 // away eventually.
793 827