From 570f33e3f57acb9a8b4b7e3c378b836bef774df4 Mon Sep 17 00:00:00 2001 Date: Wed, 17 Jul 2019 11:36:31 +0000 Subject: [PATCH] Backport of JDK-8129626 summary: G1: set_in_progress() and clear_started() needs a barrier on non-TSO platforms LLT: Bug url: https://bugs.openjdk.java.net/browse/JDK-8129626 --- .../gc_implementation/g1/concurrentMarkThread.cpp | 4 +-- .../gc_implementation/g1/concurrentMarkThread.hpp | 29 +++++++++++++--------- .../vm/gc_implementation/g1/g1CollectedHeap.cpp | 2 +- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp index b56e309234..53fe0837b1 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp @@ -43,8 +43,7 @@ SurrogateLockerThread* ConcurrentMarkThread::ConcurrentMarkThread(ConcurrentMark* cm) : ConcurrentGCThread(), _cm(cm), - _started(false), - _in_progress(false), + _state(Idle), _vtime_accum(0.0), _vtime_mark_accum(0.0) { create_and_start(); @@ -341,7 +340,6 @@ void ConcurrentMarkThread::sleepBeforeNextCycle() { if (started()) { set_in_progress(); - clear_started(); } } diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp index caa7f429c6..5f5f70ac4d 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp @@ -46,8 +46,14 @@ class ConcurrentMarkThread: public ConcurrentGCThread { private: ConcurrentMark* _cm; - volatile bool _started; - volatile bool _in_progress; + + enum State { + Idle, + Started, + InProgress + }; + + volatile State _state; void sleepBeforeNextCycle(); @@ -71,23 +77,22 @@ class ConcurrentMarkThread: public ConcurrentGCThread { ConcurrentMark* cm() { return _cm; } - void set_started() { assert(!_in_progress, "cycle in progress"); _started = true; } - void clear_started() { assert(_in_progress, "must be starting a cycle"); _started = false; } - bool started() { return _started; } - - void set_in_progress() { assert(_started, "must be starting a cycle"); _in_progress = true; } - void clear_in_progress() { assert(!_started, "must not be starting a new cycle"); _in_progress = false; } - bool in_progress() { return _in_progress; } + void set_idle() { assert(_state != Started, "must not be starting a new cycle"); _state = Idle; } + bool idle() { return _state == Idle; } + void set_started() { assert(_state == Idle, "cycle in progress"); _state = Started; } + bool started() { return _state == Started; } + void set_in_progress() { assert(_state == Started, "must be starting a cycle"); _state = InProgress; } + bool in_progress() { return _state == InProgress; } - // This flag returns true from the moment a marking cycle is + // Returns true from the moment a marking cycle is // initiated (during the initial-mark pause when started() is set) // to the moment when the cycle completes (just after the next // marking bitmap has been cleared and in_progress() is - // cleared). While this flag is true we will not start another cycle + // cleared). While during_cycle() is true we will not start another cycle // so that cycles do not overlap. We cannot use just in_progress() // as the CM thread might take some time to wake up before noticing // that started() is set and set in_progress(). - bool during_cycle() { return started() || in_progress(); } + bool during_cycle() { return !idle(); } // shutdown void stop(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index aa6bbc81a4..a6e91a08ce 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -2409,7 +2409,7 @@ void G1CollectedHeap::increment_old_marking_cycles_completed(bool concurrent) { // is set) so that if a waiter requests another System.gc() it doesn't // incorrectly see that a marking cycle is still in progress. if (concurrent) { - _cmThread->clear_in_progress(); + _cmThread->set_idle(); } // This notify_all() will ensure that a thread that called -- 2.12.3