--- old/src/share/vm/gc/shenandoah/shenandoahConcurrentThread.cpp 2017-10-09 11:48:33.090331126 +0200 +++ new/src/share/vm/gc/shenandoah/shenandoahConcurrentThread.cpp 2017-10-09 11:48:32.988330875 +0200 @@ -162,6 +162,18 @@ TraceCollectorStats tcs(heap->monitoring_support()->concurrent_collection_counters()); TraceMemoryManagerStats tmms(false, GCCause::_no_cause_specified); + // Mark requires clean bitmaps. Clear them here, before diving into STW. + // There is a potential race from this moment on to TAMS reset in init mark: the bitmaps + // would be clear, but TAMS not yet updated. + { + GCTraceTime(Info, gc) time("Concurrent cleanup", gc_timer, GCCause::_no_gc, true); + ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_cleanup); + ShenandoahGCPhase phase_reset(ShenandoahPhaseTimings::conc_cleanup_reset_bitmaps); + WorkGang *workers = heap->workers(); + ShenandoahPushWorkerScope scope(workers, ConcGCThreads); + heap->reset_mark_bitmap(workers); + } + // Start initial mark under STW: { // Workers are setup by VM_ShenandoahInitMark @@ -312,6 +324,17 @@ VM_ShenandoahFinalUpdateRefs final_update_refs; VMThread::execute(&final_update_refs); } + + if (do_it) { + GCTraceTime(Info, gc) time("Concurrent cleanup", gc_timer, GCCause::_no_gc, true); + ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_cleanup); + ShenandoahGCPhase phase_recycle(ShenandoahPhaseTimings::conc_cleanup_recycle); + heap->recycle_trash(); + } + + // Allocations happen during bitmap cleanup, record peak after the phase: + heap->shenandoahPolicy()->record_peak_occupancy(); + } else { // If update-refs were skipped, need to do another verification pass after evacuation. if (ShenandoahVerify && !check_cancellation()) { @@ -327,26 +350,6 @@ reset_full_gc(); } - { - GCTraceTime(Info, gc) time("Concurrent cleanup", gc_timer, GCCause::_no_gc, true); - ShenandoahGCPhase phase(ShenandoahPhaseTimings::conc_cleanup); - - { - ShenandoahGCPhase phase_recycle(ShenandoahPhaseTimings::conc_cleanup_recycle); - heap->recycle_trash(); - } - - { - ShenandoahGCPhase phase_reset(ShenandoahPhaseTimings::conc_cleanup_reset_bitmaps); - WorkGang *workers = heap->workers(); - ShenandoahPushWorkerScope scope(workers, ConcGCThreads); - heap->reset_next_mark_bitmap(workers); - } - } - - // Allocations happen during bitmap cleanup, record peak after the phase: - heap->shenandoahPolicy()->record_peak_occupancy(); - // Cycle is complete heap->shenandoahPolicy()->record_cycle_end();