diff options
author | Takashi Kokubun <takashikkbn@gmail.com> | 2023-03-03 22:14:15 -0800 |
---|---|---|
committer | Takashi Kokubun <takashikkbn@gmail.com> | 2023-03-05 23:28:59 -0800 |
commit | 43d1a7afd44e6016a8638e4801da8ddc137b0654 (patch) | |
tree | f613a468166546e2ef5bc8b9bb0ecc15835f881d | |
parent | 46a14b65fbeca6bc27e43da4248726b289f1157a (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.rb | 23 | ||||
-rw-r--r-- | mjit_c.h | 1 | ||||
-rw-r--r-- | mjit_c.rb | 8 |
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. @@ -179,6 +179,7 @@ MJIT_RUNTIME_COUNTERS( optgetconst_not_cached, optgetconst_cref, + optgetconst_cache_miss, setivar_frozen, setivar_not_heap, @@ -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)")], |