@@ -462,17 +462,31 @@ static bool is_oop_safe(oop obj) {
462462 return true ;
463463}
464464
465+ class G1VerifyFailureCounter {
466+ size_t _count;
467+
468+ public:
469+ G1VerifyFailureCounter () : _count(0 ) {}
470+
471+ // Increases the failure counter and return whether this has been the first failure.
472+ bool record_failure () {
473+ _count++;
474+ return _count == 1 ;
475+ }
476+
477+ size_t count () const { return _count; }
478+ };
479+
465480// Closure that glues together validity check for oop references (first),
466481// then optionally verifies the remembered set for that reference.
467482class G1VerifyLiveAndRemSetClosure : public BasicOopIterateClosure {
468- VerifyOption _vo;
469- oop _containing_obj;
470- size_t _num_failures ;
483+ const VerifyOption _vo;
484+ const oop _containing_obj;
485+ G1VerifyFailureCounter* const _failures ;
471486
472487 // Increases the failure counter and return whether this has been the first failure.
473488 bool record_failure () {
474- _num_failures++;
475- return _num_failures == 1 ;
489+ return _failures->record_failure ();
476490 }
477491
478492 static void print_object (outputStream* out, oop obj) {
@@ -486,18 +500,22 @@ class G1VerifyLiveAndRemSetClosure : public BasicOopIterateClosure {
486500 template <class T >
487501 struct Checker {
488502 G1CollectedHeap* _g1h;
489- G1VerifyLiveAndRemSetClosure* _cl ;
503+ G1VerifyFailureCounter* _failures ;
490504 oop _containing_obj;
491505 T* _p;
492506 oop _obj;
493507
494- Checker (G1VerifyLiveAndRemSetClosure* cl , oop containing_obj, T* p, oop obj) :
508+ Checker (G1VerifyFailureCounter* failures , oop containing_obj, T* p, oop obj) :
495509 _g1h (G1CollectedHeap::heap()),
496- _cl (cl ),
510+ _failures (failures ),
497511 _containing_obj (containing_obj),
498512 _p (p),
499513 _obj (obj) { }
500514
515+ bool record_failure () {
516+ return _failures->record_failure ();
517+ }
518+
501519 void print_containing_obj (outputStream* out, HeapRegion* from) {
502520 log_error (gc, verify)(" Field " PTR_FORMAT " of obj " PTR_FORMAT " in region " HR_FORMAT,
503521 p2i (_p), p2i (_containing_obj), HR_FORMAT_PARAMS (from));
@@ -516,7 +534,8 @@ class G1VerifyLiveAndRemSetClosure : public BasicOopIterateClosure {
516534 VerifyOption _vo;
517535 bool _is_in_heap;
518536
519- LiveChecker (G1VerifyLiveAndRemSetClosure* cl, oop containing_obj, T* p, oop obj, VerifyOption vo) : Checker<T>(cl, containing_obj, p, obj) {
537+ LiveChecker (G1VerifyFailureCounter* failures, oop containing_obj, T* p, oop obj, VerifyOption vo)
538+ : Checker<T>(failures, containing_obj, p, obj) {
520539 _vo = vo;
521540 _is_in_heap = this ->_g1h ->is_in (obj);
522541 }
@@ -532,7 +551,7 @@ class G1VerifyLiveAndRemSetClosure : public BasicOopIterateClosure {
532551
533552 MutexLocker x (G1RareEvent_lock, Mutex::_no_safepoint_check_flag);
534553
535- if (this ->_cl -> record_failure ()) {
554+ if (this ->record_failure ()) {
536555 log.error (" ----------" );
537556 }
538557
@@ -558,7 +577,8 @@ class G1VerifyLiveAndRemSetClosure : public BasicOopIterateClosure {
558577 CardValue _cv_obj;
559578 CardValue _cv_field;
560579
561- RemSetChecker (G1VerifyLiveAndRemSetClosure* cl, oop containing_obj, T* p, oop obj) : Checker<T>(cl, containing_obj, p, obj) {
580+ RemSetChecker (G1VerifyFailureCounter* failures, oop containing_obj, T* p, oop obj)
581+ : Checker<T>(failures, containing_obj, p, obj) {
562582 _from = this ->_g1h ->heap_region_containing (p);
563583 _to = this ->_g1h ->heap_region_containing (obj);
564584
@@ -585,7 +605,7 @@ class G1VerifyLiveAndRemSetClosure : public BasicOopIterateClosure {
585605
586606 MutexLocker x (G1RareEvent_lock, Mutex::_no_safepoint_check_flag);
587607
588- if (this ->_cl -> record_failure ()) {
608+ if (this ->record_failure ()) {
589609 log.error (" ----------" );
590610 }
591611 log.error (" Missing rem set entry:" );
@@ -598,9 +618,7 @@ class G1VerifyLiveAndRemSetClosure : public BasicOopIterateClosure {
598618
599619 template <class T >
600620 void do_oop_work (T* p) {
601- assert (_containing_obj != nullptr , " must be" );
602-
603- if (num_failures () >= G1MaxVerifyFailures) {
621+ if (_failures->count () >= G1MaxVerifyFailures) {
604622 return ;
605623 }
606624
@@ -610,31 +628,24 @@ class G1VerifyLiveAndRemSetClosure : public BasicOopIterateClosure {
610628 }
611629 oop obj = CompressedOops::decode_raw_not_null (heap_oop);
612630
613- LiveChecker<T> live_check (this , _containing_obj, p, obj, _vo);
631+ LiveChecker<T> live_check (_failures , _containing_obj, p, obj, _vo);
614632 if (live_check.failed ()) {
615633 live_check.report_error ();
616634 // There is no point in doing remset verification if the reference is bad.
617635 return ;
618636 }
619637
620- RemSetChecker<T> remset_check (this , _containing_obj, p, obj);
638+ RemSetChecker<T> remset_check (_failures , _containing_obj, p, obj);
621639 if (remset_check.failed ()) {
622640 remset_check.report_error ();
623641 }
624642 }
625643
626644public:
627- G1VerifyLiveAndRemSetClosure (G1CollectedHeap* g1h, VerifyOption vo) :
628- _vo (vo),
629- _containing_obj (nullptr ),
630- _num_failures (0 ) { }
631-
632- void set_containing_obj (oop const obj) {
633- assert (!G1CollectedHeap::heap ()->is_obj_dead_cond (obj, _vo), " Precondition" );
634- _containing_obj = obj;
635- }
636-
637- size_t num_failures () const { return _num_failures; }
645+ G1VerifyLiveAndRemSetClosure (oop containing_obj, VerifyOption vo, G1VerifyFailureCounter* failures)
646+ : _vo(vo),
647+ _containing_obj (containing_obj),
648+ _failures(failures) {}
638649
639650 virtual inline void do_oop (narrowOop* p) { do_oop_work (p); }
640651 virtual inline void do_oop (oop* p) { do_oop_work (p); }
@@ -643,9 +654,7 @@ class G1VerifyLiveAndRemSetClosure : public BasicOopIterateClosure {
643654bool HeapRegion::verify_liveness_and_remset (VerifyOption vo) const {
644655 G1CollectedHeap* g1h = G1CollectedHeap::heap ();
645656
646- G1VerifyLiveAndRemSetClosure cl (g1h, vo);
647-
648- size_t other_failures = 0 ;
657+ G1VerifyFailureCounter failures;
649658
650659 HeapWord* p;
651660 for (p = bottom (); p < top (); p += block_size (p)) {
@@ -656,13 +665,13 @@ bool HeapRegion::verify_liveness_and_remset(VerifyOption vo) const {
656665 }
657666
658667 if (is_oop_safe (obj)) {
659- cl. set_containing_obj (obj);
668+ G1VerifyLiveAndRemSetClosure cl (obj, vo, &failures );
660669 obj->oop_iterate (&cl);
661670 } else {
662- other_failures++ ;
671+ failures. record_failure () ;
663672 }
664673
665- if ((cl. num_failures () + other_failures ) >= G1MaxVerifyFailures) {
674+ if (failures. count ( ) >= G1MaxVerifyFailures) {
666675 return true ;
667676 }
668677 }
@@ -672,7 +681,7 @@ bool HeapRegion::verify_liveness_and_remset(VerifyOption vo) const {
672681 p2i (p), p2i (top ()));
673682 return true ;
674683 }
675- return (cl. num_failures () + other_failures ) != 0 ;
684+ return failures. count ( ) != 0 ;
676685}
677686
678687bool HeapRegion::verify (VerifyOption vo) const {
0 commit comments