2021-02-02 11:40:07 +08:00
|
|
|
From f73bb08c6d1578eae9c5f47253a81dd06e51beba Mon Sep 17 00:00:00 2001
|
|
|
|
|
Date: Fri, 22 Jan 2021 11:39:09 +0800
|
|
|
|
|
Subject: Backport of JDK-8129626
|
2020-01-20 12:09:52 +08:00
|
|
|
|
|
|
|
|
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
|
|
|
|
|
---
|
2021-02-02 11:40:07 +08:00
|
|
|
.../g1/concurrentMarkThread.cpp | 4 +--
|
|
|
|
|
.../g1/concurrentMarkThread.hpp | 29 +++++++++++--------
|
|
|
|
|
.../gc_implementation/g1/g1CollectedHeap.cpp | 2 +-
|
2020-01-20 12:09:52 +08:00
|
|
|
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
|
2021-02-02 11:40:07 +08:00
|
|
|
index b56e30923..53fe0837b 100644
|
2020-01-20 12:09:52 +08:00
|
|
|
--- 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
|
2021-02-02 11:40:07 +08:00
|
|
|
index caa7f429c..5f5f70ac4 100644
|
2020-01-20 12:09:52 +08:00
|
|
|
--- 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
|
2021-02-02 11:40:07 +08:00
|
|
|
index 4eccf9805..97643e792 100644
|
2020-01-20 12:09:52 +08:00
|
|
|
--- 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
|
|
|
|
|
--
|
2021-02-02 11:40:07 +08:00
|
|
|
2.19.0
|
2020-01-20 12:09:52 +08:00
|
|
|
|