RJIT: Introduce constants under RubyVM::RJIT::C
This commit is contained in:
parent
58f7e8b7f8
commit
50c5f94ed7
@ -200,7 +200,7 @@ module RubyVM::RJIT
|
|||||||
asm.mov(C_ARGS[0], EC)
|
asm.mov(C_ARGS[0], EC)
|
||||||
# The block handler for the current frame
|
# The block handler for the current frame
|
||||||
# note, VM_ASSERT(VM_ENV_LOCAL_P(ep))
|
# note, VM_ASSERT(VM_ENV_LOCAL_P(ep))
|
||||||
asm.mov(C_ARGS[1], [ep_reg, C.VALUE.size * C.VM_ENV_DATA_INDEX_SPECVAL])
|
asm.mov(C_ARGS[1], [ep_reg, C.VALUE.size * C::VM_ENV_DATA_INDEX_SPECVAL])
|
||||||
asm.call(C.rb_vm_bh_to_procval)
|
asm.call(C.rb_vm_bh_to_procval)
|
||||||
|
|
||||||
# Load environment pointer EP from CFP (again)
|
# Load environment pointer EP from CFP (again)
|
||||||
@ -271,7 +271,7 @@ module RubyVM::RJIT
|
|||||||
# Load the block handler for the current frame
|
# Load the block handler for the current frame
|
||||||
# note, VM_ASSERT(VM_ENV_LOCAL_P(ep))
|
# note, VM_ASSERT(VM_ENV_LOCAL_P(ep))
|
||||||
block_handler = :rax
|
block_handler = :rax
|
||||||
asm.mov(block_handler, [ep_reg, C.VALUE.size * C.VM_ENV_DATA_INDEX_SPECVAL])
|
asm.mov(block_handler, [ep_reg, C.VALUE.size * C::VM_ENV_DATA_INDEX_SPECVAL])
|
||||||
|
|
||||||
# Specialize compilation for the case where no block handler is present
|
# Specialize compilation for the case where no block handler is present
|
||||||
if comptime_handler == 0
|
if comptime_handler == 0
|
||||||
@ -2821,7 +2821,7 @@ module RubyVM::RJIT
|
|||||||
asm.mov(reg, [CFP, C.rb_control_frame_t.offsetof(:ep)])
|
asm.mov(reg, [CFP, C.rb_control_frame_t.offsetof(:ep)])
|
||||||
level.times do
|
level.times do
|
||||||
# GET_PREV_EP: ep[VM_ENV_DATA_INDEX_SPECVAL] & ~0x03
|
# GET_PREV_EP: ep[VM_ENV_DATA_INDEX_SPECVAL] & ~0x03
|
||||||
asm.mov(reg, [reg, C.VALUE.size * C.VM_ENV_DATA_INDEX_SPECVAL])
|
asm.mov(reg, [reg, C.VALUE.size * C::VM_ENV_DATA_INDEX_SPECVAL])
|
||||||
asm.and(reg, ~0x03)
|
asm.and(reg, ~0x03)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -2965,7 +2965,7 @@ module RubyVM::RJIT
|
|||||||
# Guard no block passed. Only handle that case for now.
|
# Guard no block passed. Only handle that case for now.
|
||||||
asm.comment('guard no block given')
|
asm.comment('guard no block given')
|
||||||
jit_get_lep(jit, asm, reg: :rax)
|
jit_get_lep(jit, asm, reg: :rax)
|
||||||
asm.cmp([:rax, C.VALUE.size * C.VM_ENV_DATA_INDEX_SPECVAL], C.VM_BLOCK_HANDLER_NONE)
|
asm.cmp([:rax, C.VALUE.size * C::VM_ENV_DATA_INDEX_SPECVAL], C.VM_BLOCK_HANDLER_NONE)
|
||||||
asm.jne(counted_exit(side_exit, :send_block_handler))
|
asm.jne(counted_exit(side_exit, :send_block_handler))
|
||||||
return C.VM_BLOCK_HANDLER_NONE
|
return C.VM_BLOCK_HANDLER_NONE
|
||||||
else
|
else
|
||||||
@ -3092,7 +3092,7 @@ module RubyVM::RJIT
|
|||||||
jit_get_lep(jit, asm, reg: :rax)
|
jit_get_lep(jit, asm, reg: :rax)
|
||||||
|
|
||||||
asm.mov(:rcx, me.to_i)
|
asm.mov(:rcx, me.to_i)
|
||||||
asm.cmp([:rax, C.VALUE.size * C.VM_ENV_DATA_INDEX_ME_CREF], :rcx)
|
asm.cmp([:rax, C.VALUE.size * C::VM_ENV_DATA_INDEX_ME_CREF], :rcx)
|
||||||
asm.jne(counted_exit(side_exit, :invokesuper_me_changed))
|
asm.jne(counted_exit(side_exit, :invokesuper_me_changed))
|
||||||
|
|
||||||
# We need to assume that both our current method entry and the super
|
# We need to assume that both our current method entry and the super
|
||||||
@ -3711,7 +3711,7 @@ module RubyVM::RJIT
|
|||||||
# VALUE handler = VM_CF_BLOCK_HANDLER(reg_cfp);
|
# VALUE handler = VM_CF_BLOCK_HANDLER(reg_cfp);
|
||||||
# reg_cfp->block_code = (const void *) handler;
|
# reg_cfp->block_code = (const void *) handler;
|
||||||
jit_get_lep(jit, asm, reg: :rax)
|
jit_get_lep(jit, asm, reg: :rax)
|
||||||
asm.mov(:rax, [:rax, C.VALUE.size * C.VM_ENV_DATA_INDEX_SPECVAL]) # handler
|
asm.mov(:rax, [:rax, C.VALUE.size * C::VM_ENV_DATA_INDEX_SPECVAL]) # handler
|
||||||
asm.mov([CFP, C.rb_control_frame_t.offsetof(:block_code)], :rax)
|
asm.mov([CFP, C.rb_control_frame_t.offsetof(:block_code)], :rax)
|
||||||
|
|
||||||
asm.mov(:rax, C.rb_block_param_proxy)
|
asm.mov(:rax, C.rb_block_param_proxy)
|
||||||
|
@ -40,7 +40,7 @@ module RubyVM::RJIT
|
|||||||
|
|
||||||
def peek_at_block_handler(level)
|
def peek_at_block_handler(level)
|
||||||
ep = ep_at_level(cfp, level:)
|
ep = ep_at_level(cfp, level:)
|
||||||
ep[C.VM_ENV_DATA_INDEX_SPECVAL]
|
ep[C::VM_ENV_DATA_INDEX_SPECVAL]
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@ -49,7 +49,7 @@ module RubyVM::RJIT
|
|||||||
ep = cfp.ep
|
ep = cfp.ep
|
||||||
level.times do
|
level.times do
|
||||||
# VM_ENV_PREV_EP
|
# VM_ENV_PREV_EP
|
||||||
ep = C.VALUE.new(ep[C.VM_ENV_DATA_INDEX_SPECVAL] & ~0x03)
|
ep = C.VALUE.new(ep[C::VM_ENV_DATA_INDEX_SPECVAL] & ~0x03)
|
||||||
end
|
end
|
||||||
ep
|
ep
|
||||||
end
|
end
|
||||||
|
15
rjit_c.rb
15
rjit_c.rb
@ -2,9 +2,9 @@
|
|||||||
# Part of this file is generated by tool/rjit/bindgen.rb.
|
# Part of this file is generated by tool/rjit/bindgen.rb.
|
||||||
# Run `make rjit-bindgen` to update code between "RJIT bindgen begin" and "RJIT bindgen end".
|
# Run `make rjit-bindgen` to update code between "RJIT bindgen begin" and "RJIT bindgen end".
|
||||||
module RubyVM::RJIT # :nodoc: all
|
module RubyVM::RJIT # :nodoc: all
|
||||||
# This `class << C` section is for calling C functions. For importing variables
|
# This `class << C` section is for calling C functions with Primitive.
|
||||||
# or macros as is, please consider using tool/rjit/bindgen.rb instead.
|
# For importing variables or macros, use tool/rjit/bindgen.rb instead.
|
||||||
class << C = Object.new
|
class << C = Module.new
|
||||||
def mmap(mem_size)
|
def mmap(mem_size)
|
||||||
Primitive.cexpr! 'SIZET2NUM((size_t)rjit_reserve_addr_space(NUM2UINT(mem_size)))'
|
Primitive.cexpr! 'SIZET2NUM((size_t)rjit_reserve_addr_space(NUM2UINT(mem_size)))'
|
||||||
end
|
end
|
||||||
@ -312,13 +312,8 @@ module RubyVM::RJIT # :nodoc: all
|
|||||||
|
|
||||||
### RJIT bindgen begin ###
|
### RJIT bindgen begin ###
|
||||||
|
|
||||||
def C.VM_ENV_DATA_INDEX_ME_CREF
|
C::VM_ENV_DATA_INDEX_ME_CREF = Primitive.cexpr! %q{ LONG2NUM(VM_ENV_DATA_INDEX_ME_CREF) }
|
||||||
Primitive.cexpr! %q{ LONG2NUM(VM_ENV_DATA_INDEX_ME_CREF) }
|
C::VM_ENV_DATA_INDEX_SPECVAL = Primitive.cexpr! %q{ LONG2NUM(VM_ENV_DATA_INDEX_SPECVAL) }
|
||||||
end
|
|
||||||
|
|
||||||
def C.VM_ENV_DATA_INDEX_SPECVAL
|
|
||||||
Primitive.cexpr! %q{ LONG2NUM(VM_ENV_DATA_INDEX_SPECVAL) }
|
|
||||||
end
|
|
||||||
|
|
||||||
def C.ARRAY_REDEFINED_OP_FLAG
|
def C.ARRAY_REDEFINED_OP_FLAG
|
||||||
Primitive.cexpr! %q{ SIZET2NUM(ARRAY_REDEFINED_OP_FLAG) }
|
Primitive.cexpr! %q{ SIZET2NUM(ARRAY_REDEFINED_OP_FLAG) }
|
||||||
|
@ -265,7 +265,8 @@ def generate_cexpr(ofile, lineno, line_file, body_lineno, text, locals, func_nam
|
|||||||
f = StringIO.new
|
f = StringIO.new
|
||||||
f.puts '{'
|
f.puts '{'
|
||||||
lineno += 1
|
lineno += 1
|
||||||
locals.reverse_each.with_index{|param, i|
|
# locals is nil outside methods
|
||||||
|
locals&.reverse_each&.with_index{|param, i|
|
||||||
next unless Symbol === param
|
next unless Symbol === param
|
||||||
f.puts "MAYBE_UNUSED(const VALUE) #{param} = rb_vm_lvar(ec, #{-3 - i});"
|
f.puts "MAYBE_UNUSED(const VALUE) #{param} = rb_vm_lvar(ec, #{-3 - i});"
|
||||||
lineno += 1
|
lineno += 1
|
||||||
|
@ -106,15 +106,17 @@ class BindingGenerator
|
|||||||
attr_reader :src
|
attr_reader :src
|
||||||
|
|
||||||
# @param src_path [String]
|
# @param src_path [String]
|
||||||
|
# @param consts [Hash{ Symbol => Array<String> }]
|
||||||
# @param values [Hash{ Symbol => Array<String> }]
|
# @param values [Hash{ Symbol => Array<String> }]
|
||||||
# @param funcs [Array<String>]
|
# @param funcs [Array<String>]
|
||||||
# @param types [Array<String>]
|
# @param types [Array<String>]
|
||||||
# @param dynamic_types [Array<String>] #ifdef-dependent immediate types, which need Primitive.cexpr! for type detection
|
# @param dynamic_types [Array<String>] #ifdef-dependent immediate types, which need Primitive.cexpr! for type detection
|
||||||
# @param skip_fields [Hash{ Symbol => Array<String> }] Struct fields that are skipped from bindgen
|
# @param skip_fields [Hash{ Symbol => Array<String> }] Struct fields that are skipped from bindgen
|
||||||
# @param ruby_fields [Hash{ Symbol => Array<String> }] Struct VALUE fields that are considered Ruby objects
|
# @param ruby_fields [Hash{ Symbol => Array<String> }] Struct VALUE fields that are considered Ruby objects
|
||||||
def initialize(src_path:, values:, funcs:, types:, dynamic_types:, skip_fields:, ruby_fields:)
|
def initialize(src_path:, consts:, values:, funcs:, types:, dynamic_types:, skip_fields:, ruby_fields:)
|
||||||
@preamble, @postamble = split_ambles(src_path)
|
@preamble, @postamble = split_ambles(src_path)
|
||||||
@src = String.new
|
@src = String.new
|
||||||
|
@consts = consts.transform_values(&:sort)
|
||||||
@values = values.transform_values(&:sort)
|
@values = values.transform_values(&:sort)
|
||||||
@funcs = funcs.sort
|
@funcs = funcs.sort
|
||||||
@types = types.sort
|
@types = types.sort
|
||||||
@ -128,6 +130,15 @@ class BindingGenerator
|
|||||||
println @preamble
|
println @preamble
|
||||||
|
|
||||||
# Define macros/enums
|
# Define macros/enums
|
||||||
|
@consts.each do |type, values|
|
||||||
|
values.each do |value|
|
||||||
|
raise "#{value} isn't a valid constant name" unless ('A'..'Z').include?(value[0])
|
||||||
|
println " C::#{value} = Primitive.cexpr! %q{ #{type}2NUM(#{value}) }"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
println
|
||||||
|
|
||||||
|
# Define variables
|
||||||
@values.each do |type, values|
|
@values.each do |type, values|
|
||||||
values.each do |value|
|
values.each do |value|
|
||||||
println " def C.#{value}"
|
println " def C.#{value}"
|
||||||
@ -137,6 +148,7 @@ class BindingGenerator
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Define function pointers
|
||||||
@funcs.each do |func|
|
@funcs.each do |func|
|
||||||
println " def C.#{func}"
|
println " def C.#{func}"
|
||||||
println " Primitive.cexpr! %q{ SIZET2NUM((size_t)#{func}) }"
|
println " Primitive.cexpr! %q{ SIZET2NUM((size_t)#{func}) }"
|
||||||
@ -351,11 +363,13 @@ end
|
|||||||
nodes = HeaderParser.new(File.join(src_dir, 'rjit_c.h'), cflags: cflags).parse
|
nodes = HeaderParser.new(File.join(src_dir, 'rjit_c.h'), cflags: cflags).parse
|
||||||
generator = BindingGenerator.new(
|
generator = BindingGenerator.new(
|
||||||
src_path: src_path,
|
src_path: src_path,
|
||||||
values: {
|
consts: {
|
||||||
LONG: %w[
|
LONG: %w[
|
||||||
VM_ENV_DATA_INDEX_ME_CREF
|
VM_ENV_DATA_INDEX_ME_CREF
|
||||||
VM_ENV_DATA_INDEX_SPECVAL
|
VM_ENV_DATA_INDEX_SPECVAL
|
||||||
],
|
],
|
||||||
|
},
|
||||||
|
values: {
|
||||||
SIZET: %w[
|
SIZET: %w[
|
||||||
ARRAY_REDEFINED_OP_FLAG
|
ARRAY_REDEFINED_OP_FLAG
|
||||||
BOP_AND
|
BOP_AND
|
||||||
|
Loading…
x
Reference in New Issue
Block a user