From 478e0fc710b8fefaa3bdb7cb41dda8716e29927a Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Mon, 4 Nov 2024 08:14:28 -0800 Subject: YJIT: Replace Array#each only when YJIT is enabled (#11955) * YJIT: Replace Array#each only when YJIT is enabled * Add comments about BUILTIN_ATTR_C_TRACE * Make Ruby Array#each available with --yjit as well * Fix all paths that expect a C location * Use method_basic_definition_p to detect patches * Copy a comment about C_TRACE flag to compilers * Rephrase a comment about add_yjit_hook * Give METHOD_ENTRY_BASIC flag to Array#each * Add --yjit-c-builtin option * Allow inconsistent source_location in test-spec * Refactor a check of BUILTIN_ATTR_C_TRACE * Set METHOD_ENTRY_BASIC without touching vm->running --- test/ruby/test_yjit.rb | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'test/ruby') diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb index 5f0a5035b0..0c8ed691d0 100644 --- a/test/ruby/test_yjit.rb +++ b/test/ruby/test_yjit.rb @@ -1677,6 +1677,71 @@ class TestYJIT < Test::Unit::TestCase RUBY end + def test_yjit_option_uses_array_each_in_ruby + assert_separately(["--yjit"], <<~'RUBY') + # Array#each should be implemented in Ruby for YJIT + assert_equal "", Array.instance_method(:each).source_location.first + + # The backtrace, however, should not be `from :XX:in 'Array#each'` + begin + [nil].each { raise } + rescue => e + assert_equal "-:11:in 'Array#each'", e.backtrace[1] + end + RUBY + end + + def test_yjit_enable_replaces_array_each + assert_separately([*("--disable=yjit" if RubyVM::YJIT.enabled?)], <<~'RUBY') + # Array#each should be implemented in C for the interpreter + assert_nil Array.instance_method(:each).source_location + + # The backtrace should not be `from :XX:in 'Array#each'` + begin + [nil].each { raise } + rescue => e + assert_equal "-:11:in 'Array#each'", e.backtrace[1] + end + + RubyVM::YJIT.enable + + # Array#each should be implemented in Ruby for YJIT + assert_equal "", Array.instance_method(:each).source_location.first + + # However, the backtrace should still not be `from :XX:in 'Array#each'` + begin + [nil].each { raise } + rescue => e + assert_equal "-:23:in 'Array#each'", e.backtrace[1] + end + RUBY + end + + def test_yjit_enable_preserves_array_each_monkey_patch + assert_separately([*("--disable=yjit" if RubyVM::YJIT.enabled?)], <<~'RUBY') + # Array#each should be implemented in C initially + assert_nil Array.instance_method(:each).source_location + + # Override Array#each + $called = false + Array.prepend(Module.new { + def each + $called = true + super + end + }) + + RubyVM::YJIT.enable + + # The monkey-patch should still be alive + [].each {} + assert_true $called + + # YJIT should not replace Array#each with the "" one + assert_equal "-", Array.instance_method(:each).source_location.first + RUBY + end + private def code_gc_helpers -- cgit v1.2.3