Example #1
0
void SharedHeap::process_strong_roots(bool activate_scope,
                                      bool is_scavenging,
                                      ScanningOption so,
                                      OopClosure* roots,
                                      CodeBlobClosure* code_roots,
                                      KlassClosure* klass_closure) {
  StrongRootsScope srs(this, activate_scope);

  // General strong roots.
  assert(_strong_roots_parity != 0, "must have called prologue code");
  // _n_termination for _process_strong_tasks should be set up stream
  // in a method not running in a GC worker.  Otherwise the GC worker
  // could be trying to change the termination condition while the task
  // is executing in another GC worker.
  if (!_process_strong_tasks->is_task_claimed(SH_PS_Universe_oops_do)) {
    Universe::oops_do(roots);
  }
  // Global (strong) JNI handles
  if (!_process_strong_tasks->is_task_claimed(SH_PS_JNIHandles_oops_do))
    JNIHandles::oops_do(roots);

  // All threads execute this; the individual threads are task groups.
  CLDToOopClosure roots_from_clds(roots);
  CLDToOopClosure* roots_from_clds_p = (is_scavenging ? NULL : &roots_from_clds);
  if (CollectedHeap::use_parallel_gc_threads()) {
    Threads::possibly_parallel_oops_do(roots, roots_from_clds_p, code_roots);
  } else {
    Threads::oops_do(roots, roots_from_clds_p, code_roots);
  }

  if (!_process_strong_tasks-> is_task_claimed(SH_PS_ObjectSynchronizer_oops_do))
    ObjectSynchronizer::oops_do(roots);
  if (!_process_strong_tasks->is_task_claimed(SH_PS_FlatProfiler_oops_do))
    FlatProfiler::oops_do(roots);
  if (!_process_strong_tasks->is_task_claimed(SH_PS_Management_oops_do))
    Management::oops_do(roots);
  if (!_process_strong_tasks->is_task_claimed(SH_PS_jvmti_oops_do))
    JvmtiExport::oops_do(roots);

  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);
    } else {
      fatal("We should always have selected either SO_AllClasses or SO_SystemClasses");
    }
  }

  if (!_process_strong_tasks->is_task_claimed(SH_PS_ClassLoaderDataGraph_oops_do)) {
    if (so & SO_AllClasses) {
      ClassLoaderDataGraph::oops_do(roots, klass_closure, !is_scavenging);
    } else if (so & SO_SystemClasses) {
      ClassLoaderDataGraph::always_strong_oops_do(roots, klass_closure, !is_scavenging);
    }
  }

  // All threads execute the following. A specific chunk of buckets
  // from the StringTable are the individual tasks.
  if (so & SO_Strings) {
    if (CollectedHeap::use_parallel_gc_threads()) {
      StringTable::possibly_parallel_oops_do(roots);
    } else {
      StringTable::oops_do(roots);
    }
  }

  if (!_process_strong_tasks->is_task_claimed(SH_PS_CodeCache_oops_do)) {
    if (so & SO_CodeCache) {
      assert(code_roots != NULL, "must supply closure for code cache");

      if (is_scavenging) {
        // We only visit parts of the CodeCache when scavenging.
        CodeCache::scavenge_root_nmethods_do(code_roots);
      } else {
        // CMSCollector uses this to do intermediate-strength collections.
        // We scan the entire code cache, since CodeCache::do_unloading is not called.
        CodeCache::blobs_do(code_roots);
      }
    }
    // 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));
  }

  _process_strong_tasks->all_tasks_completed();
}
Example #2
0
void SharedHeap::process_strong_roots(bool activate_scope,
                                      bool collecting_perm_gen,
                                      ScanningOption so,
                                      OopClosure* roots,
                                      CodeBlobClosure* code_roots,
                                      OopsInGenClosure* perm_blk) {
    StrongRootsScope srs(this, activate_scope);
    // General strong roots.
    assert(_strong_roots_parity != 0, "must have called prologue code");
    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);
    }
    // Global (strong) JNI handles
    if (!_process_strong_tasks->is_task_claimed(SH_PS_JNIHandles_oops_do))
        JNIHandles::oops_do(roots);
    // 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);
    }
    if (!_process_strong_tasks-> is_task_claimed(SH_PS_ObjectSynchronizer_oops_do))
        ObjectSynchronizer::oops_do(roots);
    if (!_process_strong_tasks->is_task_claimed(SH_PS_FlatProfiler_oops_do))
        FlatProfiler::oops_do(roots);
    if (!_process_strong_tasks->is_task_claimed(SH_PS_Management_oops_do))
        Management::oops_do(roots);
    if (!_process_strong_tasks->is_task_claimed(SH_PS_jvmti_oops_do))
        JvmtiExport::oops_do(roots);

    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);
        }
    }

    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));
        }
    }

    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);
            }
        }
        // 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));
    }

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

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