Exemplo n.º 1
0
  /* Look at this class and it's superclass contents (which includes
   * included modules) and calculate out how to allocate the slots.
   *
   * This locks the class so that construction is serialized.
   */
  void Class::auto_pack(STATE) {
    hard_lock(state);

    // If another thread did this work while we were waiting on the lock,
    // don't redo it.
    if(type_info_->type == PackedObject::type) return;

    size_t slots = 0;

    LookupTable* lt = LookupTable::create(state);

    // If autopacking is enabled, figure out how many slots to use.
    if(state->shared.config.gc_autopack) {
      Module* mod = this;

      int slot = 0;

      while(!mod->nil_p()) {
        Array* info = 0;

        if(Class* cls = try_as<Class>(mod)) {
          info = cls->seen_ivars();
        } else if(IncludedModule* im = try_as<IncludedModule>(mod)) {
          info = im->module()->seen_ivars();
        }

        if(info && !info->nil_p()) {
          for(size_t i = 0; i < info->size(); i++) {
            if(Symbol* sym = try_as<Symbol>(info->get(state, i))) {
              bool found = false;
              lt->fetch(state, sym, &found);

              if(!found) {
                lt->store(state, sym, Fixnum::from(slot++));
              }
            }

            // Limit the number of packed ivars to 25.
            if(slot > 25) break;
          }
        }

        mod = mod->superclass();
      }
      slots = lt->entries()->to_native();
    }

    packed_size_ = sizeof(Object) + (slots * sizeof(Object*));
    packed_ivar_info(state, lt);

    set_object_type(state, PackedObject::type);

    hard_unlock(state);
  }
Exemplo n.º 2
0
  Object* Class::set_packed(STATE, Array* info) {
    // Only transition Object typed objects to Packed
    if(type_info_->type != Object::type) return Fixnum::from(1);

    // Reject methods that already have packing.
    if(packed_size_) return Fixnum::from(2);

    LookupTable* lt = LookupTable::create(state);

    size_t s = info->size();
    for(size_t i = 0; i < s; i++) {
      Symbol* sym = as<Symbol>(info->get(state, i));
      lt->store(state, sym, Fixnum::from(i));
    }

    packed_size_ = sizeof(Object) + (s * sizeof(Object*));
    packed_ivar_info(state, lt);

    set_object_type(state, PackedObject::type);

    return Qtrue;
  }
Exemplo n.º 3
0
  Object* Class::set_superclass(STATE, Object* obj) {
    if(obj->nil_p()) {
      superclass(state, (Class*)Qnil);
      return Qnil;
    }

    Class* sup;
    if((sup = try_as<Class>(obj)) == 0) {
      return Primitives::failure();
    }

    superclass(state, sup);

    instance_type(state, sup->instance_type());
    set_type_info(sup->type_info());

    packed_ivar_info(state, sup->packed_ivar_info());
    set_packed_size(sup->packed_size());

    MetaClass::attach(state, this, sup->metaclass(state));

    return Qnil;
  }