Top


定義場所(file name)

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

名前(function name)

void
G1CollectedHeap::
g1_process_strong_roots(bool collecting_perm_gen,
                        SharedHeap::ScanningOption so,
                        OopClosure* scan_non_heap_roots,
                        OopsInHeapRegionClosure* scan_rs,
                        OopsInGenClosure* scan_perm,
                        int worker_i) {

本体部(body)

  {- -------------------------------------------
  (1) 処理開始時の時間を記録しておく
      ---------------------------------------- -}

      // First scan the strong roots, including the perm gen.
      double ext_roots_start = os::elapsedTime();

  {- -------------------------------------------
  (1) ?? (以下の変数は使用箇所が無いような...)
      ---------------------------------------- -}

      double closure_app_time_sec = 0.0;

  {- -------------------------------------------
  (1) (変数宣言など) (?? #TODO)
      ---------------------------------------- -}

      BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots);
      BufferingOopsInGenClosure buf_scan_perm(scan_perm);
      buf_scan_perm.set_generation(perm_gen());

      // Walk the code cache w/o buffering, because StarTask cannot handle
      // unaligned oop locations.
      CodeBlobToOopClosure eager_scan_code_roots(scan_non_heap_roots, /*do_marking=*/ true);

  {- -------------------------------------------
  (1) SharedHeap::process_strong_roots() を呼んで, 
      strong root から辿れる範囲に G1ParCopyClosure を適用する.
      (ただし, ポインタ配列については G1ParScanPartialArrayClosure を適用する)
      ---------------------------------------- -}

      process_strong_roots(false, // no scoping; this is parallel code
                           collecting_perm_gen, so,
                           &buf_scan_non_heap_roots,
                           &eager_scan_code_roots,
                           &buf_scan_perm);

  {- -------------------------------------------
  (1) 最後に, BufferingOopClosure や BufferingOopsInGenClosure のバッファ内に残っているものがあれば処理している?? #TODO
      ---------------------------------------- -}

      // Finish up any enqueued closure apps.
      buf_scan_non_heap_roots.done();
      buf_scan_perm.done();

  {- -------------------------------------------
  (1) 処理に掛かった時間を G1CollectorPolicy オブジェクトに記録.
      ---------------------------------------- -}

      double ext_roots_end = os::elapsedTime();
      g1_policy()->reset_obj_copy_time(worker_i);
      double obj_copy_time_sec =
        buf_scan_non_heap_roots.closure_app_seconds() +
        buf_scan_perm.closure_app_seconds();
      g1_policy()->record_obj_copy_time(worker_i, obj_copy_time_sec * 1000.0);
      double ext_root_time_ms =
        ((ext_roots_end - ext_roots_start) - obj_copy_time_sec) * 1000.0;
      g1_policy()->record_ext_root_scan_time(worker_i, ext_root_time_ms);

  {- -------------------------------------------
  (1) SubTasksDone::is_task_claimed() で, 他の WorkGang が mark stack の処理を行ったかどうかを確認する.
      まだであれば ConcurrentMark::oops_do() で mark stack の処理を行う.
      ---------------------------------------- -}

      // Scan strong roots in mark stack.
      if (!_process_strong_tasks->is_task_claimed(G1H_PS_mark_stack_oops_do)) {
        concurrent_mark()->oops_do(scan_non_heap_roots);
      }

  {- -------------------------------------------
  (1) mark stack の処理に掛かった時間を G1CollectorPolicy オブジェクトに記録.
      ---------------------------------------- -}

      double mark_stack_scan_ms = (os::elapsedTime() - ext_roots_end) * 1000.0;
      g1_policy()->record_mark_stack_scan_time(worker_i, mark_stack_scan_ms);

      // XXX What should this be doing in the parallel case?
      g1_policy()->record_collection_pause_end_CH_strong_roots();

  {- -------------------------------------------
  (1) G1RemSet::oops_into_collection_set_do() を呼び出して, 
      回収対象の region の remembered set に入っているポインタ (= 回収対象ではない region から回収対象の region を指しているポインタ) について処理を行う.

      (引数の scan_rs が NULL だった場合には処理しないようだが, 今のところそんな処理パスは無いような... #TODO)
      ---------------------------------------- -}

      // Now scan the complement of the collection set.
      if (scan_rs != NULL) {
        g1_rem_set()->oops_into_collection_set_do(scan_rs, worker_i);
      }

  {- -------------------------------------------
  (1) SubTasksDone::is_task_claimed() で, 他の WorkGang が refProcessor の処理を行ったかどうかを確認する.
      まだであれば ReferenceProcessor::weak_oops_do() と ReferenceProcessor::oops_do() で refProcessor の処理を行う.

      (なお, ref_processor() に格納されているのは ReferenceProcessor オブジェクト.
      G1CollectedHeap::ref_processing_init() 参照)
      ---------------------------------------- -}

      // Finish with the ref_processor roots.
      if (!_process_strong_tasks->is_task_claimed(G1H_PS_refProcessor_oops_do)) {
        // We need to treat the discovered reference lists as roots and
        // keep entries (which are added by the marking threads) on them
        // live until they can be processed at the end of marking.
        ref_processor()->weak_oops_do(scan_non_heap_roots);
        ref_processor()->oops_do(scan_non_heap_roots);
      }

  {- -------------------------------------------
  (1) 処理に掛かった時間を G1CollectorPolicy オブジェクトに記録.
      ---------------------------------------- -}

      g1_policy()->record_collection_pause_end_G1_strong_roots();

  {- -------------------------------------------
  (1) SubTasksDone::all_tasks_completed() を呼びだしておく.
      (これにより, 全部の WorkGang の処理が終わった時点で
       次の処理に備えて, SubTasksDone オブジェクトが最初の状態に戻される.)
      ---------------------------------------- -}

      _process_strong_tasks->all_tasks_completed();
    }

This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.