This commit is contained in:
Takashi Kokubun 2023-02-08 14:36:55 -08:00
Родитель e6354d5e9b
Коммит ecae1cd74e
4 изменённых файлов: 76 добавлений и 17 удалений

Просмотреть файл

@ -859,7 +859,7 @@ module RubyVM::MJIT
# @param jit [RubyVM::MJIT::JITState]
# @param ctx [RubyVM::MJIT::Context]
# @param asm [RubyVM::MJIT::Assembler]
def jit_getivar(jit, ctx, asm, comptime_obj, ivar_id)
def jit_getivar(jit, ctx, asm, comptime_obj, ivar_id, obj_opnd = nil)
side_exit = side_exit(jit, ctx)
starting_ctx = ctx.dup # copy for jit_chain_guard
@ -868,7 +868,11 @@ module RubyVM::MJIT
asm.incr_counter(:getivar_special_const)
return CantCompile
end
asm.mov(:rax, [CFP, C.rb_control_frame_t.offsetof(:self)])
if obj_opnd.nil? # getivar
asm.mov(:rax, [CFP, C.rb_control_frame_t.offsetof(:self)])
else # attr_reader
asm.mov(:rax, obj_opnd)
end
guard_object_is_heap(asm, :rax, counted_exit(side_exit, :getivar_not_heap))
case C.BUILTIN_TYPE(comptime_obj)
@ -891,7 +895,7 @@ module RubyVM::MJIT
index = C.rb_shape_get_iv_index(shape_id, ivar_id)
if index
# See ROBJECT_IVPTR
asm.comment('ROBJECT_IVPTR')
if C.FL_TEST_RAW(comptime_obj, C.ROBJECT_EMBED)
# Access embedded array
asm.mov(:rax, [:rax, C.RObject.offsetof(:as, :ary) + (index * C.VALUE.size)])
@ -906,6 +910,9 @@ module RubyVM::MJIT
val_opnd = Qnil
end
if obj_opnd
ctx.stack_pop # pop receiver for attr_reader
end
stack_opnd = ctx.stack_push
asm.mov(stack_opnd, val_opnd)
@ -981,14 +988,14 @@ module RubyVM::MJIT
# Invalidate on redefinition (part of vm_search_method_fastpath)
@invariants.assume_method_lookup_stable(jit, cme)
jit_call_method_each_type(jit, ctx, asm, ci, argc, flags, cme)
jit_call_method_each_type(jit, ctx, asm, ci, argc, flags, cme, comptime_recv, recv_opnd)
end
# vm_call_method_each_type
# @param jit [RubyVM::MJIT::JITState]
# @param ctx [RubyVM::MJIT::Context]
# @param asm [RubyVM::MJIT::Assembler]
def jit_call_method_each_type(jit, ctx, asm, ci, argc, flags, cme)
def jit_call_method_each_type(jit, ctx, asm, ci, argc, flags, cme, comptime_recv, recv_opnd)
case cme.def.type
when C.VM_METHOD_TYPE_ISEQ
jit_call_iseq_setup(jit, ctx, asm, ci, cme, flags, argc)
@ -1000,8 +1007,7 @@ module RubyVM::MJIT
asm.incr_counter(:send_attrset)
return CantCompile
when C.VM_METHOD_TYPE_IVAR
asm.incr_counter(:send_ivar)
return CantCompile
jit_call_ivar(jit, ctx, asm, ci, cme, flags, argc, comptime_recv, recv_opnd)
# when C.VM_METHOD_TYPE_MISSING
when C.VM_METHOD_TYPE_BMETHOD
asm.incr_counter(:send_bmethod)
@ -1046,6 +1052,9 @@ module RubyVM::MJIT
end
# vm_call_iseq_setup_normal (vm_call_iseq_setup_2 -> vm_call_iseq_setup_normal)
# @param jit [RubyVM::MJIT::JITState]
# @param ctx [RubyVM::MJIT::Context]
# @param asm [RubyVM::MJIT::Assembler]
def jit_call_iseq_setup_normal(jit, ctx, asm, ci, cme, flags, argc, iseq)
# Save caller SP and PC before pushing a callee frame for backtrace and side exits
asm.comment('save SP to caller CFP')
@ -1062,6 +1071,36 @@ module RubyVM::MJIT
jit_push_frame(jit, ctx, asm, ci, cme, flags, argc, iseq, frame_type, next_pc)
end
# vm_call_ivar
# @param jit [RubyVM::MJIT::JITState]
# @param ctx [RubyVM::MJIT::Context]
# @param asm [RubyVM::MJIT::Assembler]
def jit_call_ivar(jit, ctx, asm, ci, cme, flags, argc, comptime_recv, recv_opnd)
if flags & C.VM_CALL_ARGS_SPLAT != 0
asm.incr_counter(:send_ivar_splat)
return CantCompile
end
if argc != 0
asm.incr_counter(:send_ivar_arity)
return CantCompile
end
if flags & C.VM_CALL_OPT_SEND != 0
asm.incr_counter(:send_ivar_opt_send)
return CantCompile
end
ivar_id = cme.def.body.attr.id
if flags & C.VM_CALL_OPT_SEND != 0
asm.incr_counter(:send_ivar_blockarg)
return CantCompile
end
jit_getivar(jit, ctx, asm, comptime_recv, ivar_id, recv_opnd)
end
# vm_push_frame
#
# Frame structure:

Просмотреть файл

@ -119,7 +119,6 @@ MJIT_RUNTIME_COUNTERS(
send_tailcall,
send_not_implemented_type,
send_cfunc,
send_ivar,
send_attrset,
send_bmethod,
send_alias,
@ -127,6 +126,12 @@ MJIT_RUNTIME_COUNTERS(
send_zsuper,
send_refined,
send_ivar,
send_ivar_splat,
send_ivar_arity,
send_ivar_opt_send,
send_ivar_blockarg,
send_guard_nil,
send_guard_true,
send_guard_false,

Просмотреть файл

@ -395,6 +395,10 @@ module RubyVM::MJIT # :nodoc: all
Primitive.cexpr! %q{ UINT2NUM(VM_CALL_KW_SPLAT_bit) }
end
def C.VM_CALL_OPT_SEND
Primitive.cexpr! %q{ UINT2NUM(VM_CALL_OPT_SEND) }
end
def C.VM_CALL_TAILCALL
Primitive.cexpr! %q{ UINT2NUM(VM_CALL_TAILCALL) }
end
@ -499,6 +503,10 @@ module RubyVM::MJIT # :nodoc: all
@IC ||= self.iseq_inline_constant_cache
end
def C.ID
@ID ||= CType::Immediate.parse("unsigned long")
end
def C.IVC
@IVC ||= self.iseq_inline_iv_cache_entry
end
@ -856,6 +864,14 @@ module RubyVM::MJIT # :nodoc: all
@rb_iseq_t ||= self.rb_iseq_struct
end
def C.rb_method_attr_t
@rb_method_attr_t ||= CType::Struct.new(
"rb_method_attr_struct", Primitive.cexpr!("SIZEOF(struct rb_method_attr_struct)"),
id: [self.ID, Primitive.cexpr!("OFFSETOF((*((struct rb_method_attr_struct *)NULL)), id)")],
location: [self.VALUE, Primitive.cexpr!("OFFSETOF((*((struct rb_method_attr_struct *)NULL)), location)")],
)
end
def C.rb_method_definition_struct
@rb_method_definition_struct ||= CType::Struct.new(
"rb_method_definition_struct", Primitive.cexpr!("SIZEOF(struct rb_method_definition_struct)"),
@ -917,13 +933,17 @@ module RubyVM::MJIT # :nodoc: all
send_tailcall: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_tailcall)")],
send_not_implemented_type: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_not_implemented_type)")],
send_cfunc: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_cfunc)")],
send_ivar: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_ivar)")],
send_attrset: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_attrset)")],
send_bmethod: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_bmethod)")],
send_alias: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_alias)")],
send_optimized: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_optimized)")],
send_zsuper: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_zsuper)")],
send_refined: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_refined)")],
send_ivar: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_ivar)")],
send_ivar_splat: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_ivar_splat)")],
send_ivar_arity: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_ivar_arity)")],
send_ivar_opt_send: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_ivar_opt_send)")],
send_ivar_blockarg: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_ivar_blockarg)")],
send_guard_nil: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_guard_nil)")],
send_guard_true: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_guard_true)")],
send_guard_false: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), send_guard_false)")],
@ -996,10 +1016,6 @@ module RubyVM::MJIT # :nodoc: all
CType::Bool.new
end
def C.ID
CType::Stub.new(:ID)
end
def C.rb_thread_struct
CType::Stub.new(:rb_thread_struct)
end
@ -1088,10 +1104,6 @@ module RubyVM::MJIT # :nodoc: all
CType::Stub.new(:rb_method_cfunc_t)
end
def C.rb_method_attr_t
CType::Stub.new(:rb_method_attr_t)
end
def C.rb_method_alias_t
CType::Stub.new(:rb_method_alias_t)
end

Просмотреть файл

@ -376,6 +376,7 @@ generator = BindingGenerator.new(
VM_CALL_KW_SPLAT_bit
VM_CALL_TAILCALL
VM_CALL_TAILCALL_bit
VM_CALL_OPT_SEND
VM_ENV_FLAG_LOCAL
VM_FRAME_MAGIC_METHOD
VM_METHOD_TYPE_CFUNC
@ -407,6 +408,7 @@ generator = BindingGenerator.new(
types: %w[
CALL_DATA
IC
ID
IVC
RB_BUILTIN
RBasic
@ -442,6 +444,7 @@ generator = BindingGenerator.new(
rb_serial_t
rb_shape
rb_shape_t
rb_method_attr_t
],
dynamic_types: %w[
VALUE