summaryrefslogtreecommitdiff
path: root/lib/ruby_vm/rjit/insn_compiler.rb
diff options
context:
space:
mode:
authorTakashi Kokubun <[email protected]>2023-04-01 21:23:36 -0700
committerTakashi Kokubun <[email protected]>2023-04-01 21:30:42 -0700
commite45ed2da5046f7ee2a82f332d211ddbd7108fc22 (patch)
treee65ce9898be564eb21f234351b7c4b77f283b266 /lib/ruby_vm/rjit/insn_compiler.rb
parent90cdc5b8ba5421bfd183c2bfba16c1fd3ca7e0f5 (diff)
RJIT: Rewind stack_size on CantCompile and side exits
so that we can take an exit whenever we want. As a starter, this commit also pops blockarg earlier than some CantCompile exits.
Diffstat (limited to 'lib/ruby_vm/rjit/insn_compiler.rb')
-rw-r--r--lib/ruby_vm/rjit/insn_compiler.rb23
1 files changed, 12 insertions, 11 deletions
diff --git a/lib/ruby_vm/rjit/insn_compiler.rb b/lib/ruby_vm/rjit/insn_compiler.rb
index 62074eafaf..27031dc0e3 100644
--- a/lib/ruby_vm/rjit/insn_compiler.rb
+++ b/lib/ruby_vm/rjit/insn_compiler.rb
@@ -4237,7 +4237,10 @@ module RubyVM::RJIT
# Number of locals that are not parameters
num_locals = iseq.body.local_table_size - num_params
- # blockarg is currently popped later
+ # Pop blockarg after all side exits
+ if flags & C::VM_CALL_ARGS_BLOCKARG != 0
+ ctx.stack_pop(1)
+ end
if block_handler == C::VM_BLOCK_HANDLER_NONE && iseq.body.builtin_attrs & C::BUILTIN_ATTR_LEAF != 0
if jit_leaf_builtin_func(jit, ctx, asm, flags, iseq)
@@ -4290,11 +4293,6 @@ module RubyVM::RJIT
return CantCompile
end
- # Pop blockarg after all side exits
- if flags & C::VM_CALL_ARGS_BLOCKARG != 0
- ctx.stack_pop(1)
- end
-
# Setup the new frame
frame_type ||= C::VM_FRAME_MAGIC_METHOD | C::VM_ENV_FLAG_LOCAL
jit_push_frame(
@@ -5187,12 +5185,15 @@ module RubyVM::RJIT
# @param jit [RubyVM::RJIT::JITState]
# @param ctx [RubyVM::RJIT::Context]
def side_exit(jit, ctx)
- if side_exit = jit.side_exits[jit.pc]
- return side_exit
+ # We use the latest ctx.sp_offset to generate a side exit to tolerate sp_offset changes by jit_save_sp.
+ # However, we want to simulate an old stack_size when we take a side exit. We do that by adjusting the
+ # sp_offset because gen_outlined_exit uses ctx.sp_offset to move SP.
+ ctx = ctx.with_stack_size(jit.stack_size_for_pc)
+
+ jit.side_exit_for_pc[ctx.sp_offset] ||= Assembler.new.then do |asm|
+ @exit_compiler.compile_side_exit(jit.pc, ctx, asm)
+ @ocb.write(asm)
end
- asm = Assembler.new
- @exit_compiler.compile_side_exit(jit.pc, ctx, asm)
- jit.side_exits[jit.pc] = @ocb.write(asm)
end
def counted_exit(side_exit, name)