From 1fe9667bb594b66f7363cec246ebc99cd0ac9103 Mon Sep 17 00:00:00 2001
Date: Thu, 21 Sep 2023 16:43:24 +0800
Subject: add Parallel-Full-gc-mark-stack-draining-should

---
 .../share/gc/parallel/psCompactionManager.cpp  | 18 +++++++++++++++---
 .../share/gc/parallel/psCompactionManager.hpp  |  1 +
 .../share/gc/parallel/psParallelCompact.cpp    | 12 +++++-------
 3 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.cpp b/src/hotspot/share/gc/parallel/psCompactionManager.cpp
index 117817caa..b2c17140d 100644
--- a/src/hotspot/share/gc/parallel/psCompactionManager.cpp
+++ b/src/hotspot/share/gc/parallel/psCompactionManager.cpp
@@ -115,12 +115,24 @@ ParCompactionManager::gc_thread_compaction_manager(uint index) {
   return _manager_array[index];
 }
 
+bool ParCompactionManager::transfer_from_overflow_stack(ObjArrayTask& task) {
+  while (_objarray_stack.pop_overflow(task)) {
+    if (!_objarray_stack.try_push_to_taskqueue(task)) {
+      return true;
+    }
+  }
+  return false;
+}
+
 void ParCompactionManager::follow_marking_stacks() {
   do {
-    // Drain the overflow stack first, to allow stealing from the marking stack.
+    // First, try to move tasks from the overflow stack into the shared buffer, so
+    // that other threads can steal. Otherwise process the overflow stack first.
     oop obj;
     while (marking_stack()->pop_overflow(obj)) {
-      follow_contents(obj);
+      if (!marking_stack()->try_push_to_taskqueue(obj)) {
+        follow_contents(obj);
+      }
     }
     while (marking_stack()->pop_local(obj)) {
       follow_contents(obj);
@@ -128,7 +140,7 @@ void ParCompactionManager::follow_marking_stacks() {
 
     // Process ObjArrays one at a time to avoid marking stack bloat.
     ObjArrayTask task;
-    if (_objarray_stack.pop_overflow(task) || _objarray_stack.pop_local(task)) {
+    if (transfer_from_overflow_stack(task) || _objarray_stack.pop_local(task)) {
       follow_array((objArrayOop)task.obj(), task.index());
     }
   } while (!marking_stacks_empty());
diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.hpp b/src/hotspot/share/gc/parallel/psCompactionManager.hpp
index a73e898f0..12b5d891d 100644
--- a/src/hotspot/share/gc/parallel/psCompactionManager.hpp
+++ b/src/hotspot/share/gc/parallel/psCompactionManager.hpp
@@ -94,6 +94,7 @@ class ParCompactionManager : public CHeapObj<mtGC> {
 
   static void initialize(ParMarkBitMap* mbm);
 
+  bool transfer_from_overflow_stack(ObjArrayTask& task);
  protected:
   // Array of task queues.  Needed by the task terminator.
   static RegionTaskQueueSet* region_task_queues()      { return _region_task_queues; }
diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp
index 8cf13bd1d..3c276db70 100644
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp
@@ -2002,17 +2002,15 @@ void steal_marking_work(TaskTerminator& terminator, uint worker_id) {
   ParCompactionManager* cm =
     ParCompactionManager::gc_thread_compaction_manager(worker_id);
 
-  oop obj = NULL;
-  ObjArrayTask task;
   do {
-    while (ParCompactionManager::steal_objarray(worker_id,  task)) {
+    oop obj = NULL;
+    ObjArrayTask task;
+    if (ParCompactionManager::steal_objarray(worker_id,  task)) {
       cm->follow_array((objArrayOop)task.obj(), task.index());
-      cm->follow_marking_stacks();
-    }
-    while (ParCompactionManager::steal(worker_id, obj)) {
+    } else if (ParCompactionManager::steal(worker_id, obj)) {
       cm->follow_contents(obj);
-      cm->follow_marking_stacks();
     }
+    cm->follow_marking_stacks();
   } while (!terminator.offer_termination());
 }
 
-- 
2.22.0

