From 5533c2983373a9fca5a97074ebe9258841ce4d00 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 22 Jul 2020 14:21:05 +0900 Subject: Use `mrb_field_write_barrier` instead of `mrb_write_barrier` for `push`. When the array is very big, the simpler `mrb_write_barrier` causes calling `gc_mark_children` for big arrays repeatedly. That would hinder performance very badly. --- src/array.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/array.c') diff --git a/src/array.c b/src/array.c index dae2fbf34..eb94fc6c7 100644 --- a/src/array.c +++ b/src/array.c @@ -522,8 +522,10 @@ mrb_ary_push_m(mrb_state *mrb, mrb_value self) } array_copy(ARY_PTR(a)+len, argv, alen); ARY_SET_LEN(a, len2); - mrb_write_barrier(mrb, (struct RBasic*)a); - + while (alen--) { + mrb_field_write_barrier_value(mrb, (struct RBasic*)a, *argv); + argv++; + } return self; } -- cgit v1.2.3 From 097f525817d0825f12780adfc8542bb7f3db1302 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 22 Jul 2020 14:23:10 +0900 Subject: Avoid using `mrb_ary_modify` from the internal function. `mrb_ary_modify` calls `mrb_write_barrier`, so can cause the same problem of the past `push`. It is provided for use-level API. --- src/array.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/array.c') diff --git a/src/array.c b/src/array.c index eb94fc6c7..ef8588d31 100644 --- a/src/array.c +++ b/src/array.c @@ -943,7 +943,7 @@ mrb_ary_aset(mrb_state *mrb, mrb_value self) mrb_value v1, v2, v3; mrb_int i, len; - mrb_ary_modify(mrb, mrb_ary_ptr(self)); + ary_modify(mrb, mrb_ary_ptr(self)); if (mrb_get_argc(mrb) == 2) { mrb_value *vs = mrb_get_argv(mrb); v1 = vs[0]; v2 = vs[1]; -- cgit v1.2.3