216 void end_strong_roots() {
217 _strong_roots_time += (os::elapsedTime() - _start_strong_roots);
218 }
219 double strong_roots_time() const { return _strong_roots_time; }
220 void start_term_time() {
221 TASKQUEUE_STATS_ONLY(note_term_attempt());
222 _start_term = os::elapsedTime();
223 }
224 void end_term_time() {
225 _term_time += (os::elapsedTime() - _start_term);
226 }
227 double term_time() const { return _term_time; }
228
229 double elapsed_time() const {
230 return os::elapsedTime() - _start;
231 }
232 };
233
234 class ParNewGenTask: public AbstractGangTask {
235 private:
236 ParNewGeneration* _gen;
237 Generation* _old_gen;
238 HeapWord* _young_old_boundary;
239 class ParScanThreadStateSet* _state_set;
240
241 public:
242 ParNewGenTask(ParNewGeneration* gen,
243 Generation* old_gen,
244 HeapWord* young_old_boundary,
245 ParScanThreadStateSet* state_set);
246
247 HeapWord* young_old_boundary() { return _young_old_boundary; }
248
249 void work(uint worker_id);
250
251 // Reset the terminator in ParScanThreadStateSet for
252 // "active_workers" threads.
253 virtual void set_for_termination(uint active_workers);
254 };
255
256 class KeepAliveClosure: public DefNewGeneration::KeepAliveClosure {
257 protected:
258 template <class T> void do_oop_work(T* p);
259 public:
260 KeepAliveClosure(ScanWeakRefClosure* cl);
261 virtual void do_oop(oop* p);
262 virtual void do_oop(narrowOop* p);
263 };
264
265 class EvacuateFollowersClosureGeneral: public VoidClosure {
266 private:
267 GenCollectedHeap* _gch;
268 int _level;
269 OopsInGenClosure* _scan_cur_or_nonheap;
270 OopsInGenClosure* _scan_older;
271 public:
272 EvacuateFollowersClosureGeneral(GenCollectedHeap* gch, int level,
273 OopsInGenClosure* cur,
274 OopsInGenClosure* older);
275 virtual void do_void();
276 };
277
278 // Closure for scanning ParNewGeneration.
279 // Same as ScanClosure, except does parallel GC barrier.
280 class ScanClosureWithParBarrier: public ScanClosure {
281 protected:
282 template <class T> void do_oop_work(T* p);
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.
290 class ParNewRefProcTaskExecutor: public AbstractRefProcTaskExecutor {
291 private:
292 ParNewGeneration& _generation;
293 ParScanThreadStateSet& _state_set;
294 public:
295 ParNewRefProcTaskExecutor(ParNewGeneration& generation,
296 ParScanThreadStateSet& state_set)
297 : _generation(generation), _state_set(state_set)
298 { }
299
300 // Executes a task using worker threads.
301 virtual void execute(ProcessTask& task);
302 virtual void execute(EnqueueTask& task);
303 // Switch to single threaded mode.
304 virtual void set_single_threaded_mode();
305 };
306
307
308 // A Generation that does parallel young-gen collection.
309
310 class ParNewGeneration: public DefNewGeneration {
311 friend class ParNewGenTask;
312 friend class ParNewRefProcTask;
313 friend class ParNewRefProcTaskExecutor;
314 friend class ParScanThreadStateSet;
315 friend class ParEvacuateFollowersClosure;
316
317 private:
337 // GC tracer that should be used during collection.
338 ParNewTracer _gc_tracer;
339
340 static oop real_forwardee_slow(oop obj);
341 static void waste_some_time();
342
343 // Preserve the mark of "obj", if necessary, in preparation for its mark
344 // word being overwritten with a self-forwarding-pointer.
345 void preserve_mark_if_necessary(oop obj, markOop m);
346
347 void handle_promotion_failed(GenCollectedHeap* gch, ParScanThreadStateSet& thread_state_set);
348
349 protected:
350
351 bool _survivor_overflow;
352
353 bool survivor_overflow() { return _survivor_overflow; }
354 void set_survivor_overflow(bool v) { _survivor_overflow = v; }
355
356 public:
357 ParNewGeneration(ReservedSpace rs, size_t initial_byte_size, int level);
358
359 ~ParNewGeneration() {
360 for (uint i = 0; i < ParallelGCThreads; i++)
361 delete _task_queues->queue(i);
362
363 delete _task_queues;
364 }
365
366 virtual void ref_processor_init();
367 virtual Generation::Name kind() { return Generation::ParNew; }
368 virtual const char* name() const;
369 virtual const char* short_name() const { return "ParNew"; }
370
371 // override
372 virtual bool refs_discovery_is_mt() const {
373 return ParallelGCThreads > 1;
374 }
375
376 // Make the collection virtual.
377 virtual void collect(bool full,
|
216 void end_strong_roots() {
217 _strong_roots_time += (os::elapsedTime() - _start_strong_roots);
218 }
219 double strong_roots_time() const { return _strong_roots_time; }
220 void start_term_time() {
221 TASKQUEUE_STATS_ONLY(note_term_attempt());
222 _start_term = os::elapsedTime();
223 }
224 void end_term_time() {
225 _term_time += (os::elapsedTime() - _start_term);
226 }
227 double term_time() const { return _term_time; }
228
229 double elapsed_time() const {
230 return os::elapsedTime() - _start;
231 }
232 };
233
234 class ParNewGenTask: public AbstractGangTask {
235 private:
236 ParNewGeneration* _young_gen;
237 Generation* _old_gen;
238 HeapWord* _young_old_boundary;
239 class ParScanThreadStateSet* _state_set;
240
241 public:
242 ParNewGenTask(ParNewGeneration* young_gen,
243 Generation* old_gen,
244 HeapWord* young_old_boundary,
245 ParScanThreadStateSet* state_set);
246
247 HeapWord* young_old_boundary() { return _young_old_boundary; }
248
249 void work(uint worker_id);
250
251 // Reset the terminator in ParScanThreadStateSet for
252 // "active_workers" threads.
253 virtual void set_for_termination(uint active_workers);
254 };
255
256 class KeepAliveClosure: public DefNewGeneration::KeepAliveClosure {
257 protected:
258 template <class T> void do_oop_work(T* p);
259 public:
260 KeepAliveClosure(ScanWeakRefClosure* cl);
261 virtual void do_oop(oop* p);
262 virtual void do_oop(narrowOop* p);
263 };
264
265 class EvacuateFollowersClosureGeneral: public VoidClosure {
266 private:
267 GenCollectedHeap* _gch;
268 OopsInGenClosure* _scan_cur_or_nonheap;
269 OopsInGenClosure* _scan_older;
270 public:
271 EvacuateFollowersClosureGeneral(GenCollectedHeap* gch,
272 OopsInGenClosure* cur,
273 OopsInGenClosure* older);
274 virtual void do_void();
275 };
276
277 // Closure for scanning ParNewGeneration.
278 // Same as ScanClosure, except does parallel GC barrier.
279 class ScanClosureWithParBarrier: public ScanClosure {
280 protected:
281 template <class T> void do_oop_work(T* p);
282 public:
283 ScanClosureWithParBarrier(ParNewGeneration* g, bool gc_barrier);
284 virtual void do_oop(oop* p);
285 virtual void do_oop(narrowOop* p);
286 };
287
288 // Implements AbstractRefProcTaskExecutor for ParNew.
289 class ParNewRefProcTaskExecutor: public AbstractRefProcTaskExecutor {
290 private:
291 ParNewGeneration& _young_gen;
292 Generation& _old_gen;
293 ParScanThreadStateSet& _state_set;
294 public:
295 ParNewRefProcTaskExecutor(ParNewGeneration& young_gen,
296 Generation& old_gen,
297 ParScanThreadStateSet& state_set)
298 : _young_gen(young_gen), _old_gen(old_gen), _state_set(state_set)
299 { }
300
301 // Executes a task using worker threads.
302 virtual void execute(ProcessTask& task);
303 virtual void execute(EnqueueTask& task);
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
311 class 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:
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 // Preserve the mark of "obj", if necessary, in preparation for its mark
345 // word being overwritten with a self-forwarding-pointer.
346 void preserve_mark_if_necessary(oop obj, markOop m);
347
348 void handle_promotion_failed(GenCollectedHeap* gch, ParScanThreadStateSet& thread_state_set);
349
350 protected:
351
352 bool _survivor_overflow;
353
354 bool survivor_overflow() { return _survivor_overflow; }
355 void set_survivor_overflow(bool v) { _survivor_overflow = v; }
356
357 public:
358 ParNewGeneration(ReservedSpace rs, size_t initial_byte_size);
359
360 ~ParNewGeneration() {
361 for (uint i = 0; i < ParallelGCThreads; i++)
362 delete _task_queues->queue(i);
363
364 delete _task_queues;
365 }
366
367 virtual void ref_processor_init();
368 virtual Generation::Name kind() { return Generation::ParNew; }
369 virtual const char* name() const;
370 virtual const char* short_name() const { return "ParNew"; }
371
372 // override
373 virtual bool refs_discovery_is_mt() const {
374 return ParallelGCThreads > 1;
375 }
376
377 // Make the collection virtual.
378 virtual void collect(bool full,
|