8280705: Parallel: Full gc mark stack draining should prefer to make work available to other threads

Reviewed-by: ayang, mli
This commit is contained in:
Thomas Schatzl 2022-01-31 16:01:18 +00:00
parent 091aff92e2
commit bdda43e066
3 changed files with 21 additions and 10 deletions

View File

@ -113,12 +113,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);
@ -126,7 +138,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());

View File

@ -97,6 +97,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; }

View File

@ -1984,17 +1984,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());
}