Top


定義場所(file name)

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

名前(function name)

void G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc,
                                             int worker_i) {

本体部(body)

  {- -------------------------------------------
  (1) (デバッグ用の処理) (CARD_REPEAT_HISTO マクロ定数を非 0 に #define した場合にのみ実行)
      ---------------------------------------- -}

    #if CARD_REPEAT_HISTO
      ct_freq_update_histo_and_reset();
    #endif

  {- -------------------------------------------
  (1) ?? #TODO
      (初回に初期化を行う, という話??)
      ---------------------------------------- -}

      if (worker_i == 0) {
        _cg1r->clear_and_record_card_counts();
      }

  {- -------------------------------------------
  (1) (トレース出力)
      (何か, command-line flag にした方がいいよなぁ, 的なことが書かれているが...)
      ---------------------------------------- -}

      // Make this into a command-line flag...
      if (G1RSCountHisto && (ParallelGCThreads == 0 || worker_i == 0)) {
        CountRSSizeClosure count_cl;
        _g1->heap_region_iterate(&count_cl);
        gclog_or_tty->print_cr("Avg of %d RS counts is %f, max is %d, "
                      "max region is " PTR_FORMAT,
                      count_cl.n(), (float)count_cl.tot()/(float)count_cl.n(),
                      count_cl.mx(), count_cl.mxr());
        count_cl.print_histo();
      }

  {- -------------------------------------------
  (1) 引数で渡された OopsInHeapRegionClosure (以下の oc) を _cset_rs_update_cl の中に一時的に記録しておく.
      (後で G1RemSet::concurrentRefineOneCard_impl() の中で使う模様. #TODO)
      ---------------------------------------- -}

      // We cache the value of 'oc' closure into the appropriate slot in the
      // _cset_rs_update_cl for this worker
      assert(worker_i < (int)n_workers(), "sanity");
      _cset_rs_update_cl[worker_i] = oc;

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

      // A DirtyCardQueue that is used to hold cards containing references
      // that point into the collection set. This DCQ is associated with a
      // special DirtyCardQueueSet (see g1CollectedHeap.hpp).  Under normal
      // circumstances (i.e. the pause successfully completes), these cards
      // are just discarded (there's no need to update the RSets of regions
      // that were in the collection set - after the pause these regions
      // are wholly 'free' of live objects. In the event of an evacuation
      // failure the cards/buffers in this queue set are:
      // * passed to the DirtyCardQueueSet that is used to manage deferred
      //   RSet updates, or
      // * scanned for references that point into the collection set
      //   and the RSet of the corresponding region in the collection set
      //   is updated immediately.
      DirtyCardQueue into_cset_dcq(&_g1->into_cset_dirty_card_queue_set());

  {- -------------------------------------------
  (1) (assert)
      ---------------------------------------- -}

      assert((ParallelGCThreads > 0) || worker_i == 0, "invariant");

  {- -------------------------------------------
  (1) (G1UseParallelRSetUpdating と G1UseParallelRSetScanning は
       バグ回避のための一時的なフラグとのこと.
       なお, 現在ではどちらのフラグもデフォルトで true になっているので, バグは修正されている模様.)
      ---------------------------------------- -}

      // The two flags below were introduced temporarily to serialize
      // the updating and scanning of remembered sets. There are some
      // race conditions when these two operations are done in parallel
      // and they are causing failures. When we resolve said race
      // conditions, we'll revert back to parallel remembered set
      // updating and scanning. See CRs 6677707 and 6677708.

  {- -------------------------------------------
  (1) G1RemSet::updateRS() を呼び出して,
      collection set 外から collection set 内を指しているポインタを発見し, ついでに Remembered Set を更新する (?? #TODO)

      (なお, G1UseParallelRSetUpdating オプションが指定されておらず worker_i も 0 でない場合, 
      record_update_rs_processed_buffers() と record_update_rs_time() による
      G1CollectorPolicy 内への時間の記録処理だけを行っている (どちらも 0.0 秒という値を記録))
      ---------------------------------------- -}

      if (G1UseParallelRSetUpdating || (worker_i == 0)) {
        updateRS(&into_cset_dcq, worker_i);
      } else {
        _g1p->record_update_rs_processed_buffers(worker_i, 0.0);
        _g1p->record_update_rs_time(worker_i, 0.0);
      }

  {- -------------------------------------------
  (1) G1RemSet::scanRS() を呼び出して, 
      実際に Remembered Set 中のポインタの処理を行う (??)#TODO

      (なお, G1UseParallelRSetScanning オプションが指定されておらず worker_i も 0 でない場合, 
      record_scan_rs_time() による
      G1CollectorPolicy 内への時間の記録処理だけを行っている (0.0 秒という値を記録))
      ---------------------------------------- -}

      if (G1UseParallelRSetScanning || (worker_i == 0)) {
        scanRS(oc, worker_i);
      } else {
        _g1p->record_scan_rs_time(worker_i, 0.0);
      }

  {- -------------------------------------------
  (1) 上の処理で設定した _cset_rs_update_cl 内の箇所を NULL に戻しておく.
      ---------------------------------------- -}

      // We now clear the cached values of _cset_rs_update_cl for this worker
      _cset_rs_update_cl[worker_i] = NULL;
    }

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