Mercurial > hg > graal-jvmci-8
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 |