summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2023-03-03 22:14:15 -0800
committerTakashi Kokubun <takashikkbn@gmail.com>2023-03-05 23:28:59 -0800
commit43d1a7afd44e6016a8638e4801da8ddc137b0654 (patch)
treef613a468166546e2ef5bc8b9bb0ecc15835f881d
parent46a14b65fbeca6bc27e43da4248726b289f1157a (diff)
Implement cref on opt_getconstant_path
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/7448
-rw-r--r--lib/ruby_vm/mjit/insn_compiler.rb23
-rw-r--r--mjit_c.h1
-rw-r--r--mjit_c.rb8
3 files changed, 29 insertions, 3 deletions
diff --git a/lib/ruby_vm/mjit/insn_compiler.rb b/lib/ruby_vm/mjit/insn_compiler.rb
index 6531aa5426..ac759f504f 100644
--- a/lib/ruby_vm/mjit/insn_compiler.rb
+++ b/lib/ruby_vm/mjit/insn_compiler.rb
@@ -457,9 +457,26 @@ module RubyVM::MJIT
end
if ice.ic_cref # with cref
- # Not supported yet
- asm.incr_counter(:optgetconst_cref)
- return CantCompile
+ # Cache is keyed on a certain lexical scope. Use the interpreter's cache.
+ side_exit = side_exit(jit, ctx)
+
+ # Call function to verify the cache. It doesn't allocate or call methods.
+ asm.mov(C_ARGS[0], ic.to_i)
+ asm.mov(C_ARGS[1], [CFP, C.rb_control_frame_t.offsetof(:ep)])
+ asm.call(C.rb_vm_ic_hit_p)
+
+ # Check the result. SysV only specifies one byte for _Bool return values,
+ # so it's important we only check one bit to ignore the higher bits in the register.
+ asm.test(C_RET, 1)
+ asm.jz(counted_exit(side_exit, :optgetconst_cache_miss))
+
+ asm.mov(:rax, ic.to_i) # inline_cache
+ asm.mov(:rax, [:rax, C.iseq_inline_constant_cache.offsetof(:entry)]) # ic_entry
+ asm.mov(:rax, [:rax, C.iseq_inline_constant_cache_entry.offsetof(:value)]) # ic_entry_val
+
+ # Push ic->entry->value
+ stack_top = ctx.stack_push
+ asm.mov(stack_top, :rax)
else # without cref
# TODO: implement this
# Optimize for single ractor mode.
diff --git a/mjit_c.h b/mjit_c.h
index b2cf602c86..a28ba78612 100644
--- a/mjit_c.h
+++ b/mjit_c.h
@@ -179,6 +179,7 @@ MJIT_RUNTIME_COUNTERS(
optgetconst_not_cached,
optgetconst_cref,
+ optgetconst_cache_miss,
setivar_frozen,
setivar_not_heap,
diff --git a/mjit_c.rb b/mjit_c.rb
index be79d329a1..0ed9e3d538 100644
--- a/mjit_c.rb
+++ b/mjit_c.rb
@@ -344,6 +344,13 @@ module RubyVM::MJIT # :nodoc: all
}
end
+ def rb_vm_ic_hit_p
+ Primitive.cstmt! %{
+ extern bool rb_vm_ic_hit_p(IC ic, const VALUE *reg_ep);
+ return SIZET2NUM((size_t)rb_vm_ic_hit_p);
+ }
+ end
+
#========================================================================================
#
# Old stuff
@@ -1427,6 +1434,7 @@ module RubyVM::MJIT # :nodoc: all
optaref_send: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), optaref_send)")],
optgetconst_not_cached: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), optgetconst_not_cached)")],
optgetconst_cref: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), optgetconst_cref)")],
+ optgetconst_cache_miss: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), optgetconst_cache_miss)")],
setivar_frozen: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), setivar_frozen)")],
setivar_not_heap: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), setivar_not_heap)")],
setivar_megamorphic: [CType::Immediate.parse("size_t"), Primitive.cexpr!("OFFSETOF((*((struct rb_mjit_runtime_counters *)NULL)), setivar_megamorphic)")],