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