1 /*
2 * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
3 * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 #ifndef SHARE_GC_PARALLEL_PSCOMPACTIONMANAGERNEW_HPP
27 #define SHARE_GC_PARALLEL_PSCOMPACTIONMANAGERNEW_HPP
28
29 #include "classfile/classLoaderData.hpp"
30 #include "gc/parallel/psParallelCompactNew.hpp"
31 #include "gc/shared/partialArraySplitter.hpp"
32 #include "gc/shared/partialArrayTaskStats.hpp"
33 #include "gc/shared/partialArrayState.hpp"
34 #include "gc/shared/preservedMarks.hpp"
35 #include "gc/shared/stringdedup/stringDedup.hpp"
36 #include "gc/shared/taskqueue.hpp"
37 #include "gc/shared/taskTerminator.hpp"
38 #include "memory/allocation.hpp"
39 #include "utilities/stack.hpp"
40
41 class MutableSpace;
42 class PSOldGen;
43 class ParCompactionManagerNew;
44 class ObjectStartArray;
45 class ParMarkBitMap;
46
47 class PCMarkAndPushClosureNew: public ClaimMetadataVisitingOopIterateClosure {
48 ParCompactionManagerNew* _compaction_manager;
49
50 template <typename T> void do_oop_work(T* p);
51 public:
52 PCMarkAndPushClosureNew(ParCompactionManagerNew* cm, ReferenceProcessor* rp) :
53 ClaimMetadataVisitingOopIterateClosure(ClassLoaderData::_claim_stw_fullgc_mark, rp),
54 _compaction_manager(cm) { }
55
56 void do_oop(oop* p) final { do_oop_work(p); }
57 void do_oop(narrowOop* p) final { do_oop_work(p); }
58 };
59
60 class ParCompactionManagerNew : public CHeapObj<mtGC> {
61 friend class MarkFromRootsTaskNew;
62 friend class ParallelCompactRefProcProxyTaskNew;
63 friend class ParallelScavengeRefProcProxyTask;
64 friend class ParMarkBitMap;
65 friend class PSParallelCompactNew;
66 friend class PCAddThreadRootsMarkingTaskClosureNew;
67
68 private:
69 typedef OverflowTaskQueue<ScannerTask, mtGC> PSMarkTaskQueue;
70 typedef GenericTaskQueueSet<PSMarkTaskQueue, mtGC> PSMarkTasksQueueSet;
71
72 static ParCompactionManagerNew** _manager_array;
73 static PSMarkTasksQueueSet* _marking_stacks;
74 static ObjectStartArray* _start_array;
75 static PSOldGen* _old_gen;
76
77 static PartialArrayStateManager* _partial_array_state_manager;
78 PartialArraySplitter _partial_array_splitter;
79
80 PSMarkTaskQueue _marking_stack;
81
82 PCMarkAndPushClosureNew _mark_and_push_closure;
83
84 static PreservedMarksSet* _preserved_marks_set;
85 PreservedMarks* _preserved_marks;
86
87 static ParMarkBitMap* _mark_bitmap;
88
89 StringDedup::Requests _string_dedup_requests;
90
91 static PSOldGen* old_gen() { return _old_gen; }
92 static ObjectStartArray* start_array() { return _start_array; }
93 static PSMarkTasksQueueSet* marking_stacks() { return _marking_stacks; }
94
95 static void initialize(ParMarkBitMap* mbm);
96
97 ParCompactionManagerNew(PreservedMarks* preserved_marks,
98 ReferenceProcessor* ref_processor,
99 uint parallel_gc_threads);
100
101 inline PSMarkTaskQueue* marking_stack() { return &_marking_stack; }
102 inline void push(PartialArrayState* stat);
103 void push_objArray(oop obj);
104
105 #if TASKQUEUE_STATS
106 static void print_and_reset_taskqueue_stats();
107 PartialArrayTaskStats* partial_array_task_stats();
108 #endif // TASKQUEUE_STATS
109
110 public:
111 void flush_string_dedup_requests() {
112 _string_dedup_requests.flush();
113 }
114
115 static void flush_all_string_dedup_requests();
116
117 // Get the compaction manager when doing evacuation work from the VM thread.
118 // Simply use the first compaction manager here.
119 static ParCompactionManagerNew* get_vmthread_cm() { return _manager_array[0]; }
120
121 PreservedMarks* preserved_marks() const {
122 return _preserved_marks;
123 }
124
125 static ParMarkBitMap* mark_bitmap() { return _mark_bitmap; }
126
127 // Save for later processing. Must not fail.
128 inline void push(oop obj);
129
130 // Check mark and maybe push on marking stack.
131 template <typename T> inline void mark_and_push(T* p);
132
133 // Access function for compaction managers
134 static ParCompactionManagerNew* gc_thread_compaction_manager(uint index);
135
136 static bool steal(uint queue_num, ScannerTask& t);
137
138 // Process tasks remaining on marking stack
139 void follow_marking_stacks();
140 inline bool marking_stack_empty() const;
141
142 inline void follow_contents(const ScannerTask& task, bool stolen);
143 inline void follow_array(objArrayOop array, size_t start, size_t end);
144 void process_array_chunk(PartialArrayState* state, bool stolen);
145
146 class FollowStackClosure: public VoidClosure {
147 private:
148 ParCompactionManagerNew* _compaction_manager;
149 TaskTerminator* _terminator;
150 uint _worker_id;
151 public:
152 FollowStackClosure(ParCompactionManagerNew* cm, TaskTerminator* terminator, uint worker_id)
153 : _compaction_manager(cm), _terminator(terminator), _worker_id(worker_id) { }
154 void do_void() final;
155 };
156
157 // Called after marking.
158 static void verify_all_marking_stack_empty() NOT_DEBUG_RETURN;
159 };
160
161 bool ParCompactionManagerNew::marking_stack_empty() const {
162 return _marking_stack.is_empty();
163 }
164
165 #endif // SHARE_GC_PARALLEL_PSCOMPACTIONMANAGERNEW_HPP