4432 // Tell the closure that this klass is the Klass to scavenge
4433 // and is the one to dirty if oops are left pointing into the young gen.
4434 _closure->set_scanned_klass(klass);
4435
4436 klass->oops_do(_closure);
4437
4438 _closure->set_scanned_klass(NULL);
4439 }
4440 _count++;
4441 }
4442 };
4443
4444 class G1ParTask : public AbstractGangTask {
4445 protected:
4446 G1CollectedHeap* _g1h;
4447 RefToScanQueueSet *_queues;
4448 G1RootProcessor* _root_processor;
4449 ParallelTaskTerminator _terminator;
4450 uint _n_workers;
4451
4452 Mutex _stats_lock;
4453 Mutex* stats_lock() { return &_stats_lock; }
4454
4455 public:
4456 G1ParTask(G1CollectedHeap* g1h, RefToScanQueueSet *task_queues, G1RootProcessor* root_processor, uint n_workers)
4457 : AbstractGangTask("G1 collection"),
4458 _g1h(g1h),
4459 _queues(task_queues),
4460 _root_processor(root_processor),
4461 _terminator(n_workers, _queues),
4462 _n_workers(n_workers),
4463 _stats_lock(Mutex::leaf, "parallel G1 stats lock", true)
4464 {}
4465
4466 RefToScanQueueSet* queues() { return _queues; }
4467
4468 RefToScanQueue *work_queue(int i) {
4469 return queues()->queue(i);
4470 }
4471
4472 ParallelTaskTerminator* terminator() { return &_terminator; }
4473
4474 // Helps out with CLD processing.
4475 //
4476 // During InitialMark we need to:
4477 // 1) Scavenge all CLDs for the young GC.
4478 // 2) Mark all objects directly reachable from strong CLDs.
4479 template <G1Mark do_mark_object>
4480 class G1CLDClosure : public CLDClosure {
4481 G1ParCopyClosure<G1BarrierNone, do_mark_object>* _oop_closure;
4482 G1ParCopyClosure<G1BarrierKlass, do_mark_object> _oop_in_klass_closure;
4483 G1KlassScanClosure _klass_in_cld_closure;
4570 G1ParPushHeapRSClosure push_heap_rs_cl(_g1h, &pss);
4571 _root_processor->scan_remembered_sets(&push_heap_rs_cl,
4572 weak_root_cl,
4573 worker_id);
4574 pss.end_strong_roots();
4575
4576 {
4577 double start = os::elapsedTime();
4578 G1ParEvacuateFollowersClosure evac(_g1h, &pss, _queues, &_terminator);
4579 evac.do_void();
4580 double elapsed_sec = os::elapsedTime() - start;
4581 double term_sec = pss.term_time();
4582 _g1h->g1_policy()->phase_times()->add_time_secs(G1GCPhaseTimes::ObjCopy, worker_id, elapsed_sec - term_sec);
4583 _g1h->g1_policy()->phase_times()->record_time_secs(G1GCPhaseTimes::Termination, worker_id, term_sec);
4584 _g1h->g1_policy()->phase_times()->record_thread_work_item(G1GCPhaseTimes::Termination, worker_id, pss.term_attempts());
4585 }
4586 _g1h->g1_policy()->record_thread_age_table(pss.age_table());
4587 _g1h->update_surviving_young_words(pss.surviving_young_words()+1);
4588
4589 if (PrintTerminationStats) {
4590 MutexLocker x(stats_lock());
4591 pss.print_termination_stats(worker_id);
4592 }
4593
4594 assert(pss.queue_is_empty(), "should be empty");
4595
4596 // Close the inner scope so that the ResourceMark and HandleMark
4597 // destructors are executed here and are included as part of the
4598 // "GC Worker Time".
4599 }
4600 _g1h->g1_policy()->phase_times()->record_time_secs(G1GCPhaseTimes::GCWorkerEnd, worker_id, os::elapsedTime());
4601 }
4602 };
4603
4604 class G1StringSymbolTableUnlinkTask : public AbstractGangTask {
4605 private:
4606 BoolObjectClosure* _is_alive;
4607 int _initial_string_table_size;
4608 int _initial_symbol_table_size;
4609
4610 bool _process_strings;
4611 int _strings_processed;
5487 // Disable the hot card cache.
5488 G1HotCardCache* hot_card_cache = _cg1r->hot_card_cache();
5489 hot_card_cache->reset_hot_cache_claimed_index();
5490 hot_card_cache->set_use_cache(false);
5491
5492 const uint n_workers = workers()->active_workers();
5493
5494 assert(dirty_card_queue_set().completed_buffers_num() == 0, "Should be empty");
5495 double start_par_time_sec = os::elapsedTime();
5496 double end_par_time_sec;
5497
5498 {
5499 G1RootProcessor root_processor(this, n_workers);
5500 G1ParTask g1_par_task(this, _task_queues, &root_processor, n_workers);
5501 // InitialMark needs claim bits to keep track of the marked-through CLDs.
5502 if (collector_state()->during_initial_mark_pause()) {
5503 ClassLoaderDataGraph::clear_claimed_marks();
5504 }
5505
5506 // The individual threads will set their evac-failure closures.
5507 if (PrintTerminationStats) G1ParScanThreadState::print_termination_stats_hdr();
5508
5509 workers()->run_task(&g1_par_task);
5510 end_par_time_sec = os::elapsedTime();
5511
5512 // Closing the inner scope will execute the destructor
5513 // for the G1RootProcessor object. We record the current
5514 // elapsed time before closing the scope so that time
5515 // taken for the destructor is NOT included in the
5516 // reported parallel time.
5517 }
5518
5519 G1GCPhaseTimes* phase_times = g1_policy()->phase_times();
5520
5521 double par_time_ms = (end_par_time_sec - start_par_time_sec) * 1000.0;
5522 phase_times->record_par_time(par_time_ms);
5523
5524 double code_root_fixup_time_ms =
5525 (os::elapsedTime() - end_par_time_sec) * 1000.0;
5526 phase_times->record_code_root_fixup_time(code_root_fixup_time_ms);
5527
|
4432 // Tell the closure that this klass is the Klass to scavenge
4433 // and is the one to dirty if oops are left pointing into the young gen.
4434 _closure->set_scanned_klass(klass);
4435
4436 klass->oops_do(_closure);
4437
4438 _closure->set_scanned_klass(NULL);
4439 }
4440 _count++;
4441 }
4442 };
4443
4444 class G1ParTask : public AbstractGangTask {
4445 protected:
4446 G1CollectedHeap* _g1h;
4447 RefToScanQueueSet *_queues;
4448 G1RootProcessor* _root_processor;
4449 ParallelTaskTerminator _terminator;
4450 uint _n_workers;
4451
4452 public:
4453 G1ParTask(G1CollectedHeap* g1h, RefToScanQueueSet *task_queues, G1RootProcessor* root_processor, uint n_workers)
4454 : AbstractGangTask("G1 collection"),
4455 _g1h(g1h),
4456 _queues(task_queues),
4457 _root_processor(root_processor),
4458 _terminator(n_workers, _queues),
4459 _n_workers(n_workers)
4460 {}
4461
4462 RefToScanQueueSet* queues() { return _queues; }
4463
4464 RefToScanQueue *work_queue(int i) {
4465 return queues()->queue(i);
4466 }
4467
4468 ParallelTaskTerminator* terminator() { return &_terminator; }
4469
4470 // Helps out with CLD processing.
4471 //
4472 // During InitialMark we need to:
4473 // 1) Scavenge all CLDs for the young GC.
4474 // 2) Mark all objects directly reachable from strong CLDs.
4475 template <G1Mark do_mark_object>
4476 class G1CLDClosure : public CLDClosure {
4477 G1ParCopyClosure<G1BarrierNone, do_mark_object>* _oop_closure;
4478 G1ParCopyClosure<G1BarrierKlass, do_mark_object> _oop_in_klass_closure;
4479 G1KlassScanClosure _klass_in_cld_closure;
4566 G1ParPushHeapRSClosure push_heap_rs_cl(_g1h, &pss);
4567 _root_processor->scan_remembered_sets(&push_heap_rs_cl,
4568 weak_root_cl,
4569 worker_id);
4570 pss.end_strong_roots();
4571
4572 {
4573 double start = os::elapsedTime();
4574 G1ParEvacuateFollowersClosure evac(_g1h, &pss, _queues, &_terminator);
4575 evac.do_void();
4576 double elapsed_sec = os::elapsedTime() - start;
4577 double term_sec = pss.term_time();
4578 _g1h->g1_policy()->phase_times()->add_time_secs(G1GCPhaseTimes::ObjCopy, worker_id, elapsed_sec - term_sec);
4579 _g1h->g1_policy()->phase_times()->record_time_secs(G1GCPhaseTimes::Termination, worker_id, term_sec);
4580 _g1h->g1_policy()->phase_times()->record_thread_work_item(G1GCPhaseTimes::Termination, worker_id, pss.term_attempts());
4581 }
4582 _g1h->g1_policy()->record_thread_age_table(pss.age_table());
4583 _g1h->update_surviving_young_words(pss.surviving_young_words()+1);
4584
4585 if (PrintTerminationStats) {
4586 MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
4587 pss.print_termination_stats();
4588 }
4589
4590 assert(pss.queue_is_empty(), "should be empty");
4591
4592 // Close the inner scope so that the ResourceMark and HandleMark
4593 // destructors are executed here and are included as part of the
4594 // "GC Worker Time".
4595 }
4596 _g1h->g1_policy()->phase_times()->record_time_secs(G1GCPhaseTimes::GCWorkerEnd, worker_id, os::elapsedTime());
4597 }
4598 };
4599
4600 class G1StringSymbolTableUnlinkTask : public AbstractGangTask {
4601 private:
4602 BoolObjectClosure* _is_alive;
4603 int _initial_string_table_size;
4604 int _initial_symbol_table_size;
4605
4606 bool _process_strings;
4607 int _strings_processed;
5483 // Disable the hot card cache.
5484 G1HotCardCache* hot_card_cache = _cg1r->hot_card_cache();
5485 hot_card_cache->reset_hot_cache_claimed_index();
5486 hot_card_cache->set_use_cache(false);
5487
5488 const uint n_workers = workers()->active_workers();
5489
5490 assert(dirty_card_queue_set().completed_buffers_num() == 0, "Should be empty");
5491 double start_par_time_sec = os::elapsedTime();
5492 double end_par_time_sec;
5493
5494 {
5495 G1RootProcessor root_processor(this, n_workers);
5496 G1ParTask g1_par_task(this, _task_queues, &root_processor, n_workers);
5497 // InitialMark needs claim bits to keep track of the marked-through CLDs.
5498 if (collector_state()->during_initial_mark_pause()) {
5499 ClassLoaderDataGraph::clear_claimed_marks();
5500 }
5501
5502 // The individual threads will set their evac-failure closures.
5503 if (PrintTerminationStats) {
5504 G1ParScanThreadState::print_termination_stats_hdr();
5505 }
5506
5507 workers()->run_task(&g1_par_task);
5508 end_par_time_sec = os::elapsedTime();
5509
5510 // Closing the inner scope will execute the destructor
5511 // for the G1RootProcessor object. We record the current
5512 // elapsed time before closing the scope so that time
5513 // taken for the destructor is NOT included in the
5514 // reported parallel time.
5515 }
5516
5517 G1GCPhaseTimes* phase_times = g1_policy()->phase_times();
5518
5519 double par_time_ms = (end_par_time_sec - start_par_time_sec) * 1000.0;
5520 phase_times->record_par_time(par_time_ms);
5521
5522 double code_root_fixup_time_ms =
5523 (os::elapsedTime() - end_par_time_sec) * 1000.0;
5524 phase_times->record_code_root_fixup_time(code_root_fixup_time_ms);
5525
|