static void oop_pc_follow_contents_specialized(InstanceRefKlass* klass, oop obj, ParCompactionManager* cm) {
  T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
  T heap_oop = oopDesc::load_heap_oop(referent_addr);
  log_develop_trace(gc, ref)("InstanceRefKlass::oop_pc_follow_contents " PTR_FORMAT, p2i(obj));
  if (!oopDesc::is_null(heap_oop)) {
    oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
    if (PSParallelCompact::mark_bitmap()->is_unmarked(referent) &&
        PSParallelCompact::ref_processor()->discover_reference(obj, klass->reference_type())) {
      // reference already enqueued, referent will be traversed later
      klass->InstanceKlass::oop_pc_follow_contents(obj, cm);
      log_develop_trace(gc, ref)("       Non NULL enqueued " PTR_FORMAT, p2i(obj));
      return;
    } else {
      // treat referent as normal oop
      log_develop_trace(gc, ref)("       Non NULL normal " PTR_FORMAT, p2i(obj));
      cm->mark_and_push(referent_addr);
    }
  }
  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
  // Treat discovered as normal oop, if ref is not "active",
  // i.e. if next is non-NULL.
  T  next_oop = oopDesc::load_heap_oop(next_addr);
  if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
    T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
    log_develop_trace(gc, ref)("   Process discovered as normal " PTR_FORMAT, p2i(discovered_addr));
    cm->mark_and_push(discovered_addr);
  }
  cm->mark_and_push(next_addr);
  klass->InstanceKlass::oop_pc_follow_contents(obj, cm);
}
Пример #2
0
void GangWorker::run_task(WorkData data) {
  GCIdMark gc_id_mark(data._task->gc_id());
  log_develop_trace(gc, workgang)("Running work gang: %s task: %s worker: %u", name(), data._task->name(), data._worker_id);

  data._task->work(data._worker_id);

  log_develop_trace(gc, workgang)("Finished work gang: %s task: %s worker: %u thread: " PTR_FORMAT,
                                  name(), data._task->name(), data._worker_id, p2i(Thread::current()));
}
void KlassScanClosure::do_klass(Klass* klass) {
  NOT_PRODUCT(ResourceMark rm);
  log_develop_trace(gc, scavenge)("KlassScanClosure::do_klass " PTR_FORMAT ", %s, dirty: %s",
                                  p2i(klass),
                                  klass->external_name(),
                                  klass->has_modified_oops() ? "true" : "false");

  // If the klass has not been dirtied we know that there's
  // no references into  the young gen and we can skip it.
  if (klass->has_modified_oops()) {
    if (_accumulate_modified_oops) {
      klass->accumulate_modified_oops();
    }

    // Clear this state since we're going to scavenge all the metadata.
    klass->clear_modified_oops();

    // Tell the closure which Klass is being scanned so that it can be dirtied
    // if oops are left pointing into the young gen.
    _scavenge_closure->set_scanned_klass(klass);

    klass->oops_do(_scavenge_closure);

    _scavenge_closure->set_scanned_klass(NULL);
  }
}
Пример #4
0
// The current implementation will exit if the allocation
// of any worker fails.
void  AbstractWorkGang::initialize_workers() {
  log_develop_trace(gc, workgang)("Constructing work gang %s with %u threads", name(), total_workers());
  _workers = NEW_C_HEAP_ARRAY(AbstractGangWorker*, total_workers(), mtInternal);
  if (_workers == NULL) {
    vm_exit_out_of_memory(0, OOM_MALLOC_ERROR, "Cannot create GangWorker array.");
  }

  add_workers(true);
}
Пример #5
0
void AbstractGangWorker::initialize() {
  this->record_stack_base_and_size();
  this->initialize_named_thread();
  assert(_gang != NULL, "No gang to run in");
  os::set_priority(this, NearMaxPriority);
  log_develop_trace(gc, workgang)("Running gang worker for gang %s id %u", gang()->name(), id());
  // The VM thread should not execute here because MutexLocker's are used
  // as (opposed to MutexLockerEx's).
  assert(!Thread::current()->is_VM_thread(), "VM thread should not be part"
         " of a work gang");
}
Пример #6
0
  bool insert_deadspace(HeapWord* dead_start, HeapWord* dead_end) {
    if (!_active) {
      return false;
    }

    size_t dead_length = pointer_delta(dead_end, dead_start);
    if (_allowed_deadspace_words >= dead_length) {
      _allowed_deadspace_words -= dead_length;
      CollectedHeap::fill_with_object(dead_start, dead_length);
      oop obj = oop(dead_start);
      obj->set_mark(obj->mark()->set_marked());

      assert(dead_length == (size_t)obj->size(), "bad filler object size");
      log_develop_trace(gc, compaction)("Inserting object to dead space: " PTR_FORMAT ", " PTR_FORMAT ", " SIZE_FORMAT "b",
          p2i(dead_start), p2i(dead_end), dead_length * HeapWordSize);

      return true;
    } else {
      _active = false;
      return false;
    }
  }
inline void ParScanClosure::do_oop_work(T* p,
                                        bool gc_barrier,
                                        bool root_scan) {
  assert((!GenCollectedHeap::heap()->is_in_reserved(p) ||
          generation()->is_in_reserved(p))
         && (GenCollectedHeap::heap()->is_young_gen(generation()) || gc_barrier),
         "The gen must be right, and we must be doing the barrier "
         "in older generations.");
  T heap_oop = oopDesc::load_heap_oop(p);
  if (!oopDesc::is_null(heap_oop)) {
    oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
    if ((HeapWord*)obj < _boundary) {
#ifndef PRODUCT
      if (_g->to()->is_in_reserved(obj)) {
        tty->print_cr("Scanning field (" PTR_FORMAT ") twice?", p2i(p));
        GenCollectedHeap* gch = GenCollectedHeap::heap();
        Space* sp = gch->space_containing(p);
        oop obj = oop(sp->block_start(p));
        assert((HeapWord*)obj < (HeapWord*)p, "Error");
        tty->print_cr("Object: " PTR_FORMAT, p2i((void *)obj));
        tty->print_cr("-------");
        obj->print();
        tty->print_cr("-----");
        tty->print_cr("Heap:");
        tty->print_cr("-----");
        gch->print();
        ShouldNotReachHere();
      }
#endif
      // OK, we need to ensure that it is copied.
      // We read the klass and mark in this order, so that we can reliably
      // get the size of the object: if the mark we read is not a
      // forwarding pointer, then the klass is valid: the klass is only
      // overwritten with an overflow next pointer after the object is
      // forwarded.
      Klass* objK = obj->klass();
      markOop m = obj->mark();
      oop new_obj;
      if (m->is_marked()) { // Contains forwarding pointer.
        new_obj = ParNewGeneration::real_forwardee(obj);
        oopDesc::encode_store_heap_oop_not_null(p, new_obj);
        log_develop_trace(gc, scavenge)("{%s %s ( " PTR_FORMAT " ) " PTR_FORMAT " -> " PTR_FORMAT " (%d)}",
                                        "forwarded ",
                                        new_obj->klass()->internal_name(), p2i(p), p2i((void *)obj), p2i((void *)new_obj), new_obj->size());
      } else {
        size_t obj_sz = obj->size_given_klass(objK);
        new_obj = _g->copy_to_survivor_space(_par_scan_state, obj, obj_sz, m);
        oopDesc::encode_store_heap_oop_not_null(p, new_obj);
        if (root_scan) {
          // This may have pushed an object.  If we have a root
          // category with a lot of roots, can't let the queue get too
          // full:
          (void)_par_scan_state->trim_queues(10 * ParallelGCThreads);
        }
      }
      if (is_scanning_a_klass()) {
        do_klass_barrier();
      } else if (gc_barrier) {
        // Now call parent closure
        par_do_barrier(p);
      }
    }
  }
}