summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2023-03-03 20:59:58 -0800
committerTakashi Kokubun <takashikkbn@gmail.com>2023-03-05 23:28:59 -0800
commit366c3c76446108ae442e1918c15219b0fef3fb8d (patch)
treed9be7722a820981db9dea68a5336232d382dedc1
parent49f336f468659af722d473f3e3073a4e97719f76 (diff)
Support non-T_OBJECTs in getivar
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/7448
-rw-r--r--lib/ruby_vm/mjit/insn_compiler.rb35
-rw-r--r--mjit_c.h1
-rw-r--r--mjit_c.rb5
3 files changed, 31 insertions, 10 deletions
diff --git a/lib/ruby_vm/mjit/insn_compiler.rb b/lib/ruby_vm/mjit/insn_compiler.rb
index a06614450b..386e836cd7 100644
--- a/lib/ruby_vm/mjit/insn_compiler.rb
+++ b/lib/ruby_vm/mjit/insn_compiler.rb
@@ -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)
diff --git a/mjit_c.h b/mjit_c.h
index bbe09a9b6e..80c4f47681 100644
--- a/mjit_c.h
+++ b/mjit_c.h
@@ -168,7 +168,6 @@ MJIT_RUNTIME_COUNTERS(
getivar_megamorphic,
getivar_not_heap,
- getivar_not_t_object,
getivar_special_const,
getivar_too_complex,
diff --git a/mjit_c.rb b/mjit_c.rb
index 39b7a72ab9..b3c86456ac 100644
--- a/mjit_c.rb
+++ b/mjit_c.rb
@@ -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)")],