зеркало из https://github.com/github/ruby.git
RJIT: Implement ifunc invokeblock
This commit is contained in:
Родитель
47f7ec1c9f
Коммит
59b86da82c
|
@ -1536,8 +1536,47 @@ module RubyVM::RJIT
|
||||||
send_shift: 0, frame_type: C::VM_FRAME_MAGIC_BLOCK,
|
send_shift: 0, frame_type: C::VM_FRAME_MAGIC_BLOCK,
|
||||||
)
|
)
|
||||||
elsif comptime_handler & 0x3 == 0x3 # VM_BH_IFUNC_P
|
elsif comptime_handler & 0x3 == 0x3 # VM_BH_IFUNC_P
|
||||||
asm.incr_counter(:invokeblock_ifunc)
|
# We aren't handling CALLER_SETUP_ARG and CALLER_REMOVE_EMPTY_KW_SPLAT yet.
|
||||||
CantCompile
|
if calling.flags & C::VM_CALL_ARGS_SPLAT != 0
|
||||||
|
asm.incr_counter(:invokeblock_ifunc_args_splat)
|
||||||
|
return CantCompile
|
||||||
|
end
|
||||||
|
if calling.flags & C::VM_CALL_KW_SPLAT != 0
|
||||||
|
asm.incr_counter(:invokeblock_ifunc_kw_splat)
|
||||||
|
return CantCompile
|
||||||
|
end
|
||||||
|
|
||||||
|
asm.comment('get local EP')
|
||||||
|
jit_get_lep(jit, asm, reg: :rax)
|
||||||
|
asm.mov(:rcx, [:rax, C.VALUE.size * C::VM_ENV_DATA_INDEX_SPECVAL]) # block_handler_opnd
|
||||||
|
|
||||||
|
asm.comment('guard block_handler type');
|
||||||
|
side_exit = side_exit(jit, ctx)
|
||||||
|
asm.mov(:rax, :rcx) # block_handler_opnd
|
||||||
|
asm.and(:rax, 0x3) # tag_opnd: block_handler is a tagged pointer
|
||||||
|
asm.cmp(:rax, 0x3) # VM_BH_IFUNC_P
|
||||||
|
tag_changed_exit = counted_exit(side_exit, :invokeblock_tag_changed)
|
||||||
|
jit_chain_guard(:jne, jit, ctx, asm, tag_changed_exit)
|
||||||
|
|
||||||
|
# The cfunc may not be leaf
|
||||||
|
jit_prepare_routine_call(jit, ctx, asm) # clobbers :rax
|
||||||
|
|
||||||
|
asm.comment('call ifunc')
|
||||||
|
asm.and(:rcx, ~0x3) # captured_opnd
|
||||||
|
asm.lea(:rax, ctx.sp_opnd(-calling.argc * C.VALUE.size)) # argv
|
||||||
|
asm.mov(C_ARGS[0], EC)
|
||||||
|
asm.mov(C_ARGS[1], :rcx) # captured_opnd
|
||||||
|
asm.mov(C_ARGS[2], calling.argc)
|
||||||
|
asm.mov(C_ARGS[3], :rax) # argv
|
||||||
|
asm.call(C.rb_vm_yield_with_cfunc)
|
||||||
|
|
||||||
|
ctx.stack_pop(calling.argc)
|
||||||
|
stack_ret = ctx.stack_push
|
||||||
|
asm.mov(stack_ret, C_RET)
|
||||||
|
|
||||||
|
# Share the successor with other chains
|
||||||
|
jump_to_next_insn(jit, ctx, asm)
|
||||||
|
EndBlock
|
||||||
elsif symbol?(comptime_handler)
|
elsif symbol?(comptime_handler)
|
||||||
asm.incr_counter(:invokeblock_symbol)
|
asm.incr_counter(:invokeblock_symbol)
|
||||||
CantCompile
|
CantCompile
|
||||||
|
|
1
rjit_c.c
1
rjit_c.c
|
@ -505,6 +505,7 @@ extern VALUE rb_reg_new_ary(VALUE ary, int opt);
|
||||||
extern void rb_vm_setclassvariable(const rb_iseq_t *iseq, const rb_control_frame_t *cfp, ID id, VALUE val, ICVARC ic);
|
extern void rb_vm_setclassvariable(const rb_iseq_t *iseq, const rb_control_frame_t *cfp, ID id, VALUE val, ICVARC ic);
|
||||||
extern VALUE rb_str_bytesize(VALUE str);
|
extern VALUE rb_str_bytesize(VALUE str);
|
||||||
extern const rb_callable_method_entry_t *rb_callable_method_entry_or_negative(VALUE klass, ID mid);
|
extern const rb_callable_method_entry_t *rb_callable_method_entry_or_negative(VALUE klass, ID mid);
|
||||||
|
extern VALUE rb_vm_yield_with_cfunc(rb_execution_context_t *ec, const struct rb_captured_block *captured, int argc, const VALUE *argv);
|
||||||
|
|
||||||
#include "rjit_c.rbinc"
|
#include "rjit_c.rbinc"
|
||||||
|
|
||||||
|
|
3
rjit_c.h
3
rjit_c.h
|
@ -84,13 +84,14 @@ RJIT_RUNTIME_COUNTERS(
|
||||||
invokesuper_same_me,
|
invokesuper_same_me,
|
||||||
|
|
||||||
invokeblock_none,
|
invokeblock_none,
|
||||||
invokeblock_ifunc,
|
|
||||||
invokeblock_symbol,
|
invokeblock_symbol,
|
||||||
invokeblock_proc,
|
invokeblock_proc,
|
||||||
invokeblock_tag_changed,
|
invokeblock_tag_changed,
|
||||||
invokeblock_iseq_block_changed,
|
invokeblock_iseq_block_changed,
|
||||||
invokeblock_iseq_arity,
|
invokeblock_iseq_arity,
|
||||||
invokeblock_iseq_arg0_splat,
|
invokeblock_iseq_arg0_splat,
|
||||||
|
invokeblock_ifunc_args_splat,
|
||||||
|
invokeblock_ifunc_kw_splat,
|
||||||
|
|
||||||
getivar_megamorphic,
|
getivar_megamorphic,
|
||||||
getivar_not_heap,
|
getivar_not_heap,
|
||||||
|
|
|
@ -701,6 +701,10 @@ module RubyVM::RJIT # :nodoc: all
|
||||||
Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_vm_throw) }
|
Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_vm_throw) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def C.rb_vm_yield_with_cfunc
|
||||||
|
Primitive.cexpr! %q{ SIZET2NUM((size_t)rb_vm_yield_with_cfunc) }
|
||||||
|
end
|
||||||
|
|
||||||
def C.rjit_full_cfunc_return
|
def C.rjit_full_cfunc_return
|
||||||
Primitive.cexpr! %q{ SIZET2NUM((size_t)rjit_full_cfunc_return) }
|
Primitive.cexpr! %q{ SIZET2NUM((size_t)rjit_full_cfunc_return) }
|
||||||
end
|
end
|
||||||
|
@ -1316,13 +1320,14 @@ module RubyVM::RJIT # :nodoc: all
|
||||||
invokesuper_me_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokesuper_me_changed)")],
|
invokesuper_me_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokesuper_me_changed)")],
|
||||||
invokesuper_same_me: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokesuper_same_me)")],
|
invokesuper_same_me: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokesuper_same_me)")],
|
||||||
invokeblock_none: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_none)")],
|
invokeblock_none: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_none)")],
|
||||||
invokeblock_ifunc: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_ifunc)")],
|
|
||||||
invokeblock_symbol: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_symbol)")],
|
invokeblock_symbol: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_symbol)")],
|
||||||
invokeblock_proc: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_proc)")],
|
invokeblock_proc: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_proc)")],
|
||||||
invokeblock_tag_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_tag_changed)")],
|
invokeblock_tag_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_tag_changed)")],
|
||||||
invokeblock_iseq_block_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_iseq_block_changed)")],
|
invokeblock_iseq_block_changed: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_iseq_block_changed)")],
|
||||||
invokeblock_iseq_arity: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_iseq_arity)")],
|
invokeblock_iseq_arity: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_iseq_arity)")],
|
||||||
invokeblock_iseq_arg0_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_iseq_arg0_splat)")],
|
invokeblock_iseq_arg0_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_iseq_arg0_splat)")],
|
||||||
|
invokeblock_ifunc_args_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_ifunc_args_splat)")],
|
||||||
|
invokeblock_ifunc_kw_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), invokeblock_ifunc_kw_splat)")],
|
||||||
getivar_megamorphic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getivar_megamorphic)")],
|
getivar_megamorphic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getivar_megamorphic)")],
|
||||||
getivar_not_heap: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getivar_not_heap)")],
|
getivar_not_heap: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getivar_not_heap)")],
|
||||||
getivar_special_const: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getivar_special_const)")],
|
getivar_special_const: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_rjit_runtime_counters *)NULL)), getivar_special_const)")],
|
||||||
|
|
|
@ -553,6 +553,7 @@ generator = BindingGenerator.new(
|
||||||
rjit_str_simple_append
|
rjit_str_simple_append
|
||||||
rb_str_buf_append
|
rb_str_buf_append
|
||||||
rb_str_dup
|
rb_str_dup
|
||||||
|
rb_vm_yield_with_cfunc
|
||||||
],
|
],
|
||||||
types: %w[
|
types: %w[
|
||||||
CALL_DATA
|
CALL_DATA
|
||||||
|
|
Загрузка…
Ссылка в новой задаче