< prev index next >

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

Print this page




4469    public:
4470     G1CLDClosure(G1ParCopyClosure<G1BarrierNone, do_mark_object>* oop_closure,
4471                  bool only_young, bool claim)
4472         : _oop_closure(oop_closure),
4473           _oop_in_klass_closure(oop_closure->g1(),
4474                                 oop_closure->pss(),
4475                                 oop_closure->rp()),
4476           _klass_in_cld_closure(&_oop_in_klass_closure, only_young),
4477           _claim(claim) {
4478 
4479     }
4480 
4481     void do_cld(ClassLoaderData* cld) {
4482       cld->oops_do(_oop_closure, &_klass_in_cld_closure, _claim);
4483     }
4484   };
4485 
4486   void work(uint worker_id) {
4487     if (worker_id >= _n_workers) return;  // no work needed this round
4488 
4489     _g1h->g1_policy()->phase_times()->record_time(G1GCPhaseTimes::GCWorkerStart, worker_id, os::elapsedTime());
4490 
4491     {
4492       ResourceMark rm;
4493       HandleMark   hm;
4494 
4495       ReferenceProcessor*             rp = _g1h->ref_processor_stw();
4496 
4497       G1ParScanThreadState            pss(_g1h, worker_id, rp);
4498       G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, rp);
4499 
4500       pss.set_evac_failure_closure(&evac_failure_cl);
4501 
4502       bool only_young = _g1h->g1_policy()->gcs_are_young();
4503 
4504       // Non-IM young GC.
4505       G1ParCopyClosure<G1BarrierNone, G1MarkNone>             scan_only_root_cl(_g1h, &pss, rp);
4506       G1CLDClosure<G1MarkNone>                                scan_only_cld_cl(&scan_only_root_cl,
4507                                                                                only_young, // Only process dirty klasses.
4508                                                                                false);     // No need to claim CLDs.
4509       // IM young GC.


4551 
4552       G1ParPushHeapRSClosure  push_heap_rs_cl(_g1h, &pss);
4553 
4554       pss.start_strong_roots();
4555       _g1h->g1_process_roots(strong_root_cl,
4556                              weak_root_cl,
4557                              &push_heap_rs_cl,
4558                              strong_cld_cl,
4559                              weak_cld_cl,
4560                              strong_code_cl,
4561                              worker_id);
4562 
4563       pss.end_strong_roots();
4564 
4565       {
4566         double start = os::elapsedTime();
4567         G1ParEvacuateFollowersClosure evac(_g1h, &pss, _queues, &_terminator);
4568         evac.do_void();
4569         double elapsed_sec = os::elapsedTime() - start;
4570         double term_sec = pss.term_time();
4571         _g1h->g1_policy()->phase_times()->add_time(G1GCPhaseTimes::ObjCopy, worker_id, elapsed_sec - term_sec);
4572         _g1h->g1_policy()->phase_times()->record_time(G1GCPhaseTimes::Termination, worker_id, term_sec);
4573         _g1h->g1_policy()->phase_times()->record_sub_count(G1GCPhaseTimes::Termination, worker_id, pss.term_attempts());
4574       }
4575       _g1h->g1_policy()->record_thread_age_table(pss.age_table());
4576       _g1h->update_surviving_young_words(pss.surviving_young_words()+1);
4577 
4578       if (PrintTerminationStats) {
4579         MutexLocker x(stats_lock());
4580         pss.print_termination_stats(worker_id);
4581       }
4582 
4583       assert(pss.queue_is_empty(), "should be empty");
4584 
4585       // Close the inner scope so that the ResourceMark and HandleMark
4586       // destructors are executed here and are included as part of the
4587       // "GC Worker Time".
4588     }
4589     _g1h->g1_policy()->phase_times()->record_time(G1GCPhaseTimes::GCWorkerEnd, worker_id, os::elapsedTime());
4590   }
4591 };
4592 
4593 // *** Common G1 Evacuation Stuff
4594 
4595 // This method is run in a GC worker.
4596 
4597 void
4598 G1CollectedHeap::
4599 g1_process_roots(OopClosure* scan_non_heap_roots,
4600                  OopClosure* scan_non_heap_weak_roots,
4601                  G1ParPushHeapRSClosure* scan_rs,
4602                  CLDClosure* scan_strong_clds,
4603                  CLDClosure* scan_weak_clds,
4604                  CodeBlobClosure* scan_strong_code,
4605                  uint worker_i) {
4606 
4607   // First scan the shared roots.
4608   double ext_roots_start = os::elapsedTime();
4609   double closure_app_time_sec = 0.0;


4631     // until they can be processed at the end of marking.
4632     ref_processor_cm()->weak_oops_do(&buf_scan_non_heap_roots);
4633   }
4634 
4635   if (trace_metadata) {
4636     // Barrier to make sure all workers passed
4637     // the strong CLD and strong nmethods phases.
4638     active_strong_roots_scope()->wait_until_all_workers_done_with_threads(n_par_threads());
4639 
4640     // Now take the complement of the strong CLDs.
4641     ClassLoaderDataGraph::roots_cld_do(NULL, scan_weak_clds);
4642   }
4643 
4644   // Finish up any enqueued closure apps (attributed as object copy time).
4645   buf_scan_non_heap_roots.done();
4646   buf_scan_non_heap_weak_roots.done();
4647 
4648   double obj_copy_time_sec = buf_scan_non_heap_roots.closure_app_seconds()
4649       + buf_scan_non_heap_weak_roots.closure_app_seconds();
4650 
4651   g1_policy()->phase_times()->record_time(G1GCPhaseTimes::ObjCopy, worker_i, obj_copy_time_sec);
4652 
4653   double ext_root_time_sec = os::elapsedTime() - ext_roots_start - obj_copy_time_sec;
4654   g1_policy()->phase_times()->record_time(G1GCPhaseTimes::ExtRootScan, worker_i, ext_root_time_sec);
4655 
4656   // During conc marking we have to filter the per-thread SATB buffers
4657   // to make sure we remove any oops into the CSet (which will show up
4658   // as implicitly live).
4659   if (mark_in_progress() && !_process_strong_tasks->is_task_claimed(G1H_PS_filter_satb_buffers)) {
4660     G1GCPhaseTimesTracker x(g1_policy()->phase_times(), G1GCPhaseTimes::SATBFiltering, worker_i);

4661     JavaThread::satb_mark_queue_set().filter_thread_buffers();
4662   } else {
4663     g1_policy()->phase_times()->record_time(G1GCPhaseTimes::SATBFiltering, worker_i, 0.0);
4664   }
4665 
4666   // Now scan the complement of the collection set.
4667   G1CodeBlobClosure scavenge_cs_nmethods(scan_non_heap_weak_roots);
4668 
4669   g1_rem_set()->oops_into_collection_set_do(scan_rs, &scavenge_cs_nmethods, worker_i);
4670 
4671   _process_strong_tasks->all_tasks_completed();
4672 }
4673 
4674 class G1StringSymbolTableUnlinkTask : public AbstractGangTask {
4675 private:
4676   BoolObjectClosure* _is_alive;
4677   int _initial_string_table_size;
4678   int _initial_symbol_table_size;
4679 
4680   bool  _process_strings;
4681   int _strings_processed;
4682   int _strings_removed;
4683 




4469    public:
4470     G1CLDClosure(G1ParCopyClosure<G1BarrierNone, do_mark_object>* oop_closure,
4471                  bool only_young, bool claim)
4472         : _oop_closure(oop_closure),
4473           _oop_in_klass_closure(oop_closure->g1(),
4474                                 oop_closure->pss(),
4475                                 oop_closure->rp()),
4476           _klass_in_cld_closure(&_oop_in_klass_closure, only_young),
4477           _claim(claim) {
4478 
4479     }
4480 
4481     void do_cld(ClassLoaderData* cld) {
4482       cld->oops_do(_oop_closure, &_klass_in_cld_closure, _claim);
4483     }
4484   };
4485 
4486   void work(uint worker_id) {
4487     if (worker_id >= _n_workers) return;  // no work needed this round
4488 
4489     _g1h->g1_policy()->phase_times()->record_time_secs(G1GCPhaseTimes::GCWorkerStart, worker_id, os::elapsedTime());
4490 
4491     {
4492       ResourceMark rm;
4493       HandleMark   hm;
4494 
4495       ReferenceProcessor*             rp = _g1h->ref_processor_stw();
4496 
4497       G1ParScanThreadState            pss(_g1h, worker_id, rp);
4498       G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, rp);
4499 
4500       pss.set_evac_failure_closure(&evac_failure_cl);
4501 
4502       bool only_young = _g1h->g1_policy()->gcs_are_young();
4503 
4504       // Non-IM young GC.
4505       G1ParCopyClosure<G1BarrierNone, G1MarkNone>             scan_only_root_cl(_g1h, &pss, rp);
4506       G1CLDClosure<G1MarkNone>                                scan_only_cld_cl(&scan_only_root_cl,
4507                                                                                only_young, // Only process dirty klasses.
4508                                                                                false);     // No need to claim CLDs.
4509       // IM young GC.


4551 
4552       G1ParPushHeapRSClosure  push_heap_rs_cl(_g1h, &pss);
4553 
4554       pss.start_strong_roots();
4555       _g1h->g1_process_roots(strong_root_cl,
4556                              weak_root_cl,
4557                              &push_heap_rs_cl,
4558                              strong_cld_cl,
4559                              weak_cld_cl,
4560                              strong_code_cl,
4561                              worker_id);
4562 
4563       pss.end_strong_roots();
4564 
4565       {
4566         double start = os::elapsedTime();
4567         G1ParEvacuateFollowersClosure evac(_g1h, &pss, _queues, &_terminator);
4568         evac.do_void();
4569         double elapsed_sec = os::elapsedTime() - start;
4570         double term_sec = pss.term_time();
4571         _g1h->g1_policy()->phase_times()->add_time_secs(G1GCPhaseTimes::ObjCopy, worker_id, elapsed_sec - term_sec);
4572         _g1h->g1_policy()->phase_times()->record_time_secs(G1GCPhaseTimes::Termination, worker_id, term_sec);
4573         _g1h->g1_policy()->phase_times()->record_sub_count(G1GCPhaseTimes::Termination, worker_id, pss.term_attempts());
4574       }
4575       _g1h->g1_policy()->record_thread_age_table(pss.age_table());
4576       _g1h->update_surviving_young_words(pss.surviving_young_words()+1);
4577 
4578       if (PrintTerminationStats) {
4579         MutexLocker x(stats_lock());
4580         pss.print_termination_stats(worker_id);
4581       }
4582 
4583       assert(pss.queue_is_empty(), "should be empty");
4584 
4585       // Close the inner scope so that the ResourceMark and HandleMark
4586       // destructors are executed here and are included as part of the
4587       // "GC Worker Time".
4588     }
4589     _g1h->g1_policy()->phase_times()->record_time_secs(G1GCPhaseTimes::GCWorkerEnd, worker_id, os::elapsedTime());
4590   }
4591 };
4592 
4593 // *** Common G1 Evacuation Stuff
4594 
4595 // This method is run in a GC worker.
4596 
4597 void
4598 G1CollectedHeap::
4599 g1_process_roots(OopClosure* scan_non_heap_roots,
4600                  OopClosure* scan_non_heap_weak_roots,
4601                  G1ParPushHeapRSClosure* scan_rs,
4602                  CLDClosure* scan_strong_clds,
4603                  CLDClosure* scan_weak_clds,
4604                  CodeBlobClosure* scan_strong_code,
4605                  uint worker_i) {
4606 
4607   // First scan the shared roots.
4608   double ext_roots_start = os::elapsedTime();
4609   double closure_app_time_sec = 0.0;


4631     // until they can be processed at the end of marking.
4632     ref_processor_cm()->weak_oops_do(&buf_scan_non_heap_roots);
4633   }
4634 
4635   if (trace_metadata) {
4636     // Barrier to make sure all workers passed
4637     // the strong CLD and strong nmethods phases.
4638     active_strong_roots_scope()->wait_until_all_workers_done_with_threads(n_par_threads());
4639 
4640     // Now take the complement of the strong CLDs.
4641     ClassLoaderDataGraph::roots_cld_do(NULL, scan_weak_clds);
4642   }
4643 
4644   // Finish up any enqueued closure apps (attributed as object copy time).
4645   buf_scan_non_heap_roots.done();
4646   buf_scan_non_heap_weak_roots.done();
4647 
4648   double obj_copy_time_sec = buf_scan_non_heap_roots.closure_app_seconds()
4649       + buf_scan_non_heap_weak_roots.closure_app_seconds();
4650 
4651   g1_policy()->phase_times()->record_time_secs(G1GCPhaseTimes::ObjCopy, worker_i, obj_copy_time_sec);
4652 
4653   double ext_root_time_sec = os::elapsedTime() - ext_roots_start - obj_copy_time_sec;
4654   g1_policy()->phase_times()->record_time_secs(G1GCPhaseTimes::ExtRootScan, worker_i, ext_root_time_sec);
4655 
4656   // During conc marking we have to filter the per-thread SATB buffers
4657   // to make sure we remove any oops into the CSet (which will show up
4658   // as implicitly live).
4659   {
4660     G1GCPhaseTimesTracker x(g1_policy()->phase_times(), G1GCPhaseTimes::SATBFiltering, worker_i);
4661     if (!_process_strong_tasks->is_task_claimed(G1H_PS_filter_satb_buffers) && mark_in_progress()) {
4662       JavaThread::satb_mark_queue_set().filter_thread_buffers();
4663     }

4664   }
4665 
4666   // Now scan the complement of the collection set.
4667   G1CodeBlobClosure scavenge_cs_nmethods(scan_non_heap_weak_roots);
4668 
4669   g1_rem_set()->oops_into_collection_set_do(scan_rs, &scavenge_cs_nmethods, worker_i);
4670 
4671   _process_strong_tasks->all_tasks_completed();
4672 }
4673 
4674 class G1StringSymbolTableUnlinkTask : public AbstractGangTask {
4675 private:
4676   BoolObjectClosure* _is_alive;
4677   int _initial_string_table_size;
4678   int _initial_symbol_table_size;
4679 
4680   bool  _process_strings;
4681   int _strings_processed;
4682   int _strings_removed;
4683 


< prev index next >