1/*
2 * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#ifndef SHARE_GC_CMS_PARNEWGENERATION_HPP
26#define SHARE_GC_CMS_PARNEWGENERATION_HPP
27
28#include "gc/cms/parOopClosures.hpp"
29#include "gc/serial/defNewGeneration.hpp"
30#include "gc/shared/copyFailedInfo.hpp"
31#include "gc/shared/gcTrace.hpp"
32#include "gc/shared/oopStorageParState.hpp"
33#include "gc/shared/plab.hpp"
34#include "gc/shared/preservedMarks.hpp"
35#include "gc/shared/taskqueue.hpp"
36#include "memory/padded.hpp"
37
38class ChunkArray;
39class CMSHeap;
40class ParScanWithoutBarrierClosure;
41class ParScanWithBarrierClosure;
42class ParRootScanWithoutBarrierClosure;
43class ParRootScanWithBarrierTwoGensClosure;
44class ParEvacuateFollowersClosure;
45class StrongRootsScope;
46
47// It would be better if these types could be kept local to the .cpp file,
48// but they must be here to allow ParScanClosure::do_oop_work to be defined
49// in genOopClosures.inline.hpp.
50
51typedef Padded<OopTaskQueue> ObjToScanQueue;
52typedef GenericTaskQueueSet<ObjToScanQueue, mtGC> ObjToScanQueueSet;
53
54class ParKeepAliveClosure: public DefNewGeneration::KeepAliveClosure {
55 private:
56 ParScanWeakRefClosure* _par_cl;
57 protected:
58 template <class T> void do_oop_work(T* p);
59 public:
60 ParKeepAliveClosure(ParScanWeakRefClosure* cl);
61 virtual void do_oop(oop* p);
62 virtual void do_oop(narrowOop* p);
63};
64
65// The state needed by thread performing parallel young-gen collection.
66class ParScanThreadState {
67 friend class ParScanThreadStateSet;
68 private:
69 ObjToScanQueue *_work_queue;
70 Stack<oop, mtGC>* const _overflow_stack;
71 PreservedMarks* const _preserved_marks;
72
73 PLAB _to_space_alloc_buffer;
74
75 ParScanWithoutBarrierClosure _to_space_closure; // scan_without_gc_barrier
76 ParScanWithBarrierClosure _old_gen_closure; // scan_with_gc_barrier
77 ParRootScanWithoutBarrierClosure _to_space_root_closure; // scan_root_without_gc_barrier
78 // Will be passed to process_roots to set its generation.
79 ParRootScanWithBarrierTwoGensClosure _older_gen_closure;
80 // This closure will always be bound to the old gen; it will be used
81 // in evacuate_followers.
82 ParRootScanWithBarrierTwoGensClosure _old_gen_root_closure; // scan_old_root_with_gc_barrier
83 ParEvacuateFollowersClosure _evacuate_followers;
84 DefNewGeneration::IsAliveClosure _is_alive_closure;
85 ParScanWeakRefClosure _scan_weak_ref_closure;
86 ParKeepAliveClosure _keep_alive_closure;
87
88 Space* _to_space;
89 Space* to_space() { return _to_space; }
90
91 ParNewGeneration* _young_gen;
92 ParNewGeneration* young_gen() const { return _young_gen; }
93
94 Generation* _old_gen;
95 Generation* old_gen() { return _old_gen; }
96
97 HeapWord *_young_old_boundary;
98
99 int _thread_num;
100 AgeTable _ageTable;
101
102 bool _to_space_full;
103
104#if TASKQUEUE_STATS
105 size_t _term_attempts;
106 size_t _overflow_refills;
107 size_t _overflow_refill_objs;
108#endif // TASKQUEUE_STATS
109
110 // Stats for promotion failure
111 PromotionFailedInfo _promotion_failed_info;
112
113 // Timing numbers.
114 double _start;
115 double _start_strong_roots;
116 double _strong_roots_time;
117 double _start_term;
118 double _term_time;
119
120 // Helper for trim_queues. Scans subset of an array and makes
121 // remainder available for work stealing.
122 void scan_partial_array_and_push_remainder(oop obj);
123
124 // In support of CMS' parallel rescan of survivor space.
125 ChunkArray* _survivor_chunk_array;
126 ChunkArray* survivor_chunk_array() { return _survivor_chunk_array; }
127
128 void record_survivor_plab(HeapWord* plab_start, size_t plab_word_size);
129
130 ParScanThreadState(Space* to_space_, ParNewGeneration* gen_,
131 Generation* old_gen_, int thread_num_,
132 ObjToScanQueueSet* work_queue_set_,
133 Stack<oop, mtGC>* overflow_stacks_,
134 PreservedMarks* preserved_marks_,
135 size_t desired_plab_sz_,
136 TaskTerminator& term_);
137
138 public:
139 AgeTable* age_table() {return &_ageTable;}
140
141 ObjToScanQueue* work_queue() { return _work_queue; }
142
143 PreservedMarks* preserved_marks() const { return _preserved_marks; }
144
145 PLAB* to_space_alloc_buffer() {
146 return &_to_space_alloc_buffer;
147 }
148
149 ParEvacuateFollowersClosure& evacuate_followers_closure() { return _evacuate_followers; }
150 DefNewGeneration::IsAliveClosure& is_alive_closure() { return _is_alive_closure; }
151 ParScanWeakRefClosure& scan_weak_ref_closure() { return _scan_weak_ref_closure; }
152 ParKeepAliveClosure& keep_alive_closure() { return _keep_alive_closure; }
153 ParScanClosure& older_gen_closure() { return _older_gen_closure; }
154 ParRootScanWithoutBarrierClosure& to_space_root_closure() { return _to_space_root_closure; };
155
156 // Decrease queue size below "max_size".
157 void trim_queues(int max_size);
158
159 // Private overflow stack usage
160 Stack<oop, mtGC>* overflow_stack() { return _overflow_stack; }
161 bool take_from_overflow_stack();
162 void push_on_overflow_stack(oop p);
163
164 // Is new_obj a candidate for scan_partial_array_and_push_remainder method.
165 inline bool should_be_partially_scanned(oop new_obj, oop old_obj) const;
166
167 int thread_num() { return _thread_num; }
168
169 // Allocate a to-space block of size "sz", or else return NULL.
170 HeapWord* alloc_in_to_space_slow(size_t word_sz);
171
172 inline HeapWord* alloc_in_to_space(size_t word_sz);
173
174 HeapWord* young_old_boundary() { return _young_old_boundary; }
175
176 void set_young_old_boundary(HeapWord *boundary) {
177 _young_old_boundary = boundary;
178 }
179
180 // Undo the most recent allocation ("obj", of "word_sz").
181 void undo_alloc_in_to_space(HeapWord* obj, size_t word_sz);
182
183 // Promotion failure stats
184 void register_promotion_failure(size_t sz) {
185 _promotion_failed_info.register_copy_failure(sz);
186 }
187 PromotionFailedInfo& promotion_failed_info() {
188 return _promotion_failed_info;
189 }
190 bool promotion_failed() {
191 return _promotion_failed_info.has_failed();
192 }
193 void print_promotion_failure_size();
194
195#if TASKQUEUE_STATS
196 TaskQueueStats & taskqueue_stats() const { return _work_queue->stats; }
197
198 size_t term_attempts() const { return _term_attempts; }
199 size_t overflow_refills() const { return _overflow_refills; }
200 size_t overflow_refill_objs() const { return _overflow_refill_objs; }
201
202 void note_term_attempt() { ++_term_attempts; }
203 void note_overflow_refill(size_t objs) {
204 ++_overflow_refills; _overflow_refill_objs += objs;
205 }
206
207 void reset_stats();
208#endif // TASKQUEUE_STATS
209
210 void start_strong_roots() {
211 _start_strong_roots = os::elapsedTime();
212 }
213 void end_strong_roots() {
214 _strong_roots_time += (os::elapsedTime() - _start_strong_roots);
215 }
216 double strong_roots_time() const { return _strong_roots_time; }
217 void start_term_time() {
218 TASKQUEUE_STATS_ONLY(note_term_attempt());
219 _start_term = os::elapsedTime();
220 }
221 void end_term_time() {
222 _term_time += (os::elapsedTime() - _start_term);
223 }
224 double term_time() const { return _term_time; }
225
226 double elapsed_time() const {
227 return os::elapsedTime() - _start;
228 }
229};
230
231class ParNewGenTask: public AbstractGangTask {
232 private:
233 ParNewGeneration* _young_gen;
234 Generation* _old_gen;
235 HeapWord* _young_old_boundary;
236 class ParScanThreadStateSet* _state_set;
237 StrongRootsScope* _strong_roots_scope;
238
239public:
240 ParNewGenTask(ParNewGeneration* young_gen,
241 Generation* old_gen,
242 HeapWord* young_old_boundary,
243 ParScanThreadStateSet* state_set,
244 StrongRootsScope* strong_roots_scope);
245
246 HeapWord* young_old_boundary() { return _young_old_boundary; }
247
248 void work(uint worker_id);
249};
250
251class KeepAliveClosure: public DefNewGeneration::KeepAliveClosure {
252 protected:
253 template <class T> void do_oop_work(T* p);
254 public:
255 KeepAliveClosure(ScanWeakRefClosure* cl);
256 virtual void do_oop(oop* p);
257 virtual void do_oop(narrowOop* p);
258};
259
260template <typename OopClosureType1, typename OopClosureType2>
261class EvacuateFollowersClosureGeneral: public VoidClosure {
262 private:
263 CMSHeap* _heap;
264 OopClosureType1* _scan_cur_or_nonheap;
265 OopClosureType2* _scan_older;
266 public:
267 EvacuateFollowersClosureGeneral(CMSHeap* heap,
268 OopClosureType1* cur,
269 OopClosureType2* older);
270 virtual void do_void();
271};
272
273// Closure for scanning ParNewGeneration.
274// Same as ScanClosure, except does parallel GC barrier.
275class ScanClosureWithParBarrier: public OopsInClassLoaderDataOrGenClosure {
276 private:
277 ParNewGeneration* _g;
278 HeapWord* _boundary;
279 bool _gc_barrier;
280
281 template <class T> void do_oop_work(T* p);
282
283 public:
284 ScanClosureWithParBarrier(ParNewGeneration* g, bool gc_barrier);
285 virtual void do_oop(oop* p);
286 virtual void do_oop(narrowOop* p);
287};
288
289// Implements AbstractRefProcTaskExecutor for ParNew.
290class ParNewRefProcTaskExecutor: public AbstractRefProcTaskExecutor {
291 private:
292 ParNewGeneration& _young_gen;
293 Generation& _old_gen;
294 ParScanThreadStateSet& _state_set;
295 public:
296 ParNewRefProcTaskExecutor(ParNewGeneration& young_gen,
297 Generation& old_gen,
298 ParScanThreadStateSet& state_set)
299 : _young_gen(young_gen), _old_gen(old_gen), _state_set(state_set)
300 { }
301
302 // Executes a task using worker threads.
303 virtual void execute(ProcessTask& task, uint ergo_workers);
304 // Switch to single threaded mode.
305 virtual void set_single_threaded_mode();
306};
307
308
309// A Generation that does parallel young-gen collection.
310
311class ParNewGeneration: public DefNewGeneration {
312 friend class ParNewGenTask;
313 friend class ParNewRefProcTask;
314 friend class ParNewRefProcTaskExecutor;
315 friend class ParScanThreadStateSet;
316 friend class ParEvacuateFollowersClosure;
317
318 private:
319 // The per-worker-thread work queues
320 ObjToScanQueueSet* _task_queues;
321
322 // Per-worker-thread local overflow stacks
323 Stack<oop, mtGC>* _overflow_stacks;
324
325 // Desired size of survivor space plab's
326 PLABStats _plab_stats;
327
328 // A list of from-space images of to-be-scanned objects, threaded through
329 // klass-pointers (klass information already copied to the forwarded
330 // image.) Manipulated with CAS.
331 oopDesc* volatile _overflow_list;
332 NOT_PRODUCT(ssize_t _num_par_pushes;)
333
334 // This closure is used by the reference processor to filter out
335 // references to live referent.
336 DefNewGeneration::IsAliveClosure _is_alive_closure;
337
338 // GC tracer that should be used during collection.
339 ParNewTracer _gc_tracer;
340
341 static oop real_forwardee_slow(oop obj);
342 static void waste_some_time();
343
344 void handle_promotion_failed(CMSHeap* gch, ParScanThreadStateSet& thread_state_set);
345
346 protected:
347
348 void restore_preserved_marks();
349
350 public:
351 ParNewGeneration(ReservedSpace rs,
352 size_t initial_byte_size,
353 size_t min_byte_size,
354 size_t max_byte_size);
355
356 ~ParNewGeneration() {
357 for (uint i = 0; i < ParallelGCThreads; i++)
358 delete _task_queues->queue(i);
359
360 delete _task_queues;
361 }
362
363 virtual void ref_processor_init();
364 virtual Generation::Name kind() { return Generation::ParNew; }
365 virtual const char* name() const;
366 virtual const char* short_name() const { return "ParNew"; }
367
368 // override
369 virtual bool refs_discovery_is_mt() const {
370 return ParallelGCThreads > 1;
371 }
372
373 // Make the collection virtual.
374 virtual void collect(bool full,
375 bool clear_all_soft_refs,
376 size_t size,
377 bool is_tlab);
378
379 // This needs to be visible to the closure function.
380 // "obj" is the object to be copied, "m" is a recent value of its mark
381 // that must not contain a forwarding pointer (though one might be
382 // inserted in "obj"s mark word by a parallel thread).
383 oop copy_to_survivor_space(ParScanThreadState* par_scan_state,
384 oop obj, size_t obj_sz, markOop m);
385
386 // in support of testing overflow code
387 NOT_PRODUCT(int _overflow_counter;)
388 NOT_PRODUCT(bool should_simulate_overflow();)
389
390 // Accessor for overflow list
391 oop overflow_list() { return _overflow_list; }
392
393 // Push the given (from-space) object on the global overflow list.
394 void push_on_overflow_list(oop from_space_obj, ParScanThreadState* par_scan_state);
395
396 // If the global overflow list is non-empty, move some tasks from it
397 // onto "work_q" (which need not be empty). No more than 1/4 of the
398 // available space on "work_q" is used.
399 bool take_from_overflow_list(ParScanThreadState* par_scan_state);
400 bool take_from_overflow_list_work(ParScanThreadState* par_scan_state);
401
402 // The task queues to be used by parallel GC threads.
403 ObjToScanQueueSet* task_queues() {
404 return _task_queues;
405 }
406
407 PLABStats* plab_stats() {
408 return &_plab_stats;
409 }
410
411 size_t desired_plab_sz();
412
413 const ParNewTracer* gc_tracer() const {
414 return &_gc_tracer;
415 }
416
417 static oop real_forwardee(oop obj);
418};
419
420#endif // SHARE_GC_CMS_PARNEWGENERATION_HPP
421