comparison src/share/vm/gc_implementation/g1/heapRegion.cpp @ 3772:6747fd0512e0

7004681: G1: Extend marking verification to Full GCs Summary: Perform a heap verification after the first phase of G1's full GC using objects' mark words to determine liveness. The third parameter of the heap verification routines, which was used in G1 to determine which marking bitmap to use in liveness calculations, has been changed from a boolean to an enum with values defined for using the mark word, and the 'prev' and 'next' bitmaps. Reviewed-by: tonyp, ysr
author johnc
date Tue, 14 Jun 2011 11:01:10 -0700
parents c3f1170908be
children f44782f04dd4
comparison
equal deleted inserted replaced
3771:842b840e67db 3772:6747fd0512e0
58 G1CollectedHeap* _g1h; 58 G1CollectedHeap* _g1h;
59 CardTableModRefBS* _bs; 59 CardTableModRefBS* _bs;
60 oop _containing_obj; 60 oop _containing_obj;
61 bool _failures; 61 bool _failures;
62 int _n_failures; 62 int _n_failures;
63 bool _use_prev_marking; 63 VerifyOption _vo;
64 public: 64 public:
65 // use_prev_marking == true -> use "prev" marking information, 65 // _vo == UsePrevMarking -> use "prev" marking information,
66 // use_prev_marking == false -> use "next" marking information 66 // _vo == UseNextMarking -> use "next" marking information,
67 VerifyLiveClosure(G1CollectedHeap* g1h, bool use_prev_marking) : 67 // _vo == UseMarkWord -> use mark word from object header.
68 VerifyLiveClosure(G1CollectedHeap* g1h, VerifyOption vo) :
68 _g1h(g1h), _bs(NULL), _containing_obj(NULL), 69 _g1h(g1h), _bs(NULL), _containing_obj(NULL),
69 _failures(false), _n_failures(0), _use_prev_marking(use_prev_marking) 70 _failures(false), _n_failures(0), _vo(vo)
70 { 71 {
71 BarrierSet* bs = _g1h->barrier_set(); 72 BarrierSet* bs = _g1h->barrier_set();
72 if (bs->is_a(BarrierSet::CardTableModRef)) 73 if (bs->is_a(BarrierSet::CardTableModRef))
73 _bs = (CardTableModRefBS*)bs; 74 _bs = (CardTableModRefBS*)bs;
74 } 75 }
93 #endif // PRODUCT 94 #endif // PRODUCT
94 } 95 }
95 96
96 template <class T> void do_oop_work(T* p) { 97 template <class T> void do_oop_work(T* p) {
97 assert(_containing_obj != NULL, "Precondition"); 98 assert(_containing_obj != NULL, "Precondition");
98 assert(!_g1h->is_obj_dead_cond(_containing_obj, _use_prev_marking), 99 assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo),
99 "Precondition"); 100 "Precondition");
100 T heap_oop = oopDesc::load_heap_oop(p); 101 T heap_oop = oopDesc::load_heap_oop(p);
101 if (!oopDesc::is_null(heap_oop)) { 102 if (!oopDesc::is_null(heap_oop)) {
102 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); 103 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
103 bool failed = false; 104 bool failed = false;
104 if (!_g1h->is_in_closed_subset(obj) || 105 if (!_g1h->is_in_closed_subset(obj) ||
105 _g1h->is_obj_dead_cond(obj, _use_prev_marking)) { 106 _g1h->is_obj_dead_cond(obj, _vo)) {
106 if (!_failures) { 107 if (!_failures) {
107 gclog_or_tty->print_cr(""); 108 gclog_or_tty->print_cr("");
108 gclog_or_tty->print_cr("----------"); 109 gclog_or_tty->print_cr("----------");
109 } 110 }
110 if (!_g1h->is_in_closed_subset(obj)) { 111 if (!_g1h->is_in_closed_subset(obj)) {
733 G1OffsetTableContigSpace::print_on(st); 734 G1OffsetTableContigSpace::print_on(st);
734 } 735 }
735 736
736 void HeapRegion::verify(bool allow_dirty) const { 737 void HeapRegion::verify(bool allow_dirty) const {
737 bool dummy = false; 738 bool dummy = false;
738 verify(allow_dirty, /* use_prev_marking */ true, /* failures */ &dummy); 739 verify(allow_dirty, VerifyOption_G1UsePrevMarking, /* failures */ &dummy);
739 } 740 }
740 741
741 // This really ought to be commoned up into OffsetTableContigSpace somehow. 742 // This really ought to be commoned up into OffsetTableContigSpace somehow.
742 // We would need a mechanism to make that code skip dead objects. 743 // We would need a mechanism to make that code skip dead objects.
743 744
744 void HeapRegion::verify(bool allow_dirty, 745 void HeapRegion::verify(bool allow_dirty,
745 bool use_prev_marking, 746 VerifyOption vo,
746 bool* failures) const { 747 bool* failures) const {
747 G1CollectedHeap* g1 = G1CollectedHeap::heap(); 748 G1CollectedHeap* g1 = G1CollectedHeap::heap();
748 *failures = false; 749 *failures = false;
749 HeapWord* p = bottom(); 750 HeapWord* p = bottom();
750 HeapWord* prev_p = NULL; 751 HeapWord* prev_p = NULL;
751 VerifyLiveClosure vl_cl(g1, use_prev_marking); 752 VerifyLiveClosure vl_cl(g1, vo);
752 bool is_humongous = isHumongous(); 753 bool is_humongous = isHumongous();
753 bool do_bot_verify = !is_young(); 754 bool do_bot_verify = !is_young();
754 size_t object_num = 0; 755 size_t object_num = 0;
755 while (p < top()) { 756 while (p < top()) {
756 oop obj = oop(p); 757 oop obj = oop(p);
771 if (do_bot_verify && !_offsets.verify_for_object(p, obj_size)) { 772 if (do_bot_verify && !_offsets.verify_for_object(p, obj_size)) {
772 *failures = true; 773 *failures = true;
773 return; 774 return;
774 } 775 }
775 776
776 if (!g1->is_obj_dead_cond(obj, this, use_prev_marking)) { 777 if (!g1->is_obj_dead_cond(obj, this, vo)) {
777 if (obj->is_oop()) { 778 if (obj->is_oop()) {
778 klassOop klass = obj->klass(); 779 klassOop klass = obj->klass();
779 if (!klass->is_perm()) { 780 if (!klass->is_perm()) {
780 gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" " 781 gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" "
781 "not in perm", klass, obj); 782 "not in perm", klass, obj);