コード例 #1
0
  void ObjectMemory::find_referers(Object* target, ObjectArray& result) {
    ObjectMemory::GCInhibit inhibitor(this);

    ObjectWalker walker(root_state_->om);
    GCData gc_data(root_state_);

    // Seed it with the root objects.
    walker.seed(gc_data);

    Object* obj = walker.next();

    RefererFinder rf(this, target);

    while(obj) {
      rf.reset();

      rf.scan_object(obj);

      if(rf.found_p()) {
        result.push_back(obj);
      }

      obj = walker.next();
    }
  }
コード例 #2
0
  void ObjectMemory::snapshot(STATE) {
    // Assign all objects an object id...
    ObjectMemory::GCInhibit inhibitor(root_state_->om);

    // Walk the heap over and over until we don't create
    // any more objects...

    size_t last_seen = 0;

    while(last_object_id != last_seen) {
      last_seen = last_object_id;

      ObjectWalker walker(root_state_->om);
      GCData gc_data(state->vm());

      // Seed it with the root objects.
      walker.seed(gc_data);

      Object* obj = walker.next();

      while(obj) {
        obj->id(state);
        obj = walker.next();
      }
    }

    // Now, save the current value of last_object_id, since thats
    // so we can compare later to find all new objects.
    last_snapshot_id = last_object_id;

    std::cout << "Snapshot taken: " << last_snapshot_id << "\n";
  }
コード例 #3
0
  void ObjectMemory::print_new_since_snapshot(STATE) {
    // Assign all objects an object id...
    ObjectMemory::GCInhibit inhibitor(root_state_->om);

    ObjectWalker walker(root_state_->om);
    GCData gc_data(root_state_);

    // Seed it with the root objects.
    walker.seed(gc_data);

    Object* obj = walker.next();

    // All reference ids are shifted up
    native_int check_id = (native_int)last_snapshot_id << 1;

    int count = 0;
    int bytes = 0;

    while(obj) {
      if(!obj->has_id(state) || obj->id(state)->to_native() > check_id) {
        count++;
        bytes += obj->size_in_bytes(state->vm());

        if(kind_of<String>(obj)) {
          std::cout << "#<String:" << obj << ">\n";
        } else {
          std::cout << obj->to_s(state, true)->c_str(state) << "\n";
        }
      }

      obj = walker.next();
    }

    std::cout << count << " objects since snapshot.\n";
    std::cout << bytes << " bytes since snapshot.\n";
  }
コード例 #4
0
ファイル: find_object.cpp プロジェクト: Azzurrio/rubinius
  Object* System::vm_find_object(STATE, GCToken gct,
                                 Array* arg, Object* callable,
                                 CallFrame* calling_environment)
  {
    ObjectMemory::GCInhibit inhibitor(state->memory());

    // Support an aux mode, where callable is an array and we just append
    // objects to it rather than #call it.
    Array* ary = try_as<Array>(callable);
    if(!ary) ary = nil<Array>();

    Array* args = Array::create(state, 1);

    int total = 0;

    QueryCondition* condition = create_condition(state, arg);
    if(!condition) return Fixnum::from(0);

    Object* ret = cNil;

    // Special case for looking for an immediate
    if(Object* obj = condition->immediate()) {
      if(Symbol* sym = try_as<Symbol>(obj)) {
        // Check whether this is actually a valid symbol, not
        // some random non existing symbol.
        if(!state->shared().symbols.lookup_string(state, sym)) {
          delete condition;
          std::ostringstream msg;
          msg << "Invalid symbol 0x" << std::hex << reinterpret_cast<uintptr_t>(sym);
          Exception::range_error(state, msg.str().c_str());
          return 0;
        }
      }
      if(!ary->nil_p()) {
        ary->append(state, obj);
      } else {
        args->set(state, 0, obj);
        ret = callable->send(state, calling_environment, G(sym_call),
                             args, cNil, false);
      }

      delete condition;
      if(!ret) return 0;
      return Fixnum::from(1);
    }

    OnStack<2> os(state, ary, args);

    state->set_call_frame(calling_environment);
    ObjectWalker walker(state->memory());
    GCData gc_data(state->vm());

    {
      StopTheWorld stw(state, gct, calling_environment);
      // Seed it with the root objects.
      walker.seed(gc_data);
    }

    Object* obj = walker.next();

    while(obj) {
      if(condition->perform(state, obj)) {
        total++;

        if(!ary->nil_p()) {
          ary->append(state, obj);
        } else {
          // We call back into Ruby land here, so that might trigger a GC
          // This ensures we mark all the locations of the current search
          // queue for the walker, so we update these object references
          // properly.
          Object** stack_buf = walker.stack_buf();
          size_t stack_size  = walker.stack_size();

          Object** variable_buffer[stack_size];
          for(size_t i = 0; i < stack_size; ++i) {
            variable_buffer[i] = &stack_buf[i];
          }
          VariableRootBuffer vrb(state->vm()->current_root_buffers(),
                                 variable_buffer, stack_size);
          args->set(state, 0, obj);
          ret = callable->send(state, calling_environment, G(sym_call),
                               args, cNil, false);
          if(!ret) break;
        }
      }

      obj = walker.next();
    }

    delete condition;

    if(!ret) return 0;

    return Integer::from(state, total);
  }