aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2024-03-01 10:03:00 -0800
committerGitHub <noreply@github.com>2024-03-01 13:03:00 -0500
commit661f9e6d03d04667b5488ec202c0e1ec6f97c080 (patch)
tree4bdf846b768d841be1237274c0e8590981391e84
parent88050ec179b2327d4b99d08fc0d825fc8898f5a7 (diff)
downloadruby-661f9e6d03d04667b5488ec202c0e1ec6f97c080.tar.gz
YJIT: Support opt_invokebuiltin_delegate for leaf builtin (#10152)
-rw-r--r--test/ruby/test_yjit.rb13
-rw-r--r--yjit.c14
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
diff --git a/yjit.c b/yjit.c
index 13707900c0..349f4f6d02 100644
--- a/yjit.c
+++ b/yjit.c
@@ -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.