Class: RubyVM::RJIT::ExitCompiler
- Inherits:
-
Object
- Object
- RubyVM::RJIT::ExitCompiler
- Defined in:
- lib/ruby_vm/rjit/exit_compiler.rb
Instance Method Summary collapse
- #compile_branch_stub(ctx, asm, branch_stub, target0_p) ⇒ Object
-
#compile_entry_exit(pc, ctx, asm, cause:) ⇒ Object
Used for invalidating a block on entry.
- #compile_entry_stub(asm, entry_stub) ⇒ Object
-
#compile_full_cfunc_return(asm) ⇒ Object
Fire cfunc events on invalidation by TracePoint.
-
#compile_leave_exit(asm) ⇒ Object
Set to cfp->jit_return by default for leave insn.
- #compile_side_exit(pc, ctx, asm) ⇒ Object
-
#initialize ⇒ ExitCompiler
constructor
A new instance of ExitCompiler.
Constructor Details
#initialize ⇒ ExitCompiler
Returns a new instance of ExitCompiler.
3 |
# File 'lib/ruby_vm/rjit/exit_compiler.rb', line 3 def initialize = freeze |
Instance Method Details
#compile_branch_stub(ctx, asm, branch_stub, target0_p) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/ruby_vm/rjit/exit_compiler.rb', line 97 def compile_branch_stub(ctx, asm, branch_stub, target0_p) # Call rb_rjit_branch_stub_hit iseq = branch_stub.iseq if C.rjit_opts.dump_disasm && C.imemo_type_p(iseq, C.imemo_iseq) # Guard against ISEQ GC at random moments asm.comment("branch stub hit: #{iseq.body.location.label}@#{C.rb_iseq_path(iseq)}:#{iseq_lineno(iseq, target0_p ? branch_stub.target0.pc : branch_stub.target1.pc)}") end asm.mov(:rdi, to_value(branch_stub)) asm.mov(:esi, ctx.sp_offset) asm.mov(:edx, target0_p ? 1 : 0) asm.call(C.rb_rjit_branch_stub_hit) # Jump to the address returned by rb_rjit_branch_stub_hit asm.jmp(:rax) end |
#compile_entry_exit(pc, ctx, asm, cause:) ⇒ Object
Used for invalidating a block on entry.
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/ruby_vm/rjit/exit_compiler.rb', line 8 def compile_entry_exit(pc, ctx, asm, cause:) # Fix pc/sp offsets for the interpreter save_pc_and_sp(pc, ctx, asm, reset_sp_offset: false) # Increment per-insn exit counter count_insn_exit(pc, asm) # Restore callee-saved registers asm.comment("#{cause}: entry exit") asm.pop(SP) asm.pop(EC) asm.pop(CFP) asm.mov(C_RET, Qundef) asm.ret end |
#compile_entry_stub(asm, entry_stub) ⇒ Object
83 84 85 86 87 88 89 90 91 |
# File 'lib/ruby_vm/rjit/exit_compiler.rb', line 83 def compile_entry_stub(asm, entry_stub) # Call rb_rjit_entry_stub_hit asm.comment('entry stub hit') asm.mov(C_ARGS[0], to_value(entry_stub)) asm.call(C.rb_rjit_entry_stub_hit) # Jump to the address returned by rb_rjit_entry_stub_hit asm.jmp(:rax) end |
#compile_full_cfunc_return(asm) ⇒ Object
Fire cfunc events on invalidation by TracePoint
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/ruby_vm/rjit/exit_compiler.rb', line 41 def compile_full_cfunc_return(asm) # This chunk of code expects REG_EC to be filled properly and # RAX to contain the return value of the C method. asm.comment('full cfunc return') asm.mov(C_ARGS[0], EC) asm.mov(C_ARGS[1], :rax) asm.call(C.rjit_full_cfunc_return) # TODO: count the exit # Restore callee-saved registers asm.pop(SP) asm.pop(EC) asm.pop(CFP) asm.mov(C_RET, Qundef) asm.ret end |
#compile_leave_exit(asm) ⇒ Object
Set to cfp->jit_return by default for leave insn
27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/ruby_vm/rjit/exit_compiler.rb', line 27 def compile_leave_exit(asm) asm.comment('default cfp->jit_return') # Restore callee-saved registers asm.pop(SP) asm.pop(EC) asm.pop(CFP) # :rax is written by #leave asm.ret end |
#compile_side_exit(pc, ctx, asm) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/ruby_vm/rjit/exit_compiler.rb', line 64 def compile_side_exit(pc, ctx, asm) # Fix pc/sp offsets for the interpreter save_pc_and_sp(pc, ctx.dup, asm) # dup to avoid sp_offset update # Increment per-insn exit counter count_insn_exit(pc, asm) # Restore callee-saved registers asm.comment("exit to interpreter on #{pc_to_insn(pc).name}") asm.pop(SP) asm.pop(EC) asm.pop(CFP) asm.mov(C_RET, Qundef) asm.ret end |