Class: RubyVM::RJIT::ExitCompiler

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_vm/rjit/exit_compiler.rb

Instance Method Summary collapse

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

Parameters:



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.

Parameters:



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

Parameters:



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

Parameters:



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

Parameters:



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