hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
void MarkFromRootsTask::do_it(GCTaskManager* manager, uint which) {
  {- -------------------------------------------
  (1) (assert)
      ---------------------------------------- -}
      assert(Universe::heap()->is_gc_active(), "called outside gc");
  {- -------------------------------------------
  (1) (トレース出力)
      ---------------------------------------- -}
      NOT_PRODUCT(TraceTime tm("MarkFromRootsTask",
        PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
  {- -------------------------------------------
  (1) ParCompactionManager::gc_thread_compaction_manager() で, 
      これを実行している GCTaskThread 用の ParCompactionManager オブジェクトを取得する.
      ---------------------------------------- -}
      ParCompactionManager* cm =
        ParCompactionManager::gc_thread_compaction_manager(which);
  {- -------------------------------------------
  (1) (変数宣言など)
      ---------------------------------------- -}
      PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
  {- -------------------------------------------
  (1) MarkFromRootsTask は, コンストラクタで指定された _root_type に応じて処理対象を変える.
      以下, _root_type に応じて処理を分岐.
      といっても, どの場合も _root_type に対応するオブジェクトの oops_do() メソッドを呼び出すだけ.
        (SystemDictionary だけは SystemDictionary::always_strong_oops_do() というメソッド名だが...)
      その際に, PSParallelCompact::MarkAndPushClosure オブジェクト (上の mark_and_push_closure) を引数として呼び出す.
      これにより, そのオブジェクト内のポインタを ParCompactionManager オブジェクトのタスクキューに追加していく(??#TODO)
      なお現状では, 以下の case threads: のケースは使われていない模様.
        (Thread 内の処理は ThreadRootsTask クラスで処理するので, 
         ScavengeRootsTask オブジェクトが threads を指定されて生成されることはない.)
      また, case reference_processing: のケースも使われていない模様.
        (?? #TODO)
      また, case code_cache: の場合は, 特に何も処理は行わない.
        (mark sweep 時には, nmethod は参照されてなければアンロードするだけであって, 特に strong root として扱う必要が無いため.)
      ---------------------------------------- -}
      switch (_root_type) {
        case universe:
          Universe::oops_do(&mark_and_push_closure);
          break;
        case reference_processing:
          ReferenceProcessor::oops_do(&mark_and_push_closure);
          break;
        case jni_handles:
          JNIHandles::oops_do(&mark_and_push_closure);
          break;
        case threads:
        {
          ResourceMark rm;
          CodeBlobToOopClosure each_active_code_blob(&mark_and_push_closure, /*do_marking=*/ true);
          Threads::oops_do(&mark_and_push_closure, &each_active_code_blob);
        }
        break;
        case object_synchronizer:
          ObjectSynchronizer::oops_do(&mark_and_push_closure);
          break;
        case flat_profiler:
          FlatProfiler::oops_do(&mark_and_push_closure);
          break;
        case management:
          Management::oops_do(&mark_and_push_closure);
          break;
        case jvmti:
          JvmtiExport::oops_do(&mark_and_push_closure);
          break;
        case system_dictionary:
          SystemDictionary::always_strong_oops_do(&mark_and_push_closure);
          break;
        case code_cache:
          // Do not treat nmethods as strong roots for mark/sweep, since we can unload them.
          //CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(&mark_and_push_closure));
          break;
        default:
          fatal("Unknown root type");
      }
  {- -------------------------------------------
  (1) PSParallelCompact::MarkAndPushClosure::follow_marking_stacks() で, 
      タスクキューに追加したポインタに対して, 再帰的な mark 処理を行う.
      ---------------------------------------- -}
      // Do the real work
      cm->follow_marking_stacks();
    }
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.