hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
void PSParallelCompact::enqueue_dense_prefix_tasks(GCTaskQueue* q,
                                                    uint parallel_gc_threads) {
  {- -------------------------------------------
  (1) (トレース出力)
      ---------------------------------------- -}
      TraceTime tm("dense prefix task setup", print_phases(), true, gclog_or_tty);
  {- -------------------------------------------
  (1) (変数宣言など)
      ---------------------------------------- -}
      ParallelCompactData& sd = PSParallelCompact::summary_data();
  {- -------------------------------------------
  (1) 以下の for ループ内で, 各 Space の dense prefix 部分を
      処理する UpdateDensePrefixTask オブジェクトをキューに詰めていく.
      (ただし, dense prefix 量が 0 ならば, その Space に関しては何もしない (というかすることがない))
      各 Space に対して生成される UpdateDensePrefixTask オブジェクトの個数(以下の tasks_for_dense_prefix), 
      及び 1つの UpdateDensePrefixTask で処理する region 数(以下の regions_per_thread) は
      以下の通り.
      (なお, 以下の total_dense_prefix_regions は「dense prefix に含まれる region の個数」, 
       parallel_gc_threads は「引数で指定された GC スレッド数」のこと)
      * total_dense_prefix_regions が parallel_gc_threads よりも小さい場合
        * 生成される UpdateDensePrefixTask オブジェクトの個数 : 
          total_dense_prefix_regions と同数
        * 1つの UpdateDensePrefixTask で処理する region 数  : 
          1 個
      * total_dense_prefix_regions が 「parallel_gc_threads * PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING」以下の場合
        * 生成される UpdateDensePrefixTask オブジェクトの個数 : 
          parallel_gc_threads と同数 (半端な残りが出た場合は +1)
        * 1つの UpdateDensePrefixTask で処理する region 数  : 
          total_dense_prefix_regions/parallel_gc_threads  (端数切り捨て)
          (最後の1つについてはこの大きさに満たないこともある)
      * total_dense_prefix_regions が 「parallel_gc_threads * PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING」より大きい場合
        * 生成される UpdateDensePrefixTask オブジェクトの個数 : 
          parallel_gc_threads * PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING (半端な残りが出た場合は +1)
        * 1つの UpdateDensePrefixTask で処理する region 数  : 
          total_dense_prefix_regions/(parallel_gc_threads*PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING)  (端数切り捨て)
          (最後の1つについてはこの大きさに満たないこともある)
      ---------------------------------------- -}
      // Iterate over all the spaces adding tasks for updating
      // regions in the dense prefix.  Assume that 1 gc thread
      // will work on opening the gaps and the remaining gc threads
      // will work on the dense prefix.
      unsigned int space_id;
      for (space_id = old_space_id; space_id < last_space_id; ++ space_id) {
        HeapWord* const dense_prefix_end = _space_info[space_id].dense_prefix();
        const MutableSpace* const space = _space_info[space_id].space();
    {- -------------------------------------------
  (1.1) dense prefix がなければ, その Space については処理は行わない.
        ---------------------------------------- -}
        if (dense_prefix_end == space->bottom()) {
          // There is no dense prefix for this space.
          continue;
        }
    {- -------------------------------------------
  (1.1) (変数宣言など)
        ---------------------------------------- -}
        // The dense prefix is before this region.
        size_t region_index_end_dense_prefix =
            sd.addr_to_region_idx(dense_prefix_end);
        RegionData* const dense_prefix_cp =
          sd.region(region_index_end_dense_prefix);
        assert(dense_prefix_end == space->end() ||
               dense_prefix_cp->available() ||
               dense_prefix_cp->claimed(),
               "The region after the dense prefix should always be ready to fill");
        size_t region_index_start = sd.addr_to_region_idx(space->bottom());
        // Is there dense prefix work?
        size_t total_dense_prefix_regions =
          region_index_end_dense_prefix - region_index_start;
    {- -------------------------------------------
  (1.1) (以下の if 式の条件 (total_dense_prefix_regions > 0) が true になるのはどういうケース?? #TODO)
        ---------------------------------------- -}
        // How many regions of the dense prefix should be given to
        // each thread?
        if (total_dense_prefix_regions > 0) {
    {- -------------------------------------------
  (1.1) (tasks_for_dense_prefix 及び regions_per_thread を計算)
        ---------------------------------------- -}
          uint tasks_for_dense_prefix = 1;
          if (total_dense_prefix_regions <=
              (parallel_gc_threads * PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING)) {
            // Don't over partition.  This assumes that
            // PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING is a small integer value
            // so there are not many regions to process.
            tasks_for_dense_prefix = parallel_gc_threads;
          } else {
            // Over partition
            tasks_for_dense_prefix = parallel_gc_threads *
              PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING;
          }
          size_t regions_per_thread = total_dense_prefix_regions /
            tasks_for_dense_prefix;
          // Give each thread at least 1 region.
          if (regions_per_thread == 0) {
            regions_per_thread = 1;
          }
    {- -------------------------------------------
  (1.1) tasks_for_dense_prefix 分だけ UpdateDensePrefixTask オブジェクトを生成
        (ただし, dense prefix に含まれるリージョン数が parallel_gc_threads に満たない場合は, 
         そのリージョン数に達したところで終了 
         (以下の region_index_start >= region_index_end_dense_prefix という条件での break))
        ---------------------------------------- -}
          for (uint k = 0; k < tasks_for_dense_prefix; k++) {
            if (region_index_start >= region_index_end_dense_prefix) {
              break;
            }
            // region_index_end is not processed
            size_t region_index_end = MIN2(region_index_start + regions_per_thread,
                                           region_index_end_dense_prefix);
            q->enqueue(new UpdateDensePrefixTask(SpaceId(space_id),
                                                 region_index_start,
                                                 region_index_end));
            region_index_start = region_index_end;
          }
        }
    {- -------------------------------------------
  (1.1) もし半端に残っている region があった場合には, 
        そこを処理する UpdateDensePrefixTask オブジェクトを作っておく.
        ---------------------------------------- -}
        // This gets any part of the dense prefix that did not
        // fit evenly.
        if (region_index_start < region_index_end_dense_prefix) {
          q->enqueue(new UpdateDensePrefixTask(SpaceId(space_id),
                                               region_index_start,
                                               region_index_end_dense_prefix));
        }
      }
    }
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.