OpenJDK / jdk / jdk
changeset 55998:b3e44e1b135d
8224659: Parallel GC: Use WorkGang (1: PCRefProcTask)
Reviewed-by: stefank, kbarrett, tschatzl
author | lkorinth |
---|---|
date | Fri, 16 Aug 2019 09:18:19 +0200 |
parents | 81ce766c9111 |
children | fc82b6cb8b14 |
files | src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp src/hotspot/share/gc/parallel/pcTasks.cpp src/hotspot/share/gc/parallel/pcTasks.hpp src/hotspot/share/gc/parallel/psCompactionManager.hpp src/hotspot/share/gc/parallel/psParallelCompact.cpp src/hotspot/share/gc/parallel/psScavenge.cpp test/hotspot/jtreg/gc/ergonomics/TestInitialGCThreadLogging.java |
diffstat | 8 files changed, 94 insertions(+), 82 deletions(-) [+] |
line wrap: on
line diff
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp Fri Aug 16 08:42:09 2019 +0800 +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp Fri Aug 16 09:18:19 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -123,6 +123,9 @@ return JNI_ENOMEM; } + // Set up WorkGang + _workers.initialize_workers(); + return JNI_OK; }
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp Fri Aug 16 08:42:09 2019 +0800 +++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp Fri Aug 16 09:18:19 2019 +0200 @@ -37,6 +37,7 @@ #include "gc/shared/referenceProcessor.hpp" #include "gc/shared/softRefPolicy.hpp" #include "gc/shared/strongRootsScope.hpp" +#include "gc/shared/workgroup.hpp" #include "logging/log.hpp" #include "memory/metaspace.hpp" #include "utilities/growableArray.hpp" @@ -78,6 +79,8 @@ MemoryPool* _survivor_pool; MemoryPool* _old_pool; + WorkGang _workers; + virtual void initialize_serviceability(); void trace_heap(GCWhen::Type when, const GCTracer* tracer); @@ -99,7 +102,11 @@ _old_manager(NULL), _eden_pool(NULL), _survivor_pool(NULL), - _old_pool(NULL) { } + _old_pool(NULL), + _workers("GC Thread", + ParallelGCThreads, + true /* are_GC_task_threads */, + false /* are_ConcurrentGC_threads */) { } // For use by VM operations enum CollectionType { @@ -252,6 +259,10 @@ GCMemoryManager* old_gc_manager() const { return _old_manager; } GCMemoryManager* young_gc_manager() const { return _young_manager; } + + WorkGang& workers() { + return _workers; + } }; // Class that can be used to print information about the
--- a/src/hotspot/share/gc/parallel/pcTasks.cpp Fri Aug 16 08:42:09 2019 +0800 +++ b/src/hotspot/share/gc/parallel/pcTasks.cpp Fri Aug 16 09:18:19 2019 +0200 @@ -131,48 +131,6 @@ // -// RefProcTaskProxy -// - -void RefProcTaskProxy::do_it(GCTaskManager* manager, uint which) -{ - assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); - - ParCompactionManager* cm = - ParCompactionManager::gc_thread_compaction_manager(which); - PCMarkAndPushClosure mark_and_push_closure(cm); - ParCompactionManager::FollowStackClosure follow_stack_closure(cm); - _rp_task.work(_work_id, *PSParallelCompact::is_alive_closure(), - mark_and_push_closure, follow_stack_closure); -} - -// -// RefProcTaskExecutor -// - -void RefProcTaskExecutor::execute(ProcessTask& task, uint ergo_workers) -{ - ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); - uint active_gc_threads = heap->gc_task_manager()->active_workers(); - assert(active_gc_threads == ergo_workers, - "Ergonomically chosen workers (%u) must be equal to active workers (%u)", - ergo_workers, active_gc_threads); - OopTaskQueueSet* qset = ParCompactionManager::stack_array(); - TaskTerminator terminator(active_gc_threads, qset); - - GCTaskQueue* q = GCTaskQueue::create(); - for(uint i=0; i<active_gc_threads; i++) { - q->enqueue(new RefProcTaskProxy(task, i)); - } - if (task.marks_oops_alive() && (active_gc_threads>1)) { - for (uint j=0; j<active_gc_threads; j++) { - q->enqueue(new StealMarkingTask(terminator.terminator())); - } - } - PSParallelCompact::gc_task_manager()->execute_and_wait(q); -} - -// // StealMarkingTask //
--- a/src/hotspot/share/gc/parallel/pcTasks.hpp Fri Aug 16 08:42:09 2019 +0800 +++ b/src/hotspot/share/gc/parallel/pcTasks.hpp Fri Aug 16 09:18:19 2019 +0200 @@ -110,40 +110,6 @@ virtual void do_it(GCTaskManager* manager, uint which); }; -// -// RefProcTaskProxy -// -// This task is used as a proxy to parallel reference processing tasks . -// - -class RefProcTaskProxy : public GCTask { - typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask; - ProcessTask & _rp_task; - uint _work_id; -public: - RefProcTaskProxy(ProcessTask & rp_task, uint work_id) - : _rp_task(rp_task), - _work_id(work_id) - { } - -private: - virtual char* name() { return (char *)"Process referents by policy in parallel"; } - - virtual void do_it(GCTaskManager* manager, uint which); -}; - - -// -// RefProcTaskExecutor -// -// Task executor is an interface for the reference processor to run -// tasks using GCTaskManager. -// - -class RefProcTaskExecutor: public AbstractRefProcTaskExecutor { - virtual void execute(ProcessTask& task, uint ergo_workers); -}; - // // StealMarkingTask
--- a/src/hotspot/share/gc/parallel/psCompactionManager.hpp Fri Aug 16 08:42:09 2019 +0800 +++ b/src/hotspot/share/gc/parallel/psCompactionManager.hpp Fri Aug 16 09:18:19 2019 +0200 @@ -44,6 +44,7 @@ friend class UpdateAndFillClosure; friend class RefProcTaskExecutor; friend class IdleGCTask; + friend class PCRefProcTask; public:
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp Fri Aug 16 08:42:09 2019 +0800 +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp Fri Aug 16 09:18:19 2019 +0200 @@ -55,6 +55,7 @@ #include "gc/shared/referenceProcessorPhaseTimes.hpp" #include "gc/shared/spaceDecorator.hpp" #include "gc/shared/weakProcessor.hpp" +#include "gc/shared/workerPolicy.hpp" #include "logging/log.hpp" #include "memory/iterator.inline.hpp" #include "memory/resourceArea.hpp" @@ -1789,6 +1790,12 @@ ResourceMark rm; HandleMark hm; + const uint active_workers = + WorkerPolicy::calc_active_workers(ParallelScavengeHeap::heap()->workers().total_workers(), + ParallelScavengeHeap::heap()->workers().active_workers(), + Threads::number_of_non_daemon_threads()); + ParallelScavengeHeap::heap()->workers().update_active_workers(active_workers); + // Set the number of GC threads to be used in this collection gc_task_manager()->set_active_gang(); gc_task_manager()->task_idle_workers(); @@ -2089,6 +2096,66 @@ } }; +static void steal_marking_work(ParallelTaskTerminator& terminator, uint worker_id) { + assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); + + ParCompactionManager* cm = + ParCompactionManager::gc_thread_compaction_manager(worker_id); + + oop obj = NULL; + ObjArrayTask task; + do { + while (ParCompactionManager::steal_objarray(worker_id, task)) { + cm->follow_array((objArrayOop)task.obj(), task.index()); + cm->follow_marking_stacks(); + } + while (ParCompactionManager::steal(worker_id, obj)) { + cm->follow_contents(obj); + cm->follow_marking_stacks(); + } + } while (!terminator.offer_termination()); +} + +class PCRefProcTask : public AbstractGangTask { + typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask; + ProcessTask& _task; + uint _ergo_workers; + TaskTerminator _terminator; + +public: + PCRefProcTask(ProcessTask& task, uint ergo_workers) : + AbstractGangTask("PCRefProcTask"), + _task(task), + _ergo_workers(ergo_workers), + _terminator(_ergo_workers, ParCompactionManager::stack_array()) { + } + + virtual void work(uint worker_id) { + ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); + assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc"); + + ParCompactionManager* cm = + ParCompactionManager::gc_thread_compaction_manager(worker_id); + PCMarkAndPushClosure mark_and_push_closure(cm); + ParCompactionManager::FollowStackClosure follow_stack_closure(cm); + _task.work(worker_id, *PSParallelCompact::is_alive_closure(), + mark_and_push_closure, follow_stack_closure); + + steal_marking_work(*_terminator.terminator(), worker_id); + } +}; + +class RefProcTaskExecutor: public AbstractRefProcTaskExecutor { + void execute(ProcessTask& process_task, uint ergo_workers) { + assert(ParallelScavengeHeap::heap()->workers().active_workers() == ergo_workers, + "Ergonomically chosen workers (%u) must be equal to active workers (%u)", + ergo_workers, ParallelScavengeHeap::heap()->workers().active_workers()); + + PCRefProcTask task(process_task, ergo_workers); + ParallelScavengeHeap::heap()->workers().run_task(&task); + } +}; + void PSParallelCompact::marking_phase(ParCompactionManager* cm, bool maximum_heap_compaction, ParallelOldTracer *gc_tracer) {
--- a/src/hotspot/share/gc/parallel/psScavenge.cpp Fri Aug 16 08:42:09 2019 +0800 +++ b/src/hotspot/share/gc/parallel/psScavenge.cpp Fri Aug 16 09:18:19 2019 +0200 @@ -47,6 +47,7 @@ #include "gc/shared/referenceProcessorPhaseTimes.hpp" #include "gc/shared/spaceDecorator.hpp" #include "gc/shared/weakProcessor.hpp" +#include "gc/shared/workerPolicy.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" #include "logging/log.hpp" @@ -339,15 +340,20 @@ // straying into the promotion labs. HeapWord* old_top = old_gen->object_space()->top(); + const uint active_workers = + WorkerPolicy::calc_active_workers(ParallelScavengeHeap::heap()->workers().total_workers(), + ParallelScavengeHeap::heap()->workers().active_workers(), + Threads::number_of_non_daemon_threads()); + ParallelScavengeHeap::heap()->workers().update_active_workers(active_workers); + // Release all previously held resources gc_task_manager()->release_all_resources(); // Set the number of GC threads to be used in this collection gc_task_manager()->set_active_gang(); gc_task_manager()->task_idle_workers(); - // Get the active number of workers here and use that value - // throughout the methods. - uint active_workers = gc_task_manager()->active_workers(); + + assert(active_workers == gc_task_manager()->active_workers(), "sanity, taskmanager and workgang ought to agree"); PSPromotionManager::pre_scavenge();
--- a/test/hotspot/jtreg/gc/ergonomics/TestInitialGCThreadLogging.java Fri Aug 16 08:42:09 2019 +0800 +++ b/test/hotspot/jtreg/gc/ergonomics/TestInitialGCThreadLogging.java Fri Aug 16 09:18:19 2019 +0200 @@ -56,7 +56,7 @@ if (GC.Parallel.isSupported()) { noneGCSupported = false; - testInitialGCThreadLogging("UseParallelGC", "ParGC Thread"); + testInitialGCThreadLogging("UseParallelGC", "GC Thread"); } if (GC.Shenandoah.isSupported()) {