diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.cpp b/src/hotspot/share/gc/parallel/psCompactionManager.cpp index b95c7c619af7d..d9f2749230e4c 100644 --- a/src/hotspot/share/gc/parallel/psCompactionManager.cpp +++ b/src/hotspot/share/gc/parallel/psCompactionManager.cpp @@ -54,7 +54,9 @@ Monitor* ParCompactionManager::_shadow_region_monitor = nullptr; PreservedMarksSet* ParCompactionManager::_preserved_marks_set = nullptr; -ParCompactionManager::ParCompactionManager(PreservedMarks* preserved_marks) { +ParCompactionManager::ParCompactionManager(PreservedMarks* preserved_marks, + ReferenceProcessor* ref_processor) + : _mark_and_push_closure(this, ref_processor) { ParallelScavengeHeap* heap = ParallelScavengeHeap::heap(); @@ -66,8 +68,9 @@ ParCompactionManager::ParCompactionManager(PreservedMarks* preserved_marks) { } void ParCompactionManager::initialize(ParMarkBitMap* mbm) { - assert(ParallelScavengeHeap::heap() != nullptr, - "Needed for initialization"); + assert(ParallelScavengeHeap::heap() != nullptr, "Needed for initialization"); + assert(PSParallelCompact::ref_processor() != nullptr, "precondition"); + assert(ParallelScavengeHeap::heap()->workers().max_workers() != 0, "Not initialized?"); _mark_bitmap = mbm; @@ -85,15 +88,13 @@ void ParCompactionManager::initialize(ParMarkBitMap* mbm) { // Create and register the ParCompactionManager(s) for the worker threads. for(uint i=0; iget(i)); + _manager_array[i] = new ParCompactionManager(_preserved_marks_set->get(i), + PSParallelCompact::ref_processor()); oop_task_queues()->register_queue(i, _manager_array[i]->oop_stack()); _objarray_task_queues->register_queue(i, &_manager_array[i]->_objarray_stack); region_task_queues()->register_queue(i, _manager_array[i]->region_stack()); } - assert(ParallelScavengeHeap::heap()->workers().max_workers() != 0, - "Not initialized?"); - _shadow_region_array = new (mtGC) GrowableArray(10, mtGC); _shadow_region_monitor = new Monitor(Mutex::nosafepoint, "CompactionManager_lock"); diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.hpp b/src/hotspot/share/gc/parallel/psCompactionManager.hpp index 0dd68d2e2f7c7..da1609a32d8eb 100644 --- a/src/hotspot/share/gc/parallel/psCompactionManager.hpp +++ b/src/hotspot/share/gc/parallel/psCompactionManager.hpp @@ -25,6 +25,7 @@ #ifndef SHARE_GC_PARALLEL_PSCOMPACTIONMANAGER_HPP #define SHARE_GC_PARALLEL_PSCOMPACTIONMANAGER_HPP +#include "classfile/classLoaderData.hpp" #include "gc/parallel/psParallelCompact.hpp" #include "gc/shared/preservedMarks.hpp" #include "gc/shared/stringdedup/stringDedup.hpp" @@ -40,6 +41,19 @@ class ObjectStartArray; class ParallelCompactData; class ParMarkBitMap; +class PCMarkAndPushClosure: public ClaimMetadataVisitingOopIterateClosure { + ParCompactionManager* _compaction_manager; + + template void do_oop_work(T* p); +public: + PCMarkAndPushClosure(ParCompactionManager* cm, ReferenceProcessor* rp) : + ClaimMetadataVisitingOopIterateClosure(ClassLoaderData::_claim_stw_fullgc_mark, rp), + _compaction_manager(cm) { } + + virtual void do_oop(oop* p) { do_oop_work(p); } + virtual void do_oop(narrowOop* p) { do_oop_work(p); } +}; + class ParCompactionManager : public CHeapObj { friend class MarkFromRootsTask; friend class ParallelCompactRefProcProxyTask; @@ -47,6 +61,7 @@ class ParCompactionManager : public CHeapObj { friend class ParMarkBitMap; friend class PSParallelCompact; friend class FillDensePrefixAndCompactionTask; + friend class PCAddThreadRootsMarkingTaskClosure; private: typedef OverflowTaskQueue OopTaskQueue; @@ -71,6 +86,7 @@ class ParCompactionManager : public CHeapObj { ObjArrayTaskQueue _objarray_stack; size_t _next_shadow_region; + PCMarkAndPushClosure _mark_and_push_closure; // Is there a way to reuse the _oop_stack for the // saving empty regions? For now just create a different // type of TaskQueue. @@ -104,7 +120,9 @@ class ParCompactionManager : public CHeapObj { // objArray stack, otherwise returns false and the task is invalid. bool publish_or_pop_objarray_tasks(ObjArrayTask& task); - ParCompactionManager(PreservedMarks* preserved_marks); + ParCompactionManager(PreservedMarks* preserved_marks, + ReferenceProcessor* ref_processor); + // Array of task queues. Needed by the task terminator. static RegionTaskQueueSet* region_task_queues() { return _region_task_queues; } OopTaskQueue* oop_stack() { return &_oop_stack; } diff --git a/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp b/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp index 22acc11beec3c..0b92862223826 100644 --- a/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp +++ b/src/hotspot/share/gc/parallel/psCompactionManager.inline.hpp @@ -41,29 +41,10 @@ #include "utilities/debug.hpp" #include "utilities/globalDefinitions.hpp" -class PCMarkAndPushClosure: public OopClosure { -private: - ParCompactionManager* _compaction_manager; -public: - PCMarkAndPushClosure(ParCompactionManager* cm) : _compaction_manager(cm) { } - - template void do_oop_work(T* p) { _compaction_manager->mark_and_push(p); } - virtual void do_oop(oop* p) { do_oop_work(p); } - virtual void do_oop(narrowOop* p) { do_oop_work(p); } -}; - -class PCIterateMarkAndPushClosure: public ClaimMetadataVisitingOopIterateClosure { -private: - ParCompactionManager* _compaction_manager; -public: - PCIterateMarkAndPushClosure(ParCompactionManager* cm, ReferenceProcessor* rp) : - ClaimMetadataVisitingOopIterateClosure(ClassLoaderData::_claim_stw_fullgc_mark, rp), - _compaction_manager(cm) { } - - template void do_oop_work(T* p) { _compaction_manager->mark_and_push(p); } - virtual void do_oop(oop* p) { do_oop_work(p); } - virtual void do_oop(narrowOop* p) { do_oop_work(p); } -}; +template +inline void PCMarkAndPushClosure::do_oop_work(T* p) { + _compaction_manager->mark_and_push(p); +} inline bool ParCompactionManager::steal(int queue_num, oop& t) { return oop_task_queues()->steal(queue_num, t); @@ -161,13 +142,12 @@ inline void ParCompactionManager::follow_array(objArrayOop obj, int index) { inline void ParCompactionManager::follow_contents(oop obj) { assert(PSParallelCompact::mark_bitmap()->is_marked(obj), "should be marked"); - PCIterateMarkAndPushClosure cl(this, PSParallelCompact::ref_processor()); if (obj->is_objArray()) { - cl.do_klass(obj->klass()); + _mark_and_push_closure.do_klass(obj->klass()); follow_array(objArrayOop(obj), 0); } else { - obj->oop_iterate(&cl); + obj->oop_iterate(&_mark_and_push_closure); } } diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp index f41108d1a597f..4d54f11805ac2 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp @@ -1188,10 +1188,11 @@ class PCAddThreadRootsMarkingTaskClosure : public ThreadClosure { ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(_worker_id); - PCMarkAndPushClosure mark_and_push_closure(cm); - MarkingNMethodClosure mark_and_push_in_blobs(&mark_and_push_closure, !NMethodToOopClosure::FixRelocations, true /* keepalive nmethods */); + MarkingNMethodClosure mark_and_push_in_blobs(&cm->_mark_and_push_closure, + !NMethodToOopClosure::FixRelocations, + true /* keepalive nmethods */); - thread->oops_do(&mark_and_push_closure, &mark_and_push_in_blobs); + thread->oops_do(&cm->_mark_and_push_closure, &mark_and_push_in_blobs); // Do the real work cm->follow_marking_stacks(); @@ -1232,22 +1233,22 @@ class MarkFromRootsTask : public WorkerTask { virtual void work(uint worker_id) { ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(worker_id); cm->create_marking_stats_cache(); - PCMarkAndPushClosure mark_and_push_closure(cm); - { - CLDToOopClosure cld_closure(&mark_and_push_closure, ClassLoaderData::_claim_stw_fullgc_mark); + CLDToOopClosure cld_closure(&cm->_mark_and_push_closure, ClassLoaderData::_claim_stw_fullgc_mark); ClassLoaderDataGraph::always_strong_cld_do(&cld_closure); // Do the real work cm->follow_marking_stacks(); } - PCAddThreadRootsMarkingTaskClosure closure(worker_id); - Threads::possibly_parallel_threads_do(true /* is_par */, &closure); + { + PCAddThreadRootsMarkingTaskClosure closure(worker_id); + Threads::possibly_parallel_threads_do(_active_workers > 1 /* is_par */, &closure); + } // Mark from OopStorages { - _oop_storage_set_par_state.oops_do(&mark_and_push_closure); + _oop_storage_set_par_state.oops_do(&cm->_mark_and_push_closure); // Do the real work cm->follow_marking_stacks(); } @@ -1269,10 +1270,9 @@ class ParallelCompactRefProcProxyTask : public RefProcProxyTask { void work(uint worker_id) override { assert(worker_id < _max_workers, "sanity"); ParCompactionManager* cm = (_tm == RefProcThreadModel::Single) ? ParCompactionManager::get_vmthread_cm() : ParCompactionManager::gc_thread_compaction_manager(worker_id); - PCMarkAndPushClosure keep_alive(cm); BarrierEnqueueDiscoveredFieldClosure enqueue; ParCompactionManager::FollowStackClosure complete_gc(cm, (_tm == RefProcThreadModel::Single) ? nullptr : &_terminator, worker_id); - _rp_task->rp_work(worker_id, PSParallelCompact::is_alive_closure(), &keep_alive, &enqueue, &complete_gc); + _rp_task->rp_work(worker_id, PSParallelCompact::is_alive_closure(), &cm->_mark_and_push_closure, &enqueue, &complete_gc); } void prepare_run_task_hook() override {