mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Make ary_replace() to share entry buffers if possible.
This commit is contained in:
+28
-1
@@ -349,12 +349,39 @@ mrb_ary_plus(mrb_state *mrb, mrb_value self)
|
||||
return mrb_obj_value(a2);
|
||||
}
|
||||
|
||||
#define ARY_REPLACE_SHARED_MIN 20
|
||||
|
||||
static void
|
||||
ary_replace(mrb_state *mrb, struct RArray *a, struct RArray *b)
|
||||
{
|
||||
mrb_int len = ARY_LEN(b);
|
||||
|
||||
ary_modify(mrb, a);
|
||||
ary_modify_check(mrb, a);
|
||||
if (a == b) return;
|
||||
if (ARY_SHARED_P(a)) {
|
||||
mrb_ary_decref(mrb, a->as.heap.aux.shared);
|
||||
a->as.heap.aux.capa = 0;
|
||||
a->as.heap.len = 0;
|
||||
a->as.heap.ptr = NULL;
|
||||
ARY_UNSET_SHARED_FLAG(a);
|
||||
}
|
||||
if (ARY_SHARED_P(b)) {
|
||||
shared_b:
|
||||
if (ARY_EMBED_P(a)) {
|
||||
ARY_UNSET_EMBED_FLAG(a);
|
||||
}
|
||||
a->as.heap.ptr = b->as.heap.ptr;
|
||||
a->as.heap.len = len;
|
||||
a->as.heap.aux.shared = b->as.heap.aux.shared;
|
||||
a->as.heap.aux.shared->refcnt++;
|
||||
ARY_SET_SHARED_FLAG(a);
|
||||
mrb_write_barrier(mrb, (struct RBasic*)a);
|
||||
return;
|
||||
}
|
||||
if (!MRB_FROZEN_P(b) && len > ARY_REPLACE_SHARED_MIN) {
|
||||
ary_make_shared(mrb, b);
|
||||
goto shared_b;
|
||||
}
|
||||
if (ARY_CAPA(a) < len)
|
||||
ary_expand_capa(mrb, a, len);
|
||||
array_copy(ARY_PTR(a), ARY_PTR(b), len);
|
||||
|
||||
Reference in New Issue
Block a user