YJIT: Support opt_invokebuiltin_delegate for leaf builtin (#10152)

This commit is contained in:
Takashi Kokubun 2024-03-01 10:03:00 -08:00 committed by GitHub
parent 88050ec179
commit 661f9e6d03
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 21 additions and 6 deletions

View File

@ -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

14
yjit.c
View File

@ -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.