< prev index next >

src/share/vm/gc/g1/g1CollectedHeap.cpp

Print this page
rev 8789 : imported patch 8073052-Rename-and-clean-up-the-allocation-manager-hierarchy-in-g1Allocator
rev 8793 : 8133043: Clean up code related to termination stats printing
Summary: Reformat termination stats related code to make it look more similar to existing code.
Reviewed-by:


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 


< prev index next >