Top


定義場所(file name)

hotspot/src/share/vm/memory/sharedHeap.cpp

名前(function name)

void SharedHeap::process_strong_roots(bool activate_scope,
                                      bool collecting_perm_gen,
                                      ScanningOption so,
                                      OopClosure* roots,
                                      CodeBlobClosure* code_roots,
                                      OopsInGenClosure* perm_blk) {

本体部(body)

  {- -------------------------------------------
  (1) #TODO
      (See: StrongRootsScope)
      ---------------------------------------- -}

      StrongRootsScope srs(this, activate_scope);

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

      // General strong roots.
      assert(_strong_roots_parity != 0, "must have called prologue code");

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

      if (!_process_strong_tasks->is_task_claimed(SH_PS_Universe_oops_do)) {
        Universe::oops_do(roots);
        ReferenceProcessor::oops_do(roots);
        // Consider perm-gen discovered lists to be strong.
        perm_gen()->ref_processor()->weak_oops_do(roots);
      }

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

      // Global (strong) JNI handles
      if (!_process_strong_tasks->is_task_claimed(SH_PS_JNIHandles_oops_do))
        JNIHandles::oops_do(roots);

  {- -------------------------------------------
  (1) ?? #TODO
      ---------------------------------------- -}

      // All threads execute this; the individual threads are task groups.
      if (ParallelGCThreads > 0) {
        Threads::possibly_parallel_oops_do(roots, code_roots);
      } else {
        Threads::oops_do(roots, code_roots);
      }

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

      if (!_process_strong_tasks-> is_task_claimed(SH_PS_ObjectSynchronizer_oops_do))
        ObjectSynchronizer::oops_do(roots);

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

      if (!_process_strong_tasks->is_task_claimed(SH_PS_FlatProfiler_oops_do))
        FlatProfiler::oops_do(roots);

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

      if (!_process_strong_tasks->is_task_claimed(SH_PS_Management_oops_do))
        Management::oops_do(roots);

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

      if (!_process_strong_tasks->is_task_claimed(SH_PS_jvmti_oops_do))
        JvmtiExport::oops_do(roots);

  {- -------------------------------------------
  (1) SubTasksDone::is_task_claimed() で, 他の WorkGang が SystemDictionary の処理を行ったかどうかを確認する.
      まだ処理されておらず, かつ引数の処理対象種別(以下の so)で SO_AllClasses または SO_SystemClasses が指定されている場合には処理を行う.
      (SO_AllClasses の場合には, SystemDictionary::oops_do() を呼び出す.
       SO_SystemClasses の場合には, SystemDictionary::always_strong_oops_do() を呼び出す.)
      ---------------------------------------- -}

      if (!_process_strong_tasks->is_task_claimed(SH_PS_SystemDictionary_oops_do)) {
        if (so & SO_AllClasses) {
          SystemDictionary::oops_do(roots);
        } else if (so & SO_SystemClasses) {
          SystemDictionary::always_strong_oops_do(roots);
        }
      }

  {- -------------------------------------------
  (1) SubTasksDone::is_task_claimed() で, 他の WorkGang が StringTable の処理を行ったかどうかを確認する.
      まだ処理されておらず, かつ以下の条件のどちらかがなりたった場合には, 処理を行う.
      * 引数の処理対象種別(以下の so)で SO_Strings が指定されている場合
      * 引数で Perm 領域は処理対象としないよう指定されており(!collecting_perm_gen), かつ JavaObjectsInPerm オプションも指定されていない場合  (<= これはどういう条件?? #TODO)

     (なお, 非 product 版でかつ JavaObjectsInPerm オプションが指定されている場合, ここで verify 処理も行われている)
      ---------------------------------------- -}

      if (!_process_strong_tasks->is_task_claimed(SH_PS_StringTable_oops_do)) {
        if (so & SO_Strings || (!collecting_perm_gen && !JavaObjectsInPerm)) {
          StringTable::oops_do(roots);
        }
        if (JavaObjectsInPerm) {
          // Verify the string table contents are in the perm gen
          NOT_PRODUCT(StringTable::oops_do(&assert_is_perm_closure));
        }
      }

  {- -------------------------------------------
  (1) SubTasksDone::is_task_claimed() で, 他の WorkGang が CodeCache の処理を行ったかどうかを確認する.
      まだ処理されておらず, かつ引数の処理対象種別(以下の so)で SO_CodeCache または SO_SystemClasses または SO_AllClasses が指定されている場合には処理を行う.
      (SO_CodeCache の場合には, CodeCache::blobs_do を呼び出す.
       SO_SystemClasses または SO_AllClasses の場合には, CodeCache::scavenge_root_nmethods_do() を呼び出す (が, 引数の collecting_perm_gen が false の場合には何も処理しない. コメントに何か書いてあるが... #TODO))
      ---------------------------------------- -}

      if (!_process_strong_tasks->is_task_claimed(SH_PS_CodeCache_oops_do)) {
        if (so & SO_CodeCache) {
          // (Currently, CMSCollector uses this to do intermediate-strength collections.)
          assert(collecting_perm_gen, "scanning all of code cache");
          assert(code_roots != NULL, "must supply closure for code cache");
          if (code_roots != NULL) {
            CodeCache::blobs_do(code_roots);
          }
        } else if (so & (SO_SystemClasses|SO_AllClasses)) {
          if (!collecting_perm_gen) {
            // If we are collecting from class statics, but we are not going to
            // visit all of the CodeCache, collect from the non-perm roots if any.
            // This makes the code cache function temporarily as a source of strong
            // roots for oops, until the next major collection.
            //
            // If collecting_perm_gen is true, we require that this phase will call
            // CodeCache::do_unloading.  This will kill off nmethods with expired
            // weak references, such as stale invokedynamic targets.
            CodeCache::scavenge_root_nmethods_do(code_roots);
          }
        }

  {- -------------------------------------------
  (1) (verify)
      ---------------------------------------- -}

        // Verify that the code cache contents are not subject to
        // movement by a scavenging collection.
        DEBUG_ONLY(CodeBlobToOopClosure assert_code_is_non_scavengable(&assert_is_non_scavengable_closure, /*do_marking=*/ false));
        DEBUG_ONLY(CodeCache::asserted_non_scavengable_nmethods_do(&assert_code_is_non_scavengable));
      }

  {- -------------------------------------------
  (1) もし引数で Perm 領域は処理対象としないよう指定されていれば(!collecting_perm_gen), 
      代わりに Perm 領域のオブジェクトは全て live と扱うことにして, 
      Perm 内のポインタで Perm 外を指しているもの全てに対して perm_blk を適用する.
      (この関数の先頭にあるコメントも参照).
      (処理自体は CardTableRS::younger_refs_iterate() を使って実現している).
      ---------------------------------------- -}

      if (!collecting_perm_gen) {
        // All threads perform this; coordination is handled internally.

        rem_set()->younger_refs_iterate(perm_gen(), perm_blk);
      }

  {- -------------------------------------------
  (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.