diff options
author | Peter Zhu <peter@peterzhu.ca> | 2023-09-01 10:07:32 -0400 |
---|---|---|
committer | Peter Zhu <peter@peterzhu.ca> | 2023-09-04 08:50:27 -0400 |
commit | 4cc56592932d36c202b2366ffe7ad71db2f5ea0b (patch) | |
tree | ce40a99f55ad6c7634ea223670fdb81692f5a36f /array.c | |
parent | 2ac3e9abe98579261a21a2e33df16f1bff1ebc1d (diff) |
Keep write-barrier status after splicing array
We don't need to remove the write-barrier protected status after
splicing an array. We can simply add it to the rememberset for marking
during the next GC.
The benchmark illustrates the performance impact on minor GC:
```
require "benchmark"
arys = 1_000_000.times.map do
ary = Array.new(50)
ary.insert(1, 3)
ary
end
4.times { GC.start }
puts(Benchmark.measure do
1000.times do
GC.start(full_mark: false)
end
end)
```
This branch:
```
1.309910 0.004342 1.314252 ( 1.314580)
```
Master branch:
```
54.376091 0.219037 54.595128 ( 54.742996)
```
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/8350
Diffstat (limited to 'array.c')
-rw-r--r-- | array.c | 11 |
1 files changed, 8 insertions, 3 deletions
@@ -2176,9 +2176,14 @@ rb_ary_splice(VALUE ary, long beg, long len, const VALUE *rptr, long rlen) ARY_SET_LEN(ary, alen); } if (rlen > 0) { - if (rofs != -1) rptr = RARRAY_CONST_PTR(ary) + rofs; - /* give up wb-protected ary */ - RB_OBJ_WB_UNPROTECT_FOR(ARRAY, ary); + if (rofs == -1) { + rb_gc_writebarrier_remember(ary); + } + else { + /* In this case, we're copying from a region in this array, so + * we don't need to fire the write barrier. */ + rptr = RARRAY_CONST_PTR(ary) + rofs; + } /* do not use RARRAY_PTR() because it can causes GC. * ary can contain T_NONE object because it is not cleared. |