Skip to content

Commit 053e1e9

Browse files
committed
Fixed Array#concat.
Amortizing the allocation costs over the number of elements requires doubling the capacity rather than using the exact size needed.
1 parent 52c2849 commit 053e1e9

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

vm/builtin/array.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,10 +194,20 @@ namespace rubinius {
194194
// There is enough space in the current tuple, so just copy into it.
195195
tuple_->copy_from(state, other->tuple(), other->start(), other->total(), total_);
196196
} else {
197+
native_int s = size();
198+
199+
if(s == 0) s = 2;
200+
while(s <= new_size) s *= 2;
201+
197202
// We need to create a bigger tuple, then copy both tuples into it.
198-
Tuple* nt = Tuple::create_dirty(state, new_size);
203+
Tuple* nt = Tuple::create_dirty(state, s);
199204
nt->copy_from(state, tuple_, start_, total_, Fixnum::from(0));
200205
nt->copy_from(state, other->tuple(), other->start(), other->total(), total_);
206+
207+
for(native_int i = new_size; i < s; i++) {
208+
nt->put_nil(i);
209+
}
210+
201211
tuple(state, nt);
202212
}
203213

vm/builtin/tuple.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ namespace rubinius {
3737
// Rubinius.primitive :tuple_at
3838
Object* at_prim(STATE, Fixnum* pos);
3939

40+
void put_nil(native_int idx) {
41+
field[idx] = cNil;
42+
}
43+
4044
Object* put(STATE, native_int idx, Object* val) {
4145
field[idx] = val;
4246
write_barrier(state, val);

0 commit comments

Comments
 (0)