Skip to content

Commit dbf48a5

Browse files
author
Kim Barrett
committed
8344665: Refactor PartialArrayState allocation for reuse
Reviewed-by: tschatzl, ayang, iwalulya, zgu
1 parent 5cc150c commit dbf48a5

14 files changed

+211
-129
lines changed

src/hotspot/share/gc/g1/g1CollectedHeap.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
#include "gc/shared/isGCActiveMark.hpp"
8787
#include "gc/shared/locationPrinter.inline.hpp"
8888
#include "gc/shared/oopStorageParState.hpp"
89+
#include "gc/shared/partialArrayState.hpp"
8990
#include "gc/shared/referenceProcessor.inline.hpp"
9091
#include "gc/shared/suspendibleThreadSet.hpp"
9192
#include "gc/shared/taskqueue.inline.hpp"
@@ -1165,6 +1166,7 @@ G1CollectedHeap::G1CollectedHeap() :
11651166
_cm_thread(nullptr),
11661167
_cr(nullptr),
11671168
_task_queues(nullptr),
1169+
_partial_array_state_manager(nullptr),
11681170
_ref_processor_stw(nullptr),
11691171
_is_alive_closure_stw(this),
11701172
_is_subject_to_discovery_stw(this),
@@ -1198,9 +1200,13 @@ G1CollectedHeap::G1CollectedHeap() :
11981200
_task_queues->register_queue(i, q);
11991201
}
12001202

1203+
_partial_array_state_manager = new PartialArrayStateManager(n_queues);
1204+
12011205
_gc_tracer_stw->initialize();
1206+
}
12021207

1203-
guarantee(_task_queues != nullptr, "task_queues allocation failure.");
1208+
PartialArrayStateManager* G1CollectedHeap::partial_array_state_manager() const {
1209+
return _partial_array_state_manager;
12041210
}
12051211

12061212
G1RegionToSpaceMapper* G1CollectedHeap::create_aux_memory_mapper(const char* description,

src/hotspot/share/gc/g1/g1CollectedHeap.hpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class GCMemoryManager;
8282
class G1HeapRegion;
8383
class MemoryPool;
8484
class nmethod;
85+
class PartialArrayStateManager;
8586
class ReferenceProcessor;
8687
class STWGCTimer;
8788
class WorkerThreads;
@@ -807,8 +808,9 @@ class G1CollectedHeap : public CollectedHeap {
807808
// The concurrent refiner.
808809
G1ConcurrentRefine* _cr;
809810

810-
// The parallel task queues
811-
G1ScannerTasksQueueSet *_task_queues;
811+
// Reusable parallel task queues and partial array manager.
812+
G1ScannerTasksQueueSet* _task_queues;
813+
PartialArrayStateManager* _partial_array_state_manager;
812814

813815
// ("Weak") Reference processing support.
814816
//
@@ -874,6 +876,8 @@ class G1CollectedHeap : public CollectedHeap {
874876
G1ScannerTasksQueueSet* task_queues() const;
875877
G1ScannerTasksQueue* task_queue(uint i) const;
876878

879+
PartialArrayStateManager* partial_array_state_manager() const;
880+
877881
// Create a G1CollectedHeap.
878882
// Must call the initialize method afterwards.
879883
// May not return if something goes wrong.

src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ G1GCPhaseTimes::G1GCPhaseTimes(STWGCTimer* gc_timer, uint max_gc_threads) :
105105
_gc_par_phases[UpdateDerivedPointers] = new WorkerDataArray<double>("UpdateDerivedPointers", "Update Derived Pointers (ms):", max_gc_threads);
106106
#endif
107107
_gc_par_phases[EagerlyReclaimHumongousObjects] = new WorkerDataArray<double>("EagerlyReclaimHumongousObjects", "Eagerly Reclaim Humongous Objects (ms):", max_gc_threads);
108+
_gc_par_phases[ResetPartialArrayStateManager] = new WorkerDataArray<double>("ResetPartialArrayStateManager", "Reset Partial Array State Manager (ms):", max_gc_threads);
108109
_gc_par_phases[ProcessEvacuationFailedRegions] = new WorkerDataArray<double>("ProcessEvacuationFailedRegions", "Process Evacuation Failed Regions (ms):", max_gc_threads);
109110

110111
_gc_par_phases[ScanHR]->create_thread_work_items("Scanned Cards:", ScanHRScannedCards);
@@ -517,6 +518,7 @@ double G1GCPhaseTimes::print_post_evacuate_collection_set(bool evacuation_failed
517518
debug_phase(_gc_par_phases[UpdateDerivedPointers], 1);
518519
#endif
519520
debug_phase(_gc_par_phases[EagerlyReclaimHumongousObjects], 1);
521+
trace_phase(_gc_par_phases[ResetPartialArrayStateManager]);
520522

521523
if (G1CollectedHeap::heap()->should_sample_collection_set_candidates()) {
522524
debug_phase(_gc_par_phases[SampleCollectionSetCandidates], 1);

src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ class G1GCPhaseTimes : public CHeapObj<mtGC> {
8787
UpdateDerivedPointers,
8888
#endif
8989
EagerlyReclaimHumongousObjects,
90+
ResetPartialArrayStateManager,
9091
ProcessEvacuationFailedRegions,
9192
ResetMarkingState,
9293
NoteStartOfMark,

src/hotspot/share/gc/g1/g1ParScanThreadState.cpp

+9-13
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,7 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h,
6161
uint worker_id,
6262
uint num_workers,
6363
G1CollectionSet* collection_set,
64-
G1EvacFailureRegions* evac_failure_regions,
65-
PartialArrayStateAllocator* pas_allocator)
64+
G1EvacFailureRegions* evac_failure_regions)
6665
: _g1h(g1h),
6766
_task_queue(g1h->task_queue(worker_id)),
6867
_rdc_local_qset(rdcqs),
@@ -81,7 +80,7 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h,
8180
_surviving_young_words(nullptr),
8281
_surviving_words_length(collection_set->young_region_length() + 1),
8382
_old_gen_is_full(false),
84-
_partial_array_state_allocator(pas_allocator),
83+
_partial_array_state_allocator(g1h->partial_array_state_manager()),
8584
_partial_array_stepper(num_workers, ParGCArrayScanChunk),
8685
_string_dedup_requests(),
8786
_max_num_optional_regions(collection_set->optional_region_length()),
@@ -254,7 +253,7 @@ void G1ParScanThreadState::do_partial_array(PartialArrayState* state) {
254253
checked_cast<int>(step._index),
255254
checked_cast<int>(step._index + _partial_array_stepper.chunk_size()));
256255
// Release reference to the state, now that we're done with it.
257-
_partial_array_state_allocator->release(_worker_id, state);
256+
_partial_array_state_allocator.release(state);
258257
}
259258

260259
MAYBE_INLINE_EVACUATION
@@ -277,11 +276,10 @@ void G1ParScanThreadState::start_partial_objarray(G1HeapRegionAttr dest_attr,
277276
assert(((array_length - step._index) % _partial_array_stepper.chunk_size()) == 0,
278277
"invariant");
279278
PartialArrayState* state =
280-
_partial_array_state_allocator->allocate(_worker_id,
281-
from_obj, to_obj,
282-
step._index,
283-
array_length,
284-
step._ncreate);
279+
_partial_array_state_allocator.allocate(from_obj, to_obj,
280+
step._index,
281+
array_length,
282+
step._ncreate);
285283
for (uint i = 0; i < step._ncreate; ++i) {
286284
push_on_queue(ScannerTask(state));
287285
}
@@ -601,8 +599,7 @@ G1ParScanThreadState* G1ParScanThreadStateSet::state_for_worker(uint worker_id)
601599
worker_id,
602600
_num_workers,
603601
_collection_set,
604-
_evac_failure_regions,
605-
&_partial_array_state_allocator);
602+
_evac_failure_regions);
606603
}
607604
return _states[worker_id];
608605
}
@@ -732,8 +729,7 @@ G1ParScanThreadStateSet::G1ParScanThreadStateSet(G1CollectedHeap* g1h,
732729
_surviving_young_words_total(NEW_C_HEAP_ARRAY(size_t, collection_set->young_region_length() + 1, mtGC)),
733730
_num_workers(num_workers),
734731
_flushed(false),
735-
_evac_failure_regions(evac_failure_regions),
736-
_partial_array_state_allocator(num_workers)
732+
_evac_failure_regions(evac_failure_regions)
737733
{
738734
for (uint i = 0; i < num_workers; ++i) {
739735
_states[i] = nullptr;

src/hotspot/share/gc/g1/g1ParScanThreadState.hpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class G1ParScanThreadState : public CHeapObj<mtGC> {
8484
// Indicates whether in the last generation (old) there is no more space
8585
// available for allocation.
8686
bool _old_gen_is_full;
87-
PartialArrayStateAllocator* _partial_array_state_allocator;
87+
PartialArrayStateAllocator _partial_array_state_allocator;
8888
PartialArrayTaskStepper _partial_array_stepper;
8989
StringDedup::Requests _string_dedup_requests;
9090

@@ -124,8 +124,7 @@ class G1ParScanThreadState : public CHeapObj<mtGC> {
124124
uint worker_id,
125125
uint num_workers,
126126
G1CollectionSet* collection_set,
127-
G1EvacFailureRegions* evac_failure_regions,
128-
PartialArrayStateAllocator* partial_array_state_allocator);
127+
G1EvacFailureRegions* evac_failure_regions);
129128
virtual ~G1ParScanThreadState();
130129

131130
void set_ref_discoverer(ReferenceDiscoverer* rd) { _scanner.set_ref_discoverer(rd); }
@@ -247,7 +246,6 @@ class G1ParScanThreadStateSet : public StackObj {
247246
uint _num_workers;
248247
bool _flushed;
249248
G1EvacFailureRegions* _evac_failure_regions;
250-
PartialArrayStateAllocator _partial_array_state_allocator;
251249

252250
public:
253251
G1ParScanThreadStateSet(G1CollectedHeap* g1h,

src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "gc/g1/g1RemSet.hpp"
4343
#include "gc/g1/g1YoungGCPostEvacuateTasks.hpp"
4444
#include "gc/shared/bufferNode.hpp"
45+
#include "gc/shared/partialArrayState.hpp"
4546
#include "jfr/jfrEvents.hpp"
4647
#include "oops/access.inline.hpp"
4748
#include "oops/compressedOops.inline.hpp"
@@ -944,6 +945,25 @@ class G1PostEvacuateCollectionSetCleanupTask2::ResizeTLABsTask : public G1Abstra
944945
}
945946
};
946947

948+
class G1PostEvacuateCollectionSetCleanupTask2::ResetPartialArrayStateManagerTask
949+
: public G1AbstractSubTask
950+
{
951+
public:
952+
ResetPartialArrayStateManagerTask()
953+
: G1AbstractSubTask(G1GCPhaseTimes::ResetPartialArrayStateManager)
954+
{}
955+
956+
double worker_cost() const override {
957+
return AlmostNoWork;
958+
}
959+
960+
void do_work(uint worker_id) override {
961+
// This must be in phase2 cleanup, after phase1 has destroyed all of the
962+
// associated allocators.
963+
G1CollectedHeap::heap()->partial_array_state_manager()->reset();
964+
}
965+
};
966+
947967
G1PostEvacuateCollectionSetCleanupTask2::G1PostEvacuateCollectionSetCleanupTask2(G1ParScanThreadStateSet* per_thread_states,
948968
G1EvacInfo* evacuation_info,
949969
G1EvacFailureRegions* evac_failure_regions) :
@@ -955,6 +975,7 @@ G1PostEvacuateCollectionSetCleanupTask2::G1PostEvacuateCollectionSetCleanupTask2
955975
if (G1CollectedHeap::heap()->has_humongous_reclaim_candidates()) {
956976
add_serial_task(new EagerlyReclaimHumongousObjectsTask());
957977
}
978+
add_serial_task(new ResetPartialArrayStateManagerTask());
958979

959980
if (evac_failure_regions->has_regions_evac_failed()) {
960981
add_parallel_task(new ProcessEvacuationFailedRegionsTask(evac_failure_regions));

src/hotspot/share/gc/g1/g1YoungGCPostEvacuateTasks.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class G1PostEvacuateCollectionSetCleanupTask1 : public G1BatchedTask {
5858
// - Redirty Logged Cards
5959
// - Free Collection Set
6060
// - Resize TLABs
61+
// - Reset the reusable PartialArrayStateManager.
6162
class G1PostEvacuateCollectionSetCleanupTask2 : public G1BatchedTask {
6263
class EagerlyReclaimHumongousObjectsTask;
6364
#if COMPILER2_OR_JVMCI
@@ -68,6 +69,7 @@ class G1PostEvacuateCollectionSetCleanupTask2 : public G1BatchedTask {
6869
class RedirtyLoggedCardsTask;
6970
class FreeCollectionSetTask;
7071
class ResizeTLABsTask;
72+
class ResetPartialArrayStateManagerTask;
7173

7274
public:
7375
G1PostEvacuateCollectionSetCleanupTask2(G1ParScanThreadStateSet* per_thread_states,

src/hotspot/share/gc/parallel/psPromotionManager.cpp

+13-17
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ PSPromotionManager::PSScannerTasksQueueSet* PSPromotionManager::_stack_array_dep
5151
PreservedMarksSet* PSPromotionManager::_preserved_marks_set = nullptr;
5252
PSOldGen* PSPromotionManager::_old_gen = nullptr;
5353
MutableSpace* PSPromotionManager::_young_space = nullptr;
54-
PartialArrayStateAllocator* PSPromotionManager::_partial_array_state_allocator = nullptr;
54+
PartialArrayStateManager* PSPromotionManager::_partial_array_state_manager = nullptr;
5555

5656
void PSPromotionManager::initialize() {
5757
ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
@@ -61,21 +61,20 @@ void PSPromotionManager::initialize() {
6161

6262
const uint promotion_manager_num = ParallelGCThreads;
6363

64+
assert(_partial_array_state_manager == nullptr, "Attempt to initialize twice");
65+
_partial_array_state_manager
66+
= new PartialArrayStateManager(promotion_manager_num);
67+
6468
// To prevent false sharing, we pad the PSPromotionManagers
6569
// and make sure that the first instance starts at a cache line.
6670
assert(_manager_array == nullptr, "Attempt to initialize twice");
6771
_manager_array = PaddedArray<PSPromotionManager, mtGC>::create_unfreeable(promotion_manager_num);
6872

69-
assert(_partial_array_state_allocator == nullptr, "Attempt to initialize twice");
70-
_partial_array_state_allocator
71-
= new PartialArrayStateAllocator(ParallelGCThreads);
72-
73-
_stack_array_depth = new PSScannerTasksQueueSet(ParallelGCThreads);
73+
_stack_array_depth = new PSScannerTasksQueueSet(promotion_manager_num);
7474

7575
// Create and register the PSPromotionManager(s) for the worker threads.
7676
for(uint i=0; i<ParallelGCThreads; i++) {
7777
stack_array_depth()->register_queue(i, _manager_array[i].claimed_stack_depth());
78-
_manager_array[i]._partial_array_state_allocator_index = i;
7978
}
8079
// The VMThread gets its own PSPromotionManager, which is not available
8180
// for work stealing.
@@ -187,7 +186,8 @@ void PSPromotionManager::reset_stats() {
187186

188187
// Most members are initialized either by initialize() or reset().
189188
PSPromotionManager::PSPromotionManager()
190-
: _partial_array_stepper(ParallelGCThreads, ParGCArrayScanChunk)
189+
: _partial_array_state_allocator(_partial_array_state_manager),
190+
_partial_array_stepper(ParallelGCThreads, ParGCArrayScanChunk)
191191
{
192192
// We set the old lab's start array.
193193
_old_lab.set_start_array(old_gen()->start_array());
@@ -198,9 +198,6 @@ PSPromotionManager::PSPromotionManager()
198198
_target_stack_size = GCDrainStackTargetSize;
199199
}
200200

201-
// Initialize to a bad value; fixed by initialize().
202-
_partial_array_state_allocator_index = UINT_MAX;
203-
204201
// let's choose 1.5x the chunk size
205202
_min_array_size_for_chunking = (3 * ParGCArrayScanChunk / 2);
206203

@@ -317,7 +314,7 @@ void PSPromotionManager::process_array_chunk(PartialArrayState* state) {
317314
process_array_chunk_work<oop>(state->destination(), start, end);
318315
}
319316
// Release reference to state, now that we're done with it.
320-
_partial_array_state_allocator->release(_partial_array_state_allocator_index, state);
317+
_partial_array_state_allocator.release(state);
321318
}
322319

323320
void PSPromotionManager::push_objArray(oop old_obj, oop new_obj) {
@@ -331,11 +328,10 @@ void PSPromotionManager::push_objArray(oop old_obj, oop new_obj) {
331328
if (step._ncreate > 0) {
332329
TASKQUEUE_STATS_ONLY(++_arrays_chunked);
333330
PartialArrayState* state =
334-
_partial_array_state_allocator->allocate(_partial_array_state_allocator_index,
335-
old_obj, new_obj,
336-
step._index,
337-
array_length,
338-
step._ncreate);
331+
_partial_array_state_allocator.allocate(old_obj, new_obj,
332+
step._index,
333+
array_length,
334+
step._ncreate);
339335
for (uint i = 0; i < step._ncreate; ++i) {
340336
push_depth(ScannerTask(state));
341337
}

src/hotspot/share/gc/parallel/psPromotionManager.hpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "gc/parallel/psPromotionLAB.hpp"
2929
#include "gc/shared/copyFailedInfo.hpp"
3030
#include "gc/shared/gcTrace.hpp"
31+
#include "gc/shared/partialArrayState.hpp"
3132
#include "gc/shared/partialArrayTaskStepper.hpp"
3233
#include "gc/shared/preservedMarks.hpp"
3334
#include "gc/shared/stringdedup/stringDedup.hpp"
@@ -50,8 +51,6 @@
5051
class MutableSpace;
5152
class PSOldGen;
5253
class ParCompactionManager;
53-
class PartialArrayState;
54-
class PartialArrayStateAllocator;
5554

5655
class PSPromotionManager {
5756
friend class PSScavenge;
@@ -88,9 +87,9 @@ class PSPromotionManager {
8887

8988
uint _target_stack_size;
9089

91-
static PartialArrayStateAllocator* _partial_array_state_allocator;
90+
static PartialArrayStateManager* _partial_array_state_manager;
91+
PartialArrayStateAllocator _partial_array_state_allocator;
9292
PartialArrayTaskStepper _partial_array_stepper;
93-
uint _partial_array_state_allocator_index;
9493
uint _min_array_size_for_chunking;
9594

9695
PreservedMarks* _preserved_marks;

0 commit comments

Comments
 (0)