void StealMarkingTask::do_it(GCTaskManager* manager, uint which) {
  assert(Universe::heap()->is_gc_active(), "called outside gc");

  NOT_PRODUCT(GCTraceTime tm("StealMarkingTask",
    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));

  ParCompactionManager* cm =
    ParCompactionManager::gc_thread_compaction_manager(which);
  PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);

  oop obj = NULL;
  ObjArrayTask task;
  int random_seed = 17;
  do {
    while (ParCompactionManager::steal_objarray(which, &random_seed, task)) {
      objArrayKlass* const k = (objArrayKlass*)task.obj()->blueprint();
      k->oop_follow_contents(cm, task.obj(), task.index());
      cm->follow_marking_stacks();
    }
    while (ParCompactionManager::steal(which, &random_seed, obj)) {
      obj->follow_contents(cm);
      cm->follow_marking_stacks();
    }
  } while (!terminator()->offer_termination());
}
Пример #2
0
void ThreadRootsMarkingTask::do_it(GCTaskManager* manager, uint which) {
  assert(Universe::heap()->is_gc_active(), "called outside gc");

  ResourceMark rm;

  NOT_PRODUCT(TraceTime tm("ThreadRootsMarkingTask",
    PrintGCDetails && TraceParallelOldGCTasks, true, gclog_or_tty));
  ParCompactionManager* cm =
    ParCompactionManager::gc_thread_compaction_manager(which);

  PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
  CLDToOopClosure mark_and_push_from_clds(&mark_and_push_closure, true);
  CodeBlobToOopClosure mark_and_push_in_blobs(&mark_and_push_closure, /*do_marking=*/ true);

  if (_java_thread != NULL)
    _java_thread->oops_do(
        &mark_and_push_closure,
        &mark_and_push_from_clds,
        &mark_and_push_in_blobs);

  if (_vm_thread != NULL)
    _vm_thread->oops_do(
        &mark_and_push_closure,
        &mark_and_push_from_clds,
        &mark_and_push_in_blobs);

  // Do the real work
  cm->follow_marking_stacks();
}
Пример #3
0
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC

//
// ThreadRootsMarkingTask
//

void ThreadRootsMarkingTask::do_it(GCTaskManager* manager, uint which) {
  assert(Universe::heap()->is_gc_active(), "called outside gc");

  ResourceMark rm;

  NOT_PRODUCT(GCTraceTime tm("ThreadRootsMarkingTask",
    PrintGCDetails && TraceParallelOldGCTasks, true, NULL, PSParallelCompact::gc_tracer()->gc_id()));
  ParCompactionManager* cm =
    ParCompactionManager::gc_thread_compaction_manager(which);

  PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
  CLDToOopClosure mark_and_push_from_clds(&mark_and_push_closure, true);
  MarkingCodeBlobClosure mark_and_push_in_blobs(&mark_and_push_closure, !CodeBlobToOopClosure::FixRelocations);

  if (_java_thread != NULL)
    _java_thread->oops_do(
        &mark_and_push_closure,
        &mark_and_push_from_clds,
        &mark_and_push_in_blobs);

  if (_vm_thread != NULL)
    _vm_thread->oops_do(
        &mark_and_push_closure,
        &mark_and_push_from_clds,
        &mark_and_push_in_blobs);

  // Do the real work
  cm->follow_marking_stacks();
}
void MarkFromRootsTask::do_it(GCTaskManager* manager, uint which) {
  assert(Universe::heap()->is_gc_active(), "called outside gc");

  NOT_PRODUCT(GCTraceTime tm("MarkFromRootsTask",
    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
  ParCompactionManager* cm =
    ParCompactionManager::gc_thread_compaction_manager(which);
  PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);

  switch (_root_type) {
    case universe:
      Universe::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");
  }

  // Do the real work
  cm->follow_marking_stacks();
}
Пример #5
0
void PSMarkSweep::mark_sweep_phase1( bool& marked_for_unloading, bool clear_all_softrefs) {
    // Recursively traverse all live objects and mark them
    EventMark m("1 mark object");
    TraceTime tm("phase 1", PrintGC && Verbose, true, gclog_or_tty);
    trace(" 1");

    ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
    assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");

    // General strong roots.
    Universe::oops_do(mark_and_push_closure());
    JNIHandles::oops_do(mark_and_push_closure());   // Global (strong) JNI handles
    Threads::oops_do(mark_and_push_closure());
    ObjectSynchronizer::oops_do(mark_and_push_closure());
    FlatProfiler::oops_do(mark_and_push_closure());
    SystemDictionary::always_strong_oops_do(mark_and_push_closure());

    guarantee(!jvmdi::enabled(), "Should not be used with jvmdi");
    vmSymbols::oops_do(mark_and_push_closure());

    // Flush marking stack.
    follow_stack();

    // Process reference objects found during marking
    ReferencePolicy *soft_ref_policy;
    if (clear_all_softrefs) {
        soft_ref_policy = new AlwaysClearPolicy();
    } else {
        NOT_COMPILER2(soft_ref_policy = new LRUCurrentHeapPolicy();)
        COMPILER2_ONLY(soft_ref_policy = new LRUMaxHeapPolicy();)
    }
void RefProcTaskProxy::do_it(GCTaskManager* manager, uint which)
{
  assert(Universe::heap()->is_gc_active(), "called outside gc");

  NOT_PRODUCT(GCTraceTime tm("RefProcTask",
    PrintGCDetails && TraceParallelOldGCTasks, true, NULL));
  ParCompactionManager* cm =
    ParCompactionManager::gc_thread_compaction_manager(which);
  PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
  PSParallelCompact::FollowStackClosure follow_stack_closure(cm);
  _rp_task.work(_work_id, *PSParallelCompact::is_alive_closure(),
                mark_and_push_closure, follow_stack_closure);
}
void instanceKlassKlass::oop_follow_contents(ParCompactionManager* cm,
                                             oop obj) {
  assert(obj->is_klass(),"must be a klass");
  assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), "must be instance klass");

  instanceKlass* ik = instanceKlass::cast(klassOop(obj));
  ik->follow_static_fields(cm);
  ik->vtable()->oop_follow_contents(cm);
  ik->itable()->oop_follow_contents(cm);

  PSParallelCompact::mark_and_push(cm, ik->adr_array_klasses());
  PSParallelCompact::mark_and_push(cm, ik->adr_methods());
  PSParallelCompact::mark_and_push(cm, ik->adr_method_ordering());
  PSParallelCompact::mark_and_push(cm, ik->adr_local_interfaces());
  PSParallelCompact::mark_and_push(cm, ik->adr_transitive_interfaces());
  PSParallelCompact::mark_and_push(cm, ik->adr_fields());
  PSParallelCompact::mark_and_push(cm, ik->adr_constants());
  PSParallelCompact::mark_and_push(cm, ik->adr_class_loader());
  PSParallelCompact::mark_and_push(cm, ik->adr_source_file_name());
  PSParallelCompact::mark_and_push(cm, ik->adr_source_debug_extension());
  PSParallelCompact::mark_and_push(cm, ik->adr_inner_classes());
  PSParallelCompact::mark_and_push(cm, ik->adr_protection_domain());
  PSParallelCompact::mark_and_push(cm, ik->adr_host_klass());
  PSParallelCompact::mark_and_push(cm, ik->adr_signers());
  PSParallelCompact::mark_and_push(cm, ik->adr_generic_signature());
  PSParallelCompact::mark_and_push(cm, ik->adr_bootstrap_method());
  PSParallelCompact::mark_and_push(cm, ik->adr_class_annotations());
  PSParallelCompact::mark_and_push(cm, ik->adr_fields_annotations());
  PSParallelCompact::mark_and_push(cm, ik->adr_methods_annotations());
  PSParallelCompact::mark_and_push(cm, ik->adr_methods_parameter_annotations());
  PSParallelCompact::mark_and_push(cm, ik->adr_methods_default_annotations());

  // We do not follow adr_implementor() here. It is followed later
  // in instanceKlass::follow_weak_klass_links()

  klassKlass::oop_follow_contents(cm, obj);

  PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
  iterate_c_heap_oops(ik, &mark_and_push_closure);
}
Пример #8
0
void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
  // Recursively traverse all live objects and mark them
  EventMark m("1 mark object");
  TraceTime tm("phase 1", PrintGCDetails && Verbose, true, gclog_or_tty);
  trace(" 1");

  ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
  assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");

  // General strong roots.
  {
    ParallelScavengeHeap::ParStrongRootsScope psrs;
    Universe::oops_do(mark_and_push_closure());
    ReferenceProcessor::oops_do(mark_and_push_closure());
    JNIHandles::oops_do(mark_and_push_closure());   // Global (strong) JNI handles
    CodeBlobToOopClosure each_active_code_blob(mark_and_push_closure(), /*do_marking=*/ true);
    Threads::oops_do(mark_and_push_closure(), &each_active_code_blob);
    ObjectSynchronizer::oops_do(mark_and_push_closure());
    FlatProfiler::oops_do(mark_and_push_closure());
    Management::oops_do(mark_and_push_closure());
    JvmtiExport::oops_do(mark_and_push_closure());
    SystemDictionary::always_strong_oops_do(mark_and_push_closure());
    vmSymbols::oops_do(mark_and_push_closure());
    // 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()));
  }

  // Flush marking stack.
  follow_stack();

  // Process reference objects found during marking
  {
    ref_processor()->setup_policy(clear_all_softrefs);
    ref_processor()->process_discovered_references(
      is_alive_closure(), mark_and_push_closure(), follow_stack_closure(), NULL);
  }

  // Follow system dictionary roots and unload classes
  bool purged_class = SystemDictionary::do_unloading(is_alive_closure());

  // Follow code cache roots
  CodeCache::do_unloading(is_alive_closure(), mark_and_push_closure(),
                          purged_class);
  follow_stack(); // Flush marking stack

  // Update subklass/sibling/implementor links of live klasses
  follow_weak_klass_links();
  assert(_marking_stack.is_empty(), "just drained");

  // Visit memoized mdo's and clear unmarked weak refs
  follow_mdo_weak_refs();
  assert(_marking_stack.is_empty(), "just drained");

  // Visit symbol and interned string tables and delete unmarked oops
  SymbolTable::unlink(is_alive_closure());
  StringTable::unlink(is_alive_closure());

  assert(_marking_stack.is_empty(), "stack should be empty by now");
}
inline void ParCompactionManager::follow_class_loader(ClassLoaderData* cld) {
  MarkAndPushClosure mark_and_push_closure(this);
  FollowKlassClosure follow_klass_closure(&mark_and_push_closure);

  cld->oops_do(&mark_and_push_closure, &follow_klass_closure, true);
}
Пример #10
0
void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
  // Recursively traverse all live objects and mark them
  GCTraceTime tm("phase 1", PrintGCDetails && Verbose, true, _gc_timer, _gc_tracer->gc_id());

  ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();

  // Need to clear claim bits before the tracing starts.
  ClassLoaderDataGraph::clear_claimed_marks();

  // General strong roots.
  {
    ParallelScavengeHeap::ParStrongRootsScope psrs;
    Universe::oops_do(mark_and_push_closure());
    JNIHandles::oops_do(mark_and_push_closure());   // Global (strong) JNI handles
    CLDToOopClosure mark_and_push_from_cld(mark_and_push_closure());
    MarkingCodeBlobClosure each_active_code_blob(mark_and_push_closure(), !CodeBlobToOopClosure::FixRelocations);
    Threads::oops_do(mark_and_push_closure(), &mark_and_push_from_cld, &each_active_code_blob);
    ObjectSynchronizer::oops_do(mark_and_push_closure());
    FlatProfiler::oops_do(mark_and_push_closure());
    Management::oops_do(mark_and_push_closure());
    JvmtiExport::oops_do(mark_and_push_closure());
    SystemDictionary::always_strong_oops_do(mark_and_push_closure());
    ClassLoaderDataGraph::always_strong_cld_do(follow_cld_closure());
    // 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()));
  }

  // Flush marking stack.
  follow_stack();

  // Process reference objects found during marking
  {
    ref_processor()->setup_policy(clear_all_softrefs);
    const ReferenceProcessorStats& stats =
      ref_processor()->process_discovered_references(
        is_alive_closure(), mark_and_push_closure(), follow_stack_closure(), NULL, _gc_timer, _gc_tracer->gc_id());
    gc_tracer()->report_gc_reference_stats(stats);
  }

  // This is the point where the entire marking should have completed.
  assert(_marking_stack.is_empty(), "Marking should have completed");

  // Unload classes and purge the SystemDictionary.
  bool purged_class = SystemDictionary::do_unloading(is_alive_closure());

  // Unload nmethods.
  CodeCache::do_unloading(is_alive_closure(), purged_class);

  // Prune dead klasses from subklass/sibling/implementor lists.
  Klass::clean_weak_klass_links(is_alive_closure());

  // Delete entries for dead interned strings.
  StringTable::unlink(is_alive_closure());

  // Clean up unreferenced symbols in symbol table.
  SymbolTable::unlink();
  _gc_tracer->report_object_count_after_gc(is_alive_closure());
}