mirror of
https://github.com/ruby/ruby.git
synced 2025-08-26 22:45:03 +02:00
Implement opt_invokebuiltin_delegate
This commit is contained in:
parent
7b78fd0df2
commit
a4bf1c661b
Notes:
git
2023-03-06 07:29:58 +00:00
3 changed files with 56 additions and 7 deletions
|
@ -23,7 +23,7 @@ module RubyVM::MJIT
|
||||||
asm.incr_counter(:mjit_insns_count)
|
asm.incr_counter(:mjit_insns_count)
|
||||||
asm.comment("Insn: #{insn.name}")
|
asm.comment("Insn: #{insn.name}")
|
||||||
|
|
||||||
# 49/101
|
# 51/101
|
||||||
case insn.name
|
case insn.name
|
||||||
when :nop then nop(jit, ctx, asm)
|
when :nop then nop(jit, ctx, asm)
|
||||||
when :getlocal then getlocal(jit, ctx, asm)
|
when :getlocal then getlocal(jit, ctx, asm)
|
||||||
|
@ -118,8 +118,8 @@ module RubyVM::MJIT
|
||||||
when :opt_not then opt_not(jit, ctx, asm)
|
when :opt_not then opt_not(jit, ctx, asm)
|
||||||
when :opt_regexpmatch2 then opt_regexpmatch2(jit, ctx, asm)
|
when :opt_regexpmatch2 then opt_regexpmatch2(jit, ctx, asm)
|
||||||
# invokebuiltin
|
# invokebuiltin
|
||||||
# opt_invokebuiltin_delegate
|
when :opt_invokebuiltin_delegate then opt_invokebuiltin_delegate(jit, ctx, asm)
|
||||||
# opt_invokebuiltin_delegate_leave
|
when :opt_invokebuiltin_delegate_leave then opt_invokebuiltin_delegate_leave(jit, ctx, asm)
|
||||||
when :getlocal_WC_0 then getlocal_WC_0(jit, ctx, asm)
|
when :getlocal_WC_0 then getlocal_WC_0(jit, ctx, asm)
|
||||||
when :getlocal_WC_1 then getlocal_WC_1(jit, ctx, asm)
|
when :getlocal_WC_1 then getlocal_WC_1(jit, ctx, asm)
|
||||||
when :setlocal_WC_0 then setlocal_WC_0(jit, ctx, asm)
|
when :setlocal_WC_0 then setlocal_WC_0(jit, ctx, asm)
|
||||||
|
@ -1164,8 +1164,52 @@ module RubyVM::MJIT
|
||||||
end
|
end
|
||||||
|
|
||||||
# invokebuiltin
|
# invokebuiltin
|
||||||
# opt_invokebuiltin_delegate
|
|
||||||
# opt_invokebuiltin_delegate_leave
|
def opt_invokebuiltin_delegate(jit, ctx, asm)
|
||||||
|
bf = C.rb_builtin_function.new(jit.operand(0))
|
||||||
|
bf_argc = bf.argc
|
||||||
|
start_index = jit.operand(1)
|
||||||
|
|
||||||
|
# ec, self, and arguments
|
||||||
|
if bf_argc + 2 > C_ARGS.size
|
||||||
|
return CantCompile
|
||||||
|
end
|
||||||
|
|
||||||
|
# If the calls don't allocate, do they need up to date PC, SP?
|
||||||
|
jit_prepare_routine_call(jit, ctx, asm)
|
||||||
|
|
||||||
|
# Call the builtin func (ec, recv, arg1, arg2, ...)
|
||||||
|
asm.comment('call builtin func')
|
||||||
|
asm.mov(C_ARGS[0], EC)
|
||||||
|
asm.mov(C_ARGS[1], [CFP, C.rb_control_frame_t.offsetof(:self)])
|
||||||
|
|
||||||
|
# Copy arguments from locals
|
||||||
|
if bf_argc > 0
|
||||||
|
# Load environment pointer EP from CFP
|
||||||
|
asm.mov(:rax, [CFP, C.rb_control_frame_t.offsetof(:ep)])
|
||||||
|
|
||||||
|
bf_argc.times do |i|
|
||||||
|
table_size = jit.iseq.body.local_table_size
|
||||||
|
offs = -table_size - C.VM_ENV_DATA_SIZE + 1 + start_index + i
|
||||||
|
asm.mov(C_ARGS[2 + i], [:rax, offs * C.VALUE.size])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
asm.call(bf.func_ptr)
|
||||||
|
|
||||||
|
# Push the return value
|
||||||
|
stack_ret = ctx.stack_push
|
||||||
|
asm.mov(stack_ret, C_RET)
|
||||||
|
|
||||||
|
KeepCompiling
|
||||||
|
end
|
||||||
|
|
||||||
|
# @param jit [RubyVM::MJIT::JITState]
|
||||||
|
# @param ctx [RubyVM::MJIT::Context]
|
||||||
|
# @param asm [RubyVM::MJIT::Assembler]
|
||||||
|
def opt_invokebuiltin_delegate_leave(jit, ctx, asm)
|
||||||
|
opt_invokebuiltin_delegate(jit, ctx, asm)
|
||||||
|
# opt_invokebuiltin_delegate is always followed by leave insn
|
||||||
|
end
|
||||||
|
|
||||||
# @param jit [RubyVM::MJIT::JITState]
|
# @param jit [RubyVM::MJIT::JITState]
|
||||||
# @param ctx [RubyVM::MJIT::Context]
|
# @param ctx [RubyVM::MJIT::Context]
|
||||||
|
|
|
@ -833,7 +833,7 @@ module RubyVM::MJIT # :nodoc: all
|
||||||
def C.rb_builtin_function
|
def C.rb_builtin_function
|
||||||
@rb_builtin_function ||= CType::Struct.new(
|
@rb_builtin_function ||= CType::Struct.new(
|
||||||
"rb_builtin_function", Primitive.cexpr!("SIZEOF(struct rb_builtin_function)"),
|
"rb_builtin_function", Primitive.cexpr!("SIZEOF(struct rb_builtin_function)"),
|
||||||
func_ptr: [CType::Pointer.new { CType::Immediate.parse("void") }, Primitive.cexpr!("OFFSETOF((*((struct rb_builtin_function *)NULL)), func_ptr)")],
|
func_ptr: [CType::Immediate.parse("void *"), Primitive.cexpr!("OFFSETOF((*((struct rb_builtin_function *)NULL)), func_ptr)")],
|
||||||
argc: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_builtin_function *)NULL)), argc)")],
|
argc: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_builtin_function *)NULL)), argc)")],
|
||||||
index: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_builtin_function *)NULL)), index)")],
|
index: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_builtin_function *)NULL)), index)")],
|
||||||
name: [CType::Pointer.new { CType::Immediate.parse("char") }, Primitive.cexpr!("OFFSETOF((*((struct rb_builtin_function *)NULL)), name)")],
|
name: [CType::Pointer.new { CType::Immediate.parse("char") }, Primitive.cexpr!("OFFSETOF((*((struct rb_builtin_function *)NULL)), name)")],
|
||||||
|
@ -898,7 +898,7 @@ module RubyVM::MJIT # :nodoc: all
|
||||||
iseq: [CType::Pointer.new { self.rb_iseq_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), iseq)")],
|
iseq: [CType::Pointer.new { self.rb_iseq_t }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), iseq)")],
|
||||||
self: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), self)")],
|
self: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), self)")],
|
||||||
ep: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), ep)")],
|
ep: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), ep)")],
|
||||||
block_code: [CType::Pointer.new { CType::Immediate.parse("void") }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), block_code)")],
|
block_code: [CType::Immediate.parse("void *"), Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), block_code)")],
|
||||||
__bp__: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), __bp__)")],
|
__bp__: [CType::Pointer.new { self.VALUE }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), __bp__)")],
|
||||||
jit_return: [CType::Pointer.new { CType::Immediate.parse("void") }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), jit_return)")],
|
jit_return: [CType::Pointer.new { CType::Immediate.parse("void") }, Primitive.cexpr!("OFFSETOF((*((struct rb_control_frame_struct *)NULL)), jit_return)")],
|
||||||
)
|
)
|
||||||
|
|
|
@ -270,6 +270,11 @@ class BindingGenerator
|
||||||
end
|
end
|
||||||
type = type.delete_suffix('const')
|
type = type.delete_suffix('const')
|
||||||
if type.end_with?('*')
|
if type.end_with?('*')
|
||||||
|
if type == 'const void *'
|
||||||
|
# `CType::Pointer.new { CType::Immediate.parse("void") }` is never useful,
|
||||||
|
# so specially handle that case here.
|
||||||
|
return 'CType::Immediate.parse("void *")'
|
||||||
|
end
|
||||||
return "CType::Pointer.new { #{generate_type(type.delete_suffix('*').rstrip)} }"
|
return "CType::Pointer.new { #{generate_type(type.delete_suffix('*').rstrip)} }"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue