Ejemplo n.º 1
0
  Object* Class::allocate(STATE) {
    Object* obj = cNil;
    object_type obj_type = type_info()->type;

    if(obj_type == PackedObject::type) {
      obj = allocate_packed(state, this);
    } else if(!type_info()->allow_user_allocate || kind_of<SingletonClass>(this)) {
      std::ostringstream msg;
      msg << "direct allocation disabled for ";
      if(kind_of<SingletonClass>(this)) {
         msg << to_string(state);
      } else {
         msg << module_name()->debug_str(state);
      }
      Exception::raise_type_error(state, msg.str().c_str());
    } else if(obj_type == Object::type) {
      auto_pack(state);
      obj = allocate_packed(state, this);
    } else {
      // type_info()->type is neither PackedObject nor Object, so use the
      // generic path.
      obj = state->memory()->new_object<Object>(
          state, this, type_info()->instance_size, obj_type);
    }

#ifdef RBX_ALLOC_TRACKING
    if(unlikely(state->vm()->allocation_tracking())) {
      new_obj->setup_allocation_site(state);
    }
#endif

    return obj;
  }
Ejemplo n.º 2
0
Object* Class::allocate(STATE, GCToken gct, CallFrame* calling_environment) {
    object_type obj_type = type_info_->type;

    if(obj_type == PackedObject::type) {
        Object* new_obj = allocate_packed(state, gct, this, calling_environment);
#ifdef RBX_ALLOC_TRACKING
        if(unlikely(state->vm()->allocation_tracking())) {
            new_obj->setup_allocation_site(state, calling_environment);
        }
#endif
#ifdef RBX_GC_STRESS
        state->shared().gc_soon();
#endif
        return new_obj;
    } else if(!type_info_->allow_user_allocate || kind_of<SingletonClass>(this)) {
        std::ostringstream msg;
        msg << "direct allocation disabled for ";
        if(kind_of<SingletonClass>(this)) {
            msg << to_string(state);
        } else {
            msg << module_name()->debug_str(state);
        }
        Exception::type_error(state, msg.str().c_str());
        return cNil;
    } else if(obj_type == Object::type) {
        // transition all normal object classes to PackedObject
        Class* self = this;
        OnStack<1> os(state, self);

        auto_pack(state, gct, calling_environment);
        Object* new_obj = allocate_packed(state, gct, self, calling_environment);
#ifdef RBX_ALLOC_TRACKING
        if(unlikely(state->vm()->allocation_tracking())) {
            new_obj->setup_allocation_site(state, calling_environment);
        }
#endif
#ifdef RBX_GC_STRESS
        state->shared().gc_soon();
#endif
        return new_obj;
    } else {
        // type_info_->type is neither PackedObject nor Object, so use the
        // generic path.
        Object* new_obj = state->vm()->new_object_typed(this,
                          type_info_->instance_size, obj_type);
#ifdef RBX_ALLOC_TRACKING
        if(unlikely(state->vm()->allocation_tracking())) {
            new_obj->setup_allocation_site(state, calling_environment);
        }
#endif
#ifdef RBX_GC_STRESS
        state->shared().gc_soon();
#endif
        return new_obj;
    }
}
Ejemplo n.º 3
0
  Object* Class::allocate(STATE, GCToken gct, CallFrame* calling_environment) {
    if(type_info_->type == PackedObject::type) {
      Object* new_obj = allocate_packed(state, gct, this, calling_environment);
#ifdef RBX_ALLOC_TRACKING
      if(unlikely(state->vm()->allocation_tracking())) {
        new_obj->setup_allocation_site(state, calling_environment);
      }
#endif
      return new_obj;
    } else if(!type_info_->allow_user_allocate || kind_of<SingletonClass>(this)) {
      Exception::type_error(state, "direct allocation disabled");
      return cNil;
    } else if(type_info_->type == Object::type) {
      // transition all normal object classes to PackedObject
      Class* self = this;
      OnStack<1> os(state, self);

      auto_pack(state, gct);
      Object* new_obj = allocate_packed(state, gct, this, calling_environment);
#ifdef RBX_ALLOC_TRACKING
      if(unlikely(state->vm()->allocation_tracking())) {
        new_obj->setup_allocation_site(state, calling_environment);
      }
#endif
      return new_obj;
    } else {
      // type_info_->type is neither PackedObject nor Object, so use the
      // generic path.
      Object* new_obj = state->vm()->new_object_typed(this,
          type_info_->instance_size, type_info_->type);
#ifdef RBX_ALLOC_TRACKING
      if(unlikely(state->vm()->allocation_tracking())) {
        new_obj->setup_allocation_site(state, calling_environment);
      }
#endif
      return new_obj;
    }
  }
Ejemplo n.º 4
0
  Object* Class::allocate(STATE, CallFrame* calling_environment) {
    if(type_info_->type == PackedObject::type) {
use_packed:
      assert(packed_size_ > 0);

      // Pull the size out into a local to deal with this moving later on.
      uint32_t size = packed_size_;

      PackedObject* obj = state->local_slab().allocate(size).as<PackedObject>();

      if(likely(obj)) {
        obj->init_header(this, YoungObjectZone, PackedObject::type);
      } else {
        if(state->shared.om->refill_slab(state, state->local_slab())) {
          obj = state->local_slab().allocate(size).as<PackedObject>();

          if(likely(obj)) {
            obj->init_header(this, YoungObjectZone, PackedObject::type);
          } else {
            obj = reinterpret_cast<PackedObject*>(
                state->om->new_object_fast(state, this, size, PackedObject::type));
          }
        } else {
          state->shared.om->collect_young_now = true;

          Class* self = this;

          OnStack<1> os(state, self);

          state->collect_maybe(calling_environment);

          // Don't use 'this' after here! it's been moved! use 'self'!

          obj = state->local_slab().allocate(size).as<PackedObject>();

          if(likely(obj)) {
            obj->init_header(self, YoungObjectZone, PackedObject::type);
          } else {
            obj = reinterpret_cast<PackedObject*>(
                state->om->new_object_fast(state, self, size, PackedObject::type));
          }
        }
      }

      // Don't use 'this' !!! The above code might have GC'd

      uintptr_t body = reinterpret_cast<uintptr_t>(obj->body_as_array());
      for(size_t i = 0; i < size - sizeof(ObjectHeader);
          i += sizeof(Object*)) {
        Object** pos = reinterpret_cast<Object**>(body + i);
        *pos = Qundef;
      }

      return obj;
    } else if(!type_info_->allow_user_allocate || kind_of<SingletonClass>(this)) {
      Exception::type_error(state, "direct allocation disabled");
      return Qnil;
    } else if(type_info_->type == Object::type) {
      // transition all normal object classes to PackedObject
      auto_pack(state);
      goto use_packed;
    }

    // type_info_->type is neither PackedObject nor Object, so use the
    // generic path.
    return state->new_object_typed(this,
        type_info_->instance_size, type_info_->type);
  }