summaryrefslogtreecommitdiff
path: root/include/ruby/internal/intern
diff options
context:
space:
mode:
authorAlan Wu <XrXr@users.noreply.github.com>2025-07-25 22:09:51 -0400
committerAlan Wu <XrXr@users.noreply.github.com>2025-07-28 15:30:50 -0400
commitff428b4dd0c5f0a07abbd8f8520d8d1e4bff8d66 (patch)
tree3a374489edb8903846e08651f5ad81b5d82a3e69 /include/ruby/internal/intern
parent5ca71364ff6cf4a9c445cb2701b1eb4770e79579 (diff)
ZJIT: Keep a frame pointer and use it for memory params
Previously, ZJIT miscompiled the following because of native SP interference. def a(n1,n2,n3,n4,n5,n6,n7,n8) = [n8] a(0,0,0,0,0,0,0, :ok) Commented problematic disassembly: ; call rb_ary_new_capa mov x0, #1 mov x16, #0x1278 movk x16, #0x4bc, lsl #16 movk x16, #1, lsl #32 blr x16 ; call rb_ary_push mov x1, x0 str x1, [sp, #-0x10]! ; c_push() from alloc_regs() mov x0, x1 ; arg0, the array ldur x1, [sp] ; meant to be arg1=n8, but sp just moved! mov x16, #0x3968 movk x16, #0x4bc, lsl #16 movk x16, #1, lsl #32 blr x16 Since the frame pointer stays constant in the body of the function, static offsets based on it don't run the risk of being invalidated by SP movements. Pass the registers to preserve through Insn::FrameSetup. This allows ARM to use STP and waste no gaps between EC, SP, and CFP. x86 now preserves and restores RBP since we use it as the frame pointer. Since all arches now have a frame pointer, remove offset based SP movement in the epilogue and restore registers using the frame pointer.
Diffstat (limited to 'include/ruby/internal/intern')
0 files changed, 0 insertions, 0 deletions