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