Support non-T_OBJECTs in getivar

This commit is contained in:
Takashi Kokubun 2023-03-03 20:59:58 -08:00
Родитель 49f336f468
Коммит 366c3c7644
3 изменённых файлов: 31 добавлений и 10 удалений

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

@ -2226,6 +2226,7 @@ module RubyVM::MJIT
end
end
# Note: This clobbers :rax
# @param jit [RubyVM::MJIT::JITState]
# @param ctx [RubyVM::MJIT::Context]
# @param asm [RubyVM::MJIT::Assembler]
@ -2235,6 +2236,7 @@ module RubyVM::MJIT
jit_save_sp(jit, ctx, asm)
end
# Note: This clobbers :rax
# @param jit [RubyVM::MJIT::JITState]
# @param asm [RubyVM::MJIT::Assembler]
def jit_save_pc(jit, asm, comment: 'save PC to CFP')
@ -2331,21 +2333,38 @@ module RubyVM::MJIT
asm.incr_counter(:getivar_special_const)
return CantCompile
end
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)
when C.T_OBJECT
# This is the only supported case for now (ROBJECT_IVPTR)
else
asm.incr_counter(:getivar_not_t_object)
return CantCompile
# General case. Call rb_ivar_get().
# VALUE rb_ivar_get(VALUE obj, ID id)
asm.comment('call rb_ivar_get()')
asm.mov(C_ARGS[0], obj_opnd ? obj_opnd : [CFP, C.rb_control_frame_t.offsetof(:self)])
asm.mov(C_ARGS[1], ivar_id)
# The function could raise exceptions.
jit_prepare_routine_call(jit, ctx, asm) # clobbers obj_opnd and :rax
asm.call(C.rb_ivar_get)
if obj_opnd # attr_reader
ctx.stack_pop
end
# Push the ivar on the stack
out_opnd = ctx.stack_push
asm.mov(out_opnd, C_RET)
# Jump to next instruction. This allows guard chains to share the same successor.
jump_to_next_insn(jit, ctx, asm)
return EndBlock
end
asm.mov(:rax, obj_opnd ? obj_opnd : [CFP, C.rb_control_frame_t.offsetof(:self)])
guard_object_is_heap(asm, :rax, counted_exit(side_exit, :getivar_not_heap))
shape_id = C.rb_shape_get_shape_id(comptime_obj)
if shape_id == C.OBJ_TOO_COMPLEX_SHAPE_ID
asm.incr_counter(:getivar_too_complex)

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

@ -168,7 +168,6 @@ MJIT_RUNTIME_COUNTERS(
getivar_megamorphic,
getivar_not_heap,
getivar_not_t_object,
getivar_special_const,
getivar_too_complex,

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

@ -325,6 +325,10 @@ module RubyVM::MJIT # :nodoc: all
Primitive.cexpr! 'SIZET2NUM((size_t)rb_ensure_iv_list_size)'
end
def rb_ivar_get
Primitive.cexpr! 'SIZET2NUM((size_t)rb_ivar_get)'
end
#========================================================================================
#
# Old stuff
@ -1387,7 +1391,6 @@ module RubyVM::MJIT # :nodoc: all
invokesuper_same_me: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), invokesuper_same_me)")],
getivar_megamorphic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), getivar_megamorphic)")],
getivar_not_heap: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), getivar_not_heap)")],
getivar_not_t_object: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), getivar_not_t_object)")],
getivar_special_const: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), getivar_special_const)")],
getivar_too_complex: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), getivar_too_complex)")],
optaref_arg_not_fixnum: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), optaref_arg_not_fixnum)")],