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; }
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); }
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()); }
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)); }
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); }
/* 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); }
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); }
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); }
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); }
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); }
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)); }
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); }
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); }
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; }
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); }
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); }
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; }
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); }
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); }
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))); } }
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; }
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())); }
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; }
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; }
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++)); } }
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; }
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; }