예제 #1
0
파일: gc.cpp 프로젝트: soaexpert/rubinius
  /* Understands how to read the inside of an object and find all references
   * located within. It copies the objects pointed to, but does not follow into
   * those further (ie, not recursive) */
  void GarbageCollector::scan_object(Object* obj) {
    Object* slot;

    // If this object's refs are weak, then add it to the weak_refs
    // vector and don't look at it otherwise.
    if(obj->RefsAreWeak) {
      if(!weak_refs) {
        weak_refs = new ObjectArray(0);
      }

      weak_refs->push_back(obj);
      return;
    }

    if(obj->klass() && obj->klass()->reference_p()) {
      slot = saw_object(obj->klass());
      if(slot) object_memory->set_class(obj, slot);
    }

    if(obj->ivars() && obj->ivars()->reference_p()) {
      slot = saw_object(obj->ivars());
      if(slot) obj->ivars(object_memory->state, slot);
    }

    TypeInfo* ti = object_memory->type_info[obj->obj_type];
    assert(ti);

    ObjectMark mark(this);
    ti->mark(obj, mark);
  }
예제 #2
0
/**
 * Scans the specified Object +obj+ for references to other Objects, and
 * marks those Objects as reachable. Understands how to read the inside of
 * an Object and find all references located within. For each reference
 * found, it marks the object pointed to as live (which may trigger
 * movement of the object in a copying garbage collector), but does not
 * recursively scan into the referenced object (since such recursion could
 * be arbitrarily deep, depending on the object graph, and this could cause
 * the stack to blow up).
 * /param obj The Object to be scanned for references to other Objects.
 */
void GarbageCollector::scan_object(Object* obj) {
    Object* slot;

#ifdef ENABLE_OBJECT_WATCH
    if(watched_p(obj)) {
        std::cout << "detected " << obj << " during scan_object.\n";
    }
#endif

    // Check and update an inflated header
    if(obj->inflated_header_p()) {
        obj->inflated_header()->reset_object(obj);
    }

    slot = saw_object(obj->klass());
    if(slot) obj->klass(object_memory_, force_as<Class>(slot));

    if(obj->ivars()->reference_p()) {
        slot = saw_object(obj->ivars());
        if(slot) obj->ivars(object_memory_, slot);
    }

    // Handle Tuple directly, because it's so common
    if(Tuple* tup = try_as<Tuple>(obj)) {
        int size = tup->num_fields();

        for(int i = 0; i < size; i++) {
            slot = tup->field[i];
            if(slot->reference_p()) {
                slot = saw_object(slot);
                if(slot) {
                    tup->field[i] = slot;
                    object_memory_->write_barrier(tup, slot);
                }
            }
        }
    } else {
        TypeInfo* ti = object_memory_->type_info[obj->type_id()];

        ObjectMark mark(this);
        ti->mark(obj, mark);
    }
}
예제 #3
0
파일: gc.cpp 프로젝트: Azzurrio/rubinius
  /**
   * Scans the specified Object +obj+ for references to other Objects, and
   * marks those Objects as reachable. Understands how to read the inside of
   * an Object and find all references located within. For each reference
   * found, it marks the object pointed to as live (which may trigger
   * movement of the object in a copying garbage collector), but does not
   * recursively scan into the referenced object (since such recursion could
   * be arbitrarily deep, depending on the object graph, and this could cause
   * the stack to blow up).
   * /param obj The Object to be scanned for references to other Objects.
   */
  void GarbageCollector::scan_object(Object* obj) {
#ifdef ENABLE_OBJECT_WATCH
    if(watched_p(obj)) {
      std::cout << "detected " << obj << " during scan_object.\n";
    }
#endif
    // We set scanned here before we finish scanning the object.
    // This is done so we don't have a race condition while we're
    // scanning the object and another thread updates a field during
    // the phase where the object is partially scanned.
    scanned_object(obj);

    if(Object* klass = saw_object(obj->klass())) {
      obj->klass(object_memory_, force_as<Class>(klass));
    }

    if(obj->ivars()->reference_p()) {
      if(Object* ivars = saw_object(obj->ivars())) {
        obj->ivars(object_memory_, ivars);
      }
    }

    // Handle Tuple directly, because it's so common
    if(Tuple* tup = try_as<Tuple>(obj)) {
      native_int size = tup->num_fields();

      for(native_int i = 0; i < size; i++) {
        Object* slot = tup->field[i];
        if(slot->reference_p()) {
          if(Object* moved = saw_object(slot)) {
            tup->field[i] = moved;
            object_memory_->write_barrier(tup, moved);
          }
        }
      }
    } else {
      TypeInfo* ti = object_memory_->type_info[obj->type_id()];

      ObjectMark mark(this);
      ti->mark(obj, mark);
    }
  }