diff options
author | Takashi Kokubun <takashikkbn@gmail.com> | 2024-03-01 10:03:00 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-01 13:03:00 -0500 |
commit | 661f9e6d03d04667b5488ec202c0e1ec6f97c080 (patch) | |
tree | 4bdf846b768d841be1237274c0e8590981391e84 | |
parent | 88050ec179b2327d4b99d08fc0d825fc8898f5a7 (diff) | |
download | ruby-661f9e6d03d04667b5488ec202c0e1ec6f97c080.tar.gz |
YJIT: Support opt_invokebuiltin_delegate for leaf builtin (#10152)
-rw-r--r-- | test/ruby/test_yjit.rb | 13 | ||||
-rw-r--r-- | yjit.c | 14 |
2 files changed, 21 insertions, 6 deletions
diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb index 8936e567d1..67e684656d 100644 --- a/test/ruby/test_yjit.rb +++ b/test/ruby/test_yjit.rb @@ -1600,6 +1600,19 @@ class TestYJIT < Test::Unit::TestCase RUBY end + def test_leaf_builtin + assert_compiles(code_gc_helpers + <<~'RUBY', exits: :any, result: 1) + before = RubyVM::YJIT.runtime_stats[:num_send_iseq_leaf] + return 1 if before.nil? + + def entry = self.class + entry + + after = RubyVM::YJIT.runtime_stats[:num_send_iseq_leaf] + after - before + RUBY + end + private def code_gc_helpers @@ -739,15 +739,17 @@ rb_yjit_iseq_builtin_attrs(const rb_iseq_t *iseq) return iseq->body->builtin_attrs; } -// If true, the iseq has only opt_invokebuiltin_delegate_leave and leave insns. +// If true, the iseq has only opt_invokebuiltin_delegate(_leave) and leave insns. static bool invokebuiltin_delegate_leave_p(const rb_iseq_t *iseq) { - unsigned int invokebuiltin_len = insn_len(BIN(opt_invokebuiltin_delegate_leave)); - unsigned int leave_len = insn_len(BIN(leave)); - return iseq->body->iseq_size == (invokebuiltin_len + leave_len) && - rb_vm_insn_addr2opcode((void *)iseq->body->iseq_encoded[0]) == BIN(opt_invokebuiltin_delegate_leave) && - rb_vm_insn_addr2opcode((void *)iseq->body->iseq_encoded[invokebuiltin_len]) == BIN(leave); + int insn1 = rb_vm_insn_addr2opcode((void *)iseq->body->iseq_encoded[0]); + if ((int)iseq->body->iseq_size != insn_len(insn1) + insn_len(BIN(leave))) { + return false; + } + int insn2 = rb_vm_insn_addr2opcode((void *)iseq->body->iseq_encoded[insn_len(insn1)]); + return (insn1 == BIN(opt_invokebuiltin_delegate) || insn1 == BIN(opt_invokebuiltin_delegate_leave)) && + insn2 == BIN(leave); } // Return an rb_builtin_function if the iseq contains only that builtin function. |