@@ -87,6 +87,7 @@ class ShenandoahVerifyOopClosure : public BasicOopIterateClosure {
8787 _loc (nullptr ),
8888 _generation (nullptr ) {
8989 if (options._verify_marked == ShenandoahVerifier::_verify_marked_complete_except_references ||
90+ options._verify_marked == ShenandoahVerifier::_verify_marked_complete_satb_empty ||
9091 options._verify_marked == ShenandoahVerifier::_verify_marked_disable) {
9192 set_ref_discoverer_internal (new ShenandoahIgnoreReferenceDiscoverer ());
9293 }
@@ -257,6 +258,7 @@ class ShenandoahVerifyOopClosure : public BasicOopIterateClosure {
257258 " Must be marked in complete bitmap" );
258259 break ;
259260 case ShenandoahVerifier::_verify_marked_complete_except_references:
261+ case ShenandoahVerifier::_verify_marked_complete_satb_empty:
260262 check (ShenandoahAsserts::_safe_all, obj, _heap->complete_marking_context ()->is_marked_or_old (obj),
261263 " Must be marked in complete bitmap, except j.l.r.Reference referents" );
262264 break ;
@@ -597,6 +599,20 @@ class ShenandoahVerifierReachableTask : public WorkerTask {
597599 }
598600};
599601
602+ class ShenandoahVerifyNoIncompleteSatbBuffers : public ThreadClosure {
603+ public:
604+ virtual void do_thread (Thread* thread) {
605+ SATBMarkQueue& queue = ShenandoahThreadLocalData::satb_mark_queue (thread);
606+ if (!is_empty (queue)) {
607+ fatal (" All SATB buffers should have been flushed during mark" );
608+ }
609+ }
610+ private:
611+ bool is_empty (SATBMarkQueue& queue) {
612+ return queue.buffer () == nullptr || queue.index () == queue.capacity ();
613+ }
614+ };
615+
600616class ShenandoahVerifierMarkedRegionTask : public WorkerTask {
601617private:
602618 const char * _label;
@@ -622,6 +638,10 @@ class ShenandoahVerifierMarkedRegionTask : public WorkerTask {
622638 _claimed (0 ),
623639 _processed (0 ),
624640 _generation (nullptr ) {
641+ if (_options._verify_marked == ShenandoahVerifier::_verify_marked_complete_satb_empty) {
642+ Threads::change_thread_claim_token ();
643+ }
644+
625645 if (_heap->mode ()->is_generational ()) {
626646 _generation = _heap->active_generation ();
627647 assert (_generation != nullptr , " Expected active generation in this mode." );
@@ -633,6 +653,11 @@ class ShenandoahVerifierMarkedRegionTask : public WorkerTask {
633653 }
634654
635655 virtual void work (uint worker_id) {
656+ if (_options._verify_marked == ShenandoahVerifier::_verify_marked_complete_satb_empty) {
657+ ShenandoahVerifyNoIncompleteSatbBuffers verify_satb;
658+ Threads::possibly_parallel_threads_do (true , &verify_satb);
659+ }
660+
636661 ShenandoahVerifierStack stack;
637662 ShenandoahVerifyOopClosure cl (&stack, _bitmap, _ld,
638663 ShenandoahMessageBuffer (" %s, Marked" , _label),
@@ -945,7 +970,10 @@ void ShenandoahVerifier::verify_at_safepoint(const char* label,
945970 // version
946971
947972 size_t count_marked = 0 ;
948- if (ShenandoahVerifyLevel >= 4 && (marked == _verify_marked_complete || marked == _verify_marked_complete_except_references)) {
973+ if (ShenandoahVerifyLevel >= 4 &&
974+ (marked == _verify_marked_complete ||
975+ marked == _verify_marked_complete_except_references ||
976+ marked == _verify_marked_complete_satb_empty)) {
949977 guarantee (_heap->marking_context ()->is_complete (), " Marking context should be complete" );
950978 ShenandoahVerifierMarkedRegionTask task (_verification_bit_map, ld, label, options);
951979 _heap->workers ()->run_task (&task);
@@ -1031,7 +1059,7 @@ void ShenandoahVerifier::verify_after_concmark() {
10311059 " After Mark" ,
10321060 _verify_remembered_disable, // do not verify remembered set
10331061 _verify_forwarded_none, // no forwarded references
1034- _verify_marked_complete_except_references ,
1062+ _verify_marked_complete_satb_empty ,
10351063 // bitmaps as precise as we can get, except dangling j.l.r.Refs
10361064 _verify_cset_none, // no references to cset anymore
10371065 _verify_liveness_complete, // liveness data must be complete here
0 commit comments