class RubyVM::RJIT::JITState

公共类方法

new(side_exit_for_pc: {}, record_boundary_patch_point: false, **) 点击切换源代码
调用父类方法
# 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

公共实例方法

at_current_insn?() 点击切换源代码
# File ruby_vm/rjit/jit_state.rb, line 26
def at_current_insn?
  pc == cfp.pc.to_i
end
ep_at_level(cfp, level:) 点击切换源代码
# 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() 点击切换源代码
# 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) 点击切换源代码
# 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) 点击切换源代码
# 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) 点击切换源代码
# 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() 点击切换源代码
# 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) 点击切换源代码
# 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