class RubyVM::RJIT::JITState

Public Class Methods

new(side_exit_for_pc: {}, record_boundary_patch_point: false, **) click to toggle source
Calls superclass method
# File ruby_vm/rjit/jit_state.rb, line 11
  def initialize(side_exit_for_pc: {}, record_boundary_patch_point: false, **) = super

  def insn
    Compiler.decode_insn(C.VALUE.new(pc).*)
  end

  def operand(index, signed: false, ruby: false)
    addr = pc + (index + 1) * Fiddle::SIZEOF_VOIDP
    value = Fiddle::Pointer.new(addr)[0, Fiddle::SIZEOF_VOIDP].unpack(signed ? 'q' : 'Q')[0]
    if ruby
      value = C.to_ruby(value)
    end
    value
  end

  def at_current_insn?
    pc == cfp.pc.to_i
  end

  def peek_at_local(n)
    local_table_size = iseq.body.local_table_size
    offset = -C::VM_ENV_DATA_SIZE - local_table_size + n + 1
    value = (cfp.ep + offset).*
    C.to_ruby(value)
  end

  def peek_at_stack(depth_from_top)
    raise 'not at current insn' unless at_current_insn?
    offset = -(1 + depth_from_top)
    # rb_rjit_branch_stub_hit updates SP, so you don't need to worry about sp_offset
    value = (cfp.sp + offset).*
    C.to_ruby(value)
  end

  def peek_at_self
    C.to_ruby(cfp.self)
  end

  def peek_at_block_handler(level)
    ep = ep_at_level(cfp, level:)
    ep[C::VM_ENV_DATA_INDEX_SPECVAL]
  end

  private

  def ep_at_level(cfp, level:)
    ep = cfp.ep
    level.times do
      # VM_ENV_PREV_EP
      ep = C.VALUE.new(ep[C::VM_ENV_DATA_INDEX_SPECVAL] & ~0x03)
    end
    ep
  end
end

Public Instance Methods

at_current_insn?() click to toggle source
# File ruby_vm/rjit/jit_state.rb, line 26
def at_current_insn?
  pc == cfp.pc.to_i
end
ep_at_level(cfp, level:) click to toggle source
# File ruby_vm/rjit/jit_state.rb, line 56
def ep_at_level(cfp, level:)
  ep = cfp.ep
  level.times do
    # VM_ENV_PREV_EP
    ep = C.VALUE.new(ep[C::VM_ENV_DATA_INDEX_SPECVAL] & ~0x03)
  end
  ep
end
insn() click to toggle source
# File ruby_vm/rjit/jit_state.rb, line 13
def insn
  Compiler.decode_insn(C.VALUE.new(pc).*)
end
operand(index, signed: false, ruby: false) click to toggle source
# File ruby_vm/rjit/jit_state.rb, line 17
def operand(index, signed: false, ruby: false)
  addr = pc + (index + 1) * Fiddle::SIZEOF_VOIDP
  value = Fiddle::Pointer.new(addr)[0, Fiddle::SIZEOF_VOIDP].unpack(signed ? 'q' : 'Q')[0]
  if ruby
    value = C.to_ruby(value)
  end
  value
end
peek_at_block_handler(level) click to toggle source
# File ruby_vm/rjit/jit_state.rb, line 49
def peek_at_block_handler(level)
  ep = ep_at_level(cfp, level:)
  ep[C::VM_ENV_DATA_INDEX_SPECVAL]
end
peek_at_local(n) click to toggle source
# File ruby_vm/rjit/jit_state.rb, line 30
def peek_at_local(n)
  local_table_size = iseq.body.local_table_size
  offset = -C::VM_ENV_DATA_SIZE - local_table_size + n + 1
  value = (cfp.ep + offset).*
  C.to_ruby(value)
end
peek_at_self() click to toggle source
# File ruby_vm/rjit/jit_state.rb, line 45
def peek_at_self
  C.to_ruby(cfp.self)
end
peek_at_stack(depth_from_top) click to toggle source
# File ruby_vm/rjit/jit_state.rb, line 37
def peek_at_stack(depth_from_top)
  raise 'not at current insn' unless at_current_insn?
  offset = -(1 + depth_from_top)
  # rb_rjit_branch_stub_hit updates SP, so you don't need to worry about sp_offset
  value = (cfp.sp + offset).*
  C.to_ruby(value)
end