Ejemplo n.º 1
0
  LookupTable* SetCounter::to_ruby(VM* state) {
    LookupTable* tbl = LookupTable::create(state);

    tbl->store(state, stats::total(state), Integer::from(state, total_));
    tbl->store(state, stats::max(state), Integer::from(state, max()));
    tbl->store(state, stats::min(state), Integer::from(state, min()));
    tbl->store(state, stats::average(state), Float::create(state, moving_average()));

    return tbl;
  }
Ejemplo n.º 2
0
  void test_store_overwrites_previous() {
    TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 0);
    tbl->store(state, cNil, Fixnum::from(47));
    TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 1);

    Object* out = tbl->aref(state, cNil);
    TS_ASSERT_EQUALS(as<Integer>(out)->to_native(), 47);

    tbl->store(state, cNil, Fixnum::from(42));
    TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 1);

    out = tbl->aref(state, cNil);
    TS_ASSERT_EQUALS(as<Integer>(out)->to_native(), 42);
  }
Ejemplo n.º 3
0
  void test_remove_works_for_chained_bins() {
    Object* k1 = Fixnum::from((4 << 5)  | 31);
    Object* k2 = Fixnum::from((10 << 5) | 31);
    Object* k3 = Fixnum::from((11 << 5) | 31);
    tbl->store(state, k1, cNil);
    tbl->store(state, k2, cTrue);
    tbl->store(state, k3, cFalse);

    TS_ASSERT_EQUALS(tbl->remove(state, k3), cFalse);
    TS_ASSERT_EQUALS(tbl->remove(state, k2), cTrue);
    TS_ASSERT_EQUALS(tbl->remove(state, k1), cNil);

    TS_ASSERT_EQUALS(0, as<Integer>(tbl->entries())->to_native());
  }
Ejemplo n.º 4
0
  void Transcoding::declare(STATE, const char* from, const char* to, const char* lib) {
    LookupTable* map = Encoding::transcoding_map(state);
    Object* obj = map->fetch(state, encoding_symbol(state, from));
    LookupTable* table;

    if(obj->nil_p()) {
      table = LookupTable::create(state);
      map->store(state, encoding_symbol(state, from), table);
    } else {
      table = as<LookupTable>(obj);
    }

    table->store(state, encoding_symbol(state, to), String::create(state, lib));
  }
Ejemplo n.º 5
0
  void Transcoding::define(STATE, OnigTranscodingType* tr) {
    LookupTable* map = Encoding::transcoding_map(state);
    Object* obj = map->fetch(state, encoding_symbol(state, tr->src_encoding));
    LookupTable* table;

    if(obj->nil_p()) {
      table = LookupTable::create(state);
      map->store(state, encoding_symbol(state, tr->src_encoding), table);
    } else {
      table = as<LookupTable>(obj);
    }

    Transcoding* t = Transcoding::create(state, tr);
    table->store(state, encoding_symbol(state, tr->dst_encoding), t);
  }
Ejemplo n.º 6
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, GCToken gct) {
    Class* self = this;
    OnStack<1> os(state, self);

    hard_lock(state, gct);

    // If another thread did this work while we were waiting on the lock,
    // don't redo it.
    if(self->type_info_->type == PackedObject::type) {
      hard_unlock(state, gct);
      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 = self;

      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*));
    self->packed_ivar_info(state, lt);

    self->set_object_type(state, PackedObject::type);

    self->hard_unlock(state, gct);
  }
Ejemplo n.º 7
0
  void test_fetch_returns_found() {
    TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 0);
    tbl->store(state, Qnil, Fixnum::from(47));
    TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 1);

    Object* out = tbl->fetch(state, Qnil, Qundef);
    TS_ASSERT_EQUALS(as<Integer>(out)->to_native(), 47);
  }
Ejemplo n.º 8
0
  void test_fetch_returns_given_when_not_found() {
    TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 0);
    tbl->store(state, cNil, Fixnum::from(47));
    TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 1);

    Object* out = tbl->fetch(state, cTrue, cUndef);
    TS_ASSERT_EQUALS(cUndef, out);
  }
Ejemplo n.º 9
0
  void test_store_resizes_table_with_chained_bins() {
    size_t i;
    size_t bins = tbl-> bins()->to_native() - 2;

    Object* k1 = Fixnum::from((4 << 5)  | 31);
    Object* k2 = Fixnum::from((10 << 5) | 31);
    Object* k3 = Fixnum::from((11 << 5) | 31);
    tbl->store(state, k1, cTrue);
    tbl->store(state, k2, cTrue);
    tbl->store(state, k3, cTrue);

    for(i = 0; i < bins; i++) {
      tbl->store(state, Fixnum::from(i), cTrue);
    }

    TS_ASSERT((size_t)(tbl-> bins()->to_native()) > bins);
  }
Ejemplo n.º 10
0
  void test_store_fetch() {
    TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 0);
    tbl->store(state, Qnil, Fixnum::from(47));
    TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 1);

    Object* out = tbl->aref(state, Qnil);
    TS_ASSERT_EQUALS(as<Integer>(out)->to_native(), 47);
  }
Ejemplo n.º 11
0
  void test_has_key() {
    Object* k1 = Fixnum::from(4);
    TS_ASSERT_EQUALS(cFalse, tbl->has_key(state, k1));

    tbl->store(state, k1, cTrue);

    TS_ASSERT_EQUALS(cTrue, tbl->has_key(state, k1));
  }
Ejemplo n.º 12
0
  void test_dup() {
    Object* k1 = Fixnum::from(4);

    tbl->store(state, k1, cTrue);

    LookupTable* tbl2 = tbl->duplicate(state);

    TS_ASSERT_EQUALS(tbl2->aref(state, k1), cTrue);
  }
Ejemplo n.º 13
0
  void test_all_keys() {
    Object* k1 = Fixnum::from(4);

    tbl->store(state, k1, cTrue);
    Array* ary = tbl->all_keys(state);

    TS_ASSERT_EQUALS(ary->total()->to_native(), 1);
    TS_ASSERT_EQUALS(ary->get(state, 0), k1);
  }
Ejemplo n.º 14
0
LookupTable* CompactLookupTable::to_lookuptable(STATE) {
    LookupTable* tbl = (LookupTable*)LookupTable::create(state);

    for(unsigned int i = 0; i < COMPACTLOOKUPTABLE_SIZE; i += 2) {
        Object* key = at(state, i);
        if(!key->nil_p()) tbl->store(state, key, at(state, i + 1));
    }

    return tbl;
}
Ejemplo n.º 15
0
  void test_find() {
    Object* k = Fixnum::from(47);
    tbl->store(state, k, cTrue);

    Object* out = tbl->find(state, k);
    TS_ASSERT_EQUALS(out, cTrue);

    out = tbl->find(state, Fixnum::from(40));
    TS_ASSERT(out == cUndef);
  }
Ejemplo n.º 16
0
  void test_find_entry() {
    Object* k = Fixnum::from(47);
    tbl->store(state, k, cTrue);

    LookupTableBucket* entry = tbl->find_entry(state, k);
    TS_ASSERT(entry != cNil);
    TS_ASSERT_EQUALS(entry->key(),k);
    TS_ASSERT_EQUALS(entry->value(),cTrue);

    entry = tbl->find_entry(state, Fixnum::from(40));
    TS_ASSERT(entry == cNil);
  }
Ejemplo n.º 17
0
  static int _gather_names(const UChar *name, const UChar *name_end,
      int ngroup_num, int *group_nums, regex_t *reg, struct _gather_data *gd) {

    int gn;
    STATE;
    LookupTable* tbl = gd->tbl;

    state = gd->state;

    gn = group_nums[0];
    tbl->store(state, state->symbol((char*)name), Fixnum::from(gn - 1));
    return 0;
  }
Ejemplo n.º 18
0
  void test_remove() {
    Object* k = Fixnum::from(47);
    tbl->store(state, k, cTrue);

    Object* out = tbl->find(state, k);
    TS_ASSERT_EQUALS(out, cTrue);

    out = tbl->remove(state, k);
    TS_ASSERT_EQUALS(out, cTrue);
    TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 0);

    out = tbl->fetch(state, k);
    TS_ASSERT_EQUALS(out, cNil);
  }
Ejemplo n.º 19
0
  void test_store_handles_entries_in_same_bin() {
    Object* k1 = Fixnum::from((4 << 4)  | 15);
    Object* k2 = Fixnum::from((10 << 4) | 15);
    Object* k3 = Fixnum::from((11 << 4) | 15);
    Object* v1 = cTrue;
    Object* v2 = cFalse;
    Object* v3 = cTrue;

    tbl->store(state, k1, v1);
    tbl->store(state, k2, v2);
    tbl->store(state, k3, v3);
    TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 3);

    LookupTableBucket* entry = tbl->find_entry(state, k1);
    TS_ASSERT(entry != cNil);

    TS_ASSERT(entry->next() != cNil);
    TS_ASSERT_EQUALS(entry->next()->key(), k2);

    entry = tbl->find_entry(state, k3);
    TS_ASSERT(entry != cNil);
    TS_ASSERT_EQUALS(entry->key(), k3);
  }
Ejemplo n.º 20
0
  void test_store_resizes_table() {
    size_t i;
    size_t bins = tbl-> bins()->to_native();

    for(i = 0; i < bins; i++) {
      tbl->store(state, Fixnum::from(i), Fixnum::from(i));
    }

    TS_ASSERT_EQUALS(i, (size_t)as<Integer>(tbl->entries())->to_native());

    TS_ASSERT((size_t)(tbl-> bins()->to_native()) > bins);

    for(i = 0; i < bins; i++) {
      TS_ASSERT_EQUALS(Fixnum::from(i), tbl->aref(state, Fixnum::from(i)));
    }
  }
Ejemplo n.º 21
0
  VALUE rb_protect_inspect(VALUE (*func)(VALUE a, VALUE b), VALUE h_obj, VALUE h_arg) {
    NativeMethodEnvironment* env = NativeMethodEnvironment::get();
    STATE = env->state();

    Thread* thr = Thread::current(state);
    LookupTable* rectbl = thr->recursive_objects();

    Object* obj = env->get_object(h_obj);

    Object* id = obj->id(state);

    bool found = false;
    rectbl->fetch(state, id, &found);

    if(found) {
      return (*func)(h_obj, h_arg);
    }

    rectbl->store(state, id, cTrue);

    VALUE ret = Qnil;

    ExceptionPoint ep(env);
    PLACE_EXCEPTION_POINT(ep);

    bool unwinding = false;

    if(unlikely(ep.jumped_to())) {
      unwinding = true;
    } else {
      ret = (*func)(h_obj, h_arg);
    }

    ep.pop(env);

    // Get the thread and table again, the GC might have fun.
    thr = Thread::current(state);
    rectbl = thr->recursive_objects();
    obj = env->get_object(h_obj);
    id = obj->id(state);

    rectbl->remove(state, id);

    if(unwinding) env->current_ep()->return_to(env);

    return ret;
  }
Ejemplo n.º 22
0
  void test_remove_redistributes() {
    size_t bins = tbl-> bins()->to_native();
    size_t bound = bins * 2;

    for(size_t i = 0; i < bound; i++) {
      tbl->store(state, Fixnum::from(i), cTrue);
    }

    TS_ASSERT(bins < (size_t)tbl-> bins()->to_native());

    for(size_t i = 0; i < bound; i++) {
      Object* out = tbl->remove(state, Fixnum::from(i));
      TS_ASSERT_EQUALS(out, cTrue);
    }

    TS_ASSERT_EQUALS(bins, static_cast<unsigned int>(tbl-> bins()->to_native()));
  }
Ejemplo n.º 23
0
  LookupTable* LookupTable::dup(STATE) {
    size_t size, i;
    LookupTable *dup;

    size = bins_->to_native();
    dup = LookupTable::create(state, size);
    state->om->set_class(dup, class_object(state));
    size_t num = entries_->to_native();

    Array* entries = all_entries(state);
    for(i = 0; i < num; i++) {
      Tuple* entry = as<Tuple>(entries->get(state, i));
      Object* key =   entry->at(state, 0);
      Object* value = entry->at(state, 1);
      dup->store(state, key, value);
    }
    return dup;

  }
Ejemplo n.º 24
0
  LookupTable* LookupTable::duplicate(STATE) {
    size_t size, i;
    LookupTable *dup;

    size = bins_->to_native();
    dup = LookupTable::create(state, size);

    // Allow for subclassing.
    dup->klass(state, class_object(state));

    size_t num = entries_->to_native();

    Array* entries = all_entries(state);
    for(i = 0; i < num; i++) {
      LookupTableBucket* entry = as<LookupTableBucket>(entries->get(state, i));
      dup->store(state, entry->key(), entry->value());
    }
    return dup;
  }
Ejemplo n.º 25
0
    void Metrics::init_ruby_metrics(STATE) {
      LookupTable* map = LookupTable::create(state);
      Module* mod = as<Module>(G(rubinius)->get_const(state, state->symbol("Metrics")));
      mod->set_const(state, "Map", map);

      Tuple* values = Tuple::create(state, metrics_map_.size());
      values_.set(values);
      mod->set_const(state, "Values", values);

      int index = 0;

      for(MetricsMap::iterator i = metrics_map_.begin();
          i != metrics_map_.end();
          ++i)
      {
        values->put(state, index, Bignum::from(state, (*i)->second));

        Object* key = reinterpret_cast<Object*>(state->symbol((*i)->first.c_str()));
        map->store(state, key, Fixnum::from(index++));
      }
    }
Ejemplo n.º 26
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;
  }
Ejemplo n.º 27
0
  LookupTable* GCStats::to_ruby(VM* state) {
    LookupTable* tbl;
    LookupTable* gc_tbl = LookupTable::create(state);

    tbl = collect_young.to_ruby(state);
    tbl->store(state, state->symbol("objects_copied"), objects_copied.to_ruby(state));
    tbl->store(state, state->symbol("bytes_copied"), bytes_copied.to_ruby(state));
    tbl->store(state, state->symbol("objects_promoted"), objects_promoted.to_ruby(state));
    tbl->store(state, state->symbol("lifetimes"), lifetimes.to_ruby(state));
    gc_tbl->store(state, state->symbol("collect_young"), tbl);

    tbl = allocate_young.to_ruby(state);
    tbl->store(state, bytes_allocated(state), young_bytes_allocated.to_ruby(state));
    tbl->store(state, state->symbol("object_types"), young_object_types.to_ruby(state));
    gc_tbl->store(state, state->symbol("allocate_young"), tbl);

    tbl = collect_mature.to_ruby(state);
    tbl->store(state, state->symbol("objects_seen"), objects_seen.to_ruby(state));
    gc_tbl->store(state, state->symbol("collect_mature"), tbl);

    tbl = allocate_mature.to_ruby(state);
    tbl->store(state, bytes_allocated(state), mature_bytes_allocated.to_ruby(state));
    tbl->store(state, state->symbol("chunks_added"), chunks_added.to_ruby(state));
    tbl->store(state, state->symbol("large_objects"), large_objects.to_ruby(state));
    tbl->store(state, state->symbol("object_types"), mature_object_types.to_ruby(state));
    gc_tbl->store(state, state->symbol("allocate_mature"), tbl);

    gc_tbl->store(state, state->symbol("clock"), clock.to_ruby(state));

    return gc_tbl;
  }