Skip to content
Browse files

Introduce creating a dirty Tuple

This can be used for cases where after the tuple is created, immediately
values are set. This results in not having to set all entries to nil
first if they are overwritten afterwards.
  • Loading branch information...
1 parent c3e8ad8 commit 3ac462096cd52f478ad6aca6aff36d94502b817b @dbussink dbussink committed Aug 23, 2013
View
10 vm/arguments.cpp
@@ -2,7 +2,7 @@
namespace rubinius {
void Arguments::append(STATE, Array* ary) {
- Tuple* tup = Tuple::create(state, ary->size() + total());
+ Tuple* tup = Tuple::create_dirty(state, ary->size() + total());
for(uint32_t i = 0; i < total(); i++) {
tup->put(state, i, get_argument(i));
@@ -17,7 +17,7 @@ namespace rubinius {
}
void Arguments::prepend(STATE, Array* ary) {
- Tuple* tup = Tuple::create(state, ary->size() + total());
+ Tuple* tup = Tuple::create_dirty(state, ary->size() + total());
for(native_int i = 0; i < ary->size(); i++) {
tup->put(state, i, ary->get(state, i));
@@ -42,7 +42,7 @@ namespace rubinius {
}
void Arguments::unshift(STATE, Object* val) {
- Tuple* tup = Tuple::create(state, total() + 1);
+ Tuple* tup = Tuple::create_dirty(state, total() + 1);
tup->put(state, 0, val);
@@ -54,7 +54,7 @@ namespace rubinius {
}
void Arguments::unshift2(STATE, Object* one, Object* two) {
- Tuple* tup = Tuple::create(state, total() + 2);
+ Tuple* tup = Tuple::create_dirty(state, total() + 2);
tup->put(state, 0, one);
tup->put(state, 1, two);
@@ -70,7 +70,7 @@ namespace rubinius {
Object* first = arguments_[0];
if(argument_container_) {
- Tuple* tup = Tuple::create(state, total() - 1);
+ Tuple* tup = Tuple::create_dirty(state, total() - 1);
for(uint32_t i = 1; i < total_; i++) {
tup->put(state, i - 1, get_argument(i));
}
View
4 vm/builtin/array.cpp
@@ -55,7 +55,7 @@ namespace rubinius {
ary->total(state, Fixnum::from(0));
ary->tuple(state, Tuple::create(state, 0));
} else {
- Tuple* tup = Tuple::create(state, total);
+ Tuple* tup = Tuple::create_dirty(state, total);
Tuple* orig = tuple_;
for(native_int i = 0, j = start->to_native(); i < total; i++, j++) {
@@ -236,7 +236,7 @@ namespace rubinius {
start(state, Fixnum::from(lend-1));
total(state, Fixnum::from(new_size));
} else {
- Tuple* nt = Tuple::create(state, new_size);
+ Tuple* nt = Tuple::create_dirty(state, new_size);
nt->copy_from(state, tuple_, start_, total_,
Fixnum::from(1));
nt->put(state, 0, val);
View
2 vm/builtin/encoding.cpp
@@ -114,7 +114,7 @@ namespace rubinius {
}
static Tuple* encoding_reference(STATE, int index, const char* alias_name = 0) {
- Tuple* pair = Tuple::create(state, 2);
+ Tuple* pair = Tuple::create_dirty(state, 2);
if(!alias_name) {
pair->put(state, 0, cNil);
} else {
View
2 vm/builtin/float.cpp
@@ -431,7 +431,7 @@ namespace rubinius {
char buf[FLOAT_TO_S_STRLEN];
int length = double_to_ascii(buf, FLOAT_TO_S_STRLEN, val, &sign, &decpt);
- Tuple* result = Tuple::create(state, 4);
+ Tuple* result = Tuple::create_dirty(state, 4);
result->put(state, 0, String::create(state, buf, length));
result->put(state, 1, Fixnum::from(decpt));
result->put(state, 2, Fixnum::from(sign));
View
2 vm/builtin/regexp.cpp
@@ -399,7 +399,7 @@ namespace rubinius {
}
static Tuple* _md_region_to_tuple(STATE, OnigRegion *region, int pos) {
- Tuple* tup = Tuple::create(state, region->num_regs - 1);
+ Tuple* tup = Tuple::create_dirty(state, region->num_regs - 1);
for(int i = 1; i < region->num_regs; i++) {
int beg = region->beg[i];
View
2 vm/builtin/system.cpp
@@ -1545,7 +1545,7 @@ namespace rubinius {
Tuple* System::vm_thread_state(STATE) {
VMThreadState* ts = state->vm()->thread_state();
- Tuple* tuple = Tuple::create(state, 5);
+ Tuple* tuple = Tuple::create_dirty(state, 5);
Symbol* reason = 0;
switch(ts->raise_reason()) {
View
37 vm/builtin/tuple.cpp
@@ -42,16 +42,6 @@ namespace rubinius {
return field[index];
}
- Object* Tuple::put(STATE, native_int idx, Object* val) {
- if(idx < 0 || idx >= num_fields()) {
- rubinius::bug("Invalid tuple index");
- }
-
- field[idx] = val;
- write_barrier(state, val);
- return val;
- }
-
/* The Tuple#put primitive. */
Object* Tuple::put_prim(STATE, Fixnum* index, Object* val) {
native_int idx = index->to_native();
@@ -99,6 +89,25 @@ namespace rubinius {
return tup;
}
+ Tuple* Tuple::create_dirty(STATE, native_int fields) {
+ // Fast path using GC optimized tuple creation
+ Tuple* tup = state->vm()->new_young_tuple_dirty(fields);
+
+ if(likely(tup)) return tup;
+
+ // Slow path.
+
+ size_t bytes = 0;
+
+ tup = state->vm()->new_object_variable<Tuple>(G(tuple), fields, bytes);
+ if(unlikely(!tup)) {
+ Exception::memory_error(state);
+ } else {
+ tup->full_size_ = bytes;
+ }
+ return tup;
+ }
+
Tuple* Tuple::allocate(STATE, Fixnum* fields) {
native_int size = fields->to_native();
@@ -110,12 +119,8 @@ namespace rubinius {
}
Tuple* Tuple::from(STATE, native_int fields, ...) {
- if(fields < 0) {
- rubinius::bug("Invalid tuple size");
- }
-
va_list ar;
- Tuple* tup = create(state, fields);
+ Tuple* tup = create_dirty(state, fields);
va_start(ar, fields);
for(native_int i = 0; i < fields; i++) {
@@ -300,7 +305,7 @@ namespace rubinius {
Exception::argument_error(state, "negative tuple size");
}
- Tuple* tuple = Tuple::create(state, cnt);
+ Tuple* tuple = Tuple::create_dirty(state, cnt);
for(native_int i = 0; i < cnt; i++) {
// bounds checking is covered because we instantiated the tuple
View
7 vm/builtin/tuple.hpp
@@ -21,6 +21,7 @@ namespace rubinius {
static void init(STATE);
static Tuple* create(STATE, native_int fields);
+ static Tuple* create_dirty(STATE, native_int fields);
static Tuple* from(STATE, native_int fields, ...);
/** Shift all elements leftward, clear old slots. */
@@ -36,7 +37,11 @@ namespace rubinius {
// Rubinius.primitive :tuple_at
Object* at_prim(STATE, Fixnum* pos);
- Object* put(STATE, native_int idx, Object* val);
+ Object* put(STATE, native_int idx, Object* val) {
+ field[idx] = val;
+ write_barrier(state, val);
+ return val;
+ }
// Rubinius.primitive :tuple_put
Object* put_prim(STATE, Fixnum* idx, Object* val);
View
4 vm/builtin/variable_scope.cpp
@@ -69,7 +69,7 @@ namespace rubinius {
}
Tuple* VariableScope::locals(STATE) {
- Tuple* tup = Tuple::create(state, number_of_locals_);
+ Tuple* tup = Tuple::create_dirty(state, number_of_locals_);
for(int i = 0; i < number_of_locals_; i++) {
tup->put(state, i, get_local(state, i));
}
@@ -184,7 +184,7 @@ namespace rubinius {
void VariableScope::flush_to_heap_internal(STATE) {
if(isolated_) return;
- Tuple* new_locals = Tuple::create(state, number_of_locals_);
+ Tuple* new_locals = Tuple::create_dirty(state, number_of_locals_);
for(int i = 0; i < number_of_locals_; i++) {
new_locals->put(state, i, locals_[i]);
}
View
2 vm/instructions.def
@@ -2061,7 +2061,7 @@ instruction zsuper(literal) [ block -- value ]
}
}
- Tuple* tup = Tuple::create(state, arg_count);
+ Tuple* tup = Tuple::create_dirty(state, arg_count);
for(int i = 0; i < mc->total_args; i++) {
tup->put(state, i, scope->get_local(state, i));
}
View
2 vm/llvm/jit_util.cpp
@@ -193,7 +193,7 @@ extern "C" {
}
}
- Tuple* tup = Tuple::create(state, arg_count);
+ Tuple* tup = Tuple::create_dirty(state, arg_count);
for(int i = 0; i < v->total_args; i++) {
tup->put(state, i, scope->get_local(state, i));
}
View
4 vm/machine_code.cpp
@@ -299,15 +299,15 @@ namespace rubinius {
}
Tuple* MachineCode::call_sites(STATE) {
- Tuple* sites = Tuple::create(state, number_of_call_sites_);
+ Tuple* sites = Tuple::create_dirty(state, number_of_call_sites_);
for(size_t i = 0; i < number_of_call_sites_; ++i) {
sites->put(state, i, call_site(state, call_site_offsets_[i]));
}
return sites;
}
Tuple* MachineCode::constant_caches(STATE) {
- Tuple* caches = Tuple::create(state, number_of_constant_caches_);
+ Tuple* caches = Tuple::create_dirty(state, number_of_constant_caches_);
for(size_t i = 0; i < number_of_constant_caches_; ++i) {
caches->put(state, i, constant_cache(state, constant_cache_offsets_[i]));
}
View
2 vm/marshal.cpp
@@ -140,7 +140,7 @@ namespace rubinius {
size_t count;
stream >> count;
- Tuple* tup = Tuple::create(state, count);
+ Tuple* tup = Tuple::create_dirty(state, count);
for(size_t i = 0; i < count; i++) {
tup->put(state, i, unmarshal());

0 comments on commit 3ac4620

Please sign in to comment.
Something went wrong with that request. Please try again.