aboutsummaryrefslogtreecommitdiffstats
path: root/insns.def
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2023-11-30 10:51:51 -0500
committerPeter Zhu <peter@peterzhu.ca>2023-12-01 17:13:56 -0500
commit0aed37b973c66e9ff071a1f46944cb0c6151d2dc (patch)
treee6f785c47230ebeb7ad341e61495bfaa73b1c32e /insns.def
parent492c82cb417a92d1941f10b52e77ec0c4b2cc8a6 (diff)
downloadruby-0aed37b973c66e9ff071a1f46944cb0c6151d2dc.tar.gz
Make expandarray compaction safe
The expandarray instruction can allocate an array, which can trigger a GC compaction. However, since it does not increment the sp until the end of the instruction, the objects it places on the stack are not marked or reference updated by the GC, which can cause the objects to move which leaves broken or incorrect objects on the stack. This commit changes the instruction to be handles_sp so the sp is incremented inside of the instruction right after the object is written on the stack.
Diffstat (limited to 'insns.def')
-rw-r--r--insns.def3
1 files changed, 2 insertions, 1 deletions
diff --git a/insns.def b/insns.def
index b784d7c043..b33dcf20fb 100644
--- a/insns.def
+++ b/insns.def
@@ -498,10 +498,11 @@ expandarray
(rb_num_t num, rb_num_t flag)
(..., VALUE ary)
(...)
+// attr bool handles_sp = true;
// attr bool leaf = false; /* has rb_check_array_type() */
// attr rb_snum_t sp_inc = (rb_snum_t)num - 1 + (flag & 1 ? 1 : 0);
{
- vm_expandarray(GET_SP(), ary, num, (int)flag);
+ vm_expandarray(GET_CFP(), ary, num, (int)flag);
}
/* concat two arrays */