From 03645d1eefdf280c3c1ff20f9431fb8fe45799b4 Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Wed, 17 Jan 2024 10:52:15 -0500 Subject: YJIT: Support empty splat and some block_arg calls to ivar getters (#9567) These seem odd at first glance, but they're used with `...` calls with `Module#delegate` from Active Support. These account for ~3% of fallback reasons in the `lobsters` benchmark. --- test/ruby/test_yjit.rb | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'test/ruby') diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb index 55b86bea78..bd513c60e6 100644 --- a/test/ruby/test_yjit.rb +++ b/test/ruby/test_yjit.rb @@ -1514,6 +1514,24 @@ class TestYJIT < Test::Unit::TestCase assert_in_out_err(%w[--yjit-stats --yjit-disable]) end + def test_odd_calls_to_attr_reader + # Use of delegate from ActiveSupport use these kind of calls to getter methods. + assert_compiles(<<~RUBY, result: [1, 1, 1], no_send_fallbacks: true) + class One + attr_reader :one + def initialize + @one = 1 + end + end + + def calls(obj, empty, &) + [obj.one(*empty), obj.one(&), obj.one(*empty, &)] + end + + calls(One.new, []) + RUBY + end + private def code_gc_helpers @@ -1537,7 +1555,17 @@ class TestYJIT < Test::Unit::TestCase end ANY = Object.new - def assert_compiles(test_script, insns: [], call_threshold: 1, stdout: nil, exits: {}, result: ANY, frozen_string_literal: nil, mem_size: nil, code_gc: false) + def assert_compiles( + test_script, insns: [], + call_threshold: 1, + stdout: nil, + exits: {}, + result: ANY, + frozen_string_literal: nil, + mem_size: nil, + code_gc: false, + no_send_fallbacks: false + ) reset_stats = <<~RUBY RubyVM::YJIT.runtime_stats RubyVM::YJIT.reset_stats! @@ -1610,6 +1638,10 @@ class TestYJIT < Test::Unit::TestCase end end + if no_send_fallbacks + assert_equal(0, runtime_stats[:num_send_dynamic], "Expected no use of fallback implementation") + end + # Only available when --enable-yjit=dev if runtime_stats[:all_stats] missed_insns = insns.dup -- cgit v1.2.3