Skip to content

Commit

Permalink
RJIT: Implement throw insn
Browse files Browse the repository at this point in the history
  • Loading branch information
k0kubun committed Mar 18, 2023
1 parent 39cd74d commit 45a1701
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 7 deletions.
43 changes: 36 additions & 7 deletions lib/ruby_vm/rjit/insn_compiler.rb
Expand Up @@ -18,7 +18,7 @@ def compile(jit, ctx, asm, insn)
asm.incr_counter(:rjit_insns_count)
asm.comment("Insn: #{insn.name}")

# 74/102
# 75/102
case insn.name
when :nop then nop(jit, ctx, asm)
when :getlocal then getlocal(jit, ctx, asm)
Expand Down Expand Up @@ -82,7 +82,7 @@ def compile(jit, ctx, asm, insn)
when :invokesuper then invokesuper(jit, ctx, asm)
when :invokeblock then invokeblock(jit, ctx, asm)
when :leave then leave(jit, ctx, asm)
# throw
when :throw then throw(jit, ctx, asm)
when :jump then jump(jit, ctx, asm)
when :branchif then branchif(jit, ctx, asm)
when :branchunless then branchunless(jit, ctx, asm)
Expand Down Expand Up @@ -1308,7 +1308,37 @@ def leave(jit, ctx, asm)
EndBlock
end

# throw
# @param jit [RubyVM::RJIT::JITState]
# @param ctx [RubyVM::RJIT::Context]
# @param asm [RubyVM::RJIT::Assembler]
def throw(jit, ctx, asm)
throw_state = jit.operand(0)
asm.mov(:rcx, ctx.stack_pop(1)) # throwobj

# THROW_DATA_NEW allocates. Save SP for GC and PC for allocation tracing as
# well as handling the catch table. However, not using jit_prepare_routine_call
# since we don't need a patch point for this implementation.
jit_save_pc(jit, asm) # clobbers rax
jit_save_sp(ctx, asm)

# rb_vm_throw verifies it's a valid throw, sets ec->tag->state, and returns throw
# data, which is throwobj or a vm_throw_data wrapping it. When ec->tag->state is
# set, JIT code callers will handle the throw with vm_exec_handle_exception.
asm.mov(C_ARGS[0], EC)
asm.mov(C_ARGS[1], CFP)
asm.mov(C_ARGS[2], throw_state)
# asm.mov(C_ARGS[3], :rcx) # same reg
asm.call(C.rb_vm_throw)

asm.comment('exit from throw')
asm.pop(SP)
asm.pop(EC)
asm.pop(CFP)

# return C_RET as C_RET
asm.ret
EndBlock
end

# @param jit [RubyVM::RJIT::JITState]
# @param ctx [RubyVM::RJIT::Context]
Expand Down Expand Up @@ -2810,10 +2840,10 @@ def jit_equality_specialized(jit, ctx, asm, gen_eq)
def jit_prepare_routine_call(jit, ctx, asm)
jit.record_boundary_patch_point = true
jit_save_pc(jit, asm)
jit_save_sp(jit, ctx, asm)
jit_save_sp(ctx, asm)
end

# Note: This clobbers :rax
# NOTE: This clobbers :rax
# @param jit [RubyVM::RJIT::JITState]
# @param asm [RubyVM::RJIT::Assembler]
def jit_save_pc(jit, asm, comment: 'save PC to CFP')
Expand All @@ -2823,10 +2853,9 @@ def jit_save_pc(jit, asm, comment: 'save PC to CFP')
asm.mov([CFP, C.rb_control_frame_t.offsetof(:pc)], :rax)
end

# @param jit [RubyVM::RJIT::JITState]
# @param ctx [RubyVM::RJIT::Context]
# @param asm [RubyVM::RJIT::Assembler]
def jit_save_sp(jit, ctx, asm)
def jit_save_sp(ctx, asm)
if ctx.sp_offset != 0
asm.comment('save SP to CFP')
asm.lea(SP, ctx.sp_opnd)
Expand Down
1 change: 1 addition & 0 deletions rjit_c.c
Expand Up @@ -494,6 +494,7 @@ extern bool rb_vm_defined(rb_execution_context_t *ec, rb_control_frame_t *reg_cf
extern bool rb_vm_ic_hit_p(IC ic, const VALUE *reg_ep);
extern rb_event_flag_t rb_rjit_global_events;
extern void rb_vm_setinstancevariable(const rb_iseq_t *iseq, VALUE obj, ID id, VALUE val, IVC ic);
extern VALUE rb_vm_throw(const rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, rb_num_t throw_state, VALUE throwobj);

#include "rjit_c.rbinc"

Expand Down
4 changes: 4 additions & 0 deletions rjit_c.rb
Expand Up @@ -580,6 +580,10 @@ def C.rb_vm_splat_array
Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_vm_splat_array) }
end

def C.rb_vm_throw
Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_vm_throw) }
end

def C.rjit_full_cfunc_return
Primitive.cexpr! %q{ SIZET2NUM((size_t)rjit_full_cfunc_return) }
end
Expand Down
1 change: 1 addition & 0 deletions tool/rjit/bindgen.rb
Expand Up @@ -515,6 +515,7 @@ def push_target(target)
rjit_str_neq_internal
rjit_record_exit_stack
rb_ivar_defined
rb_vm_throw
],
types: %w[
CALL_DATA
Expand Down

0 comments on commit 45a1701

Please sign in to comment.