summaryrefslogtreecommitdiff
path: root/test/ruby
diff options
context:
space:
mode:
authorNoah Gibbs <noah.gibbs@shopify.com>2022-05-11 16:20:21 +0100
committerGitHub <noreply@github.com>2022-05-11 11:20:21 -0400
commite88ada469976e1dad653748bd2c0bedca9e30981 (patch)
treeaab2347018b139a0f48fc99390f43df7f72e61e5 /test/ruby
parentc00feffb46ac646605adc277b5454e6b067e2d8a (diff)
Ruby shovel operator (<<) speedup. (#5896)
For string concat, see if compile-time encoding of strings matches. If so, use simple buffer string concat at runtime. Otherwise, use encoding-checking string concat.
Notes
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
Diffstat (limited to 'test/ruby')
-rw-r--r--test/ruby/test_yjit.rb37
1 files changed, 34 insertions, 3 deletions
diff --git a/test/ruby/test_yjit.rb b/test/ruby/test_yjit.rb
index 88be6622ce..19ca75f883 100644
--- a/test/ruby/test_yjit.rb
+++ b/test/ruby/test_yjit.rb
@@ -316,6 +316,32 @@ class TestYJIT < Test::Unit::TestCase
RUBY
end
+ def test_string_concat_utf8
+ assert_compiles(<<~RUBY, frozen_string_literal: true, result: true)
+ def str_cat_utf8
+ s = String.new
+ 10.times { s << "✅" }
+ s
+ end
+
+ str_cat_utf8 == "✅" * 10
+ RUBY
+ end
+
+ def test_string_concat_ascii
+ # Constant-get for classes (e.g. String, Encoding) can cause a side-exit in getinlinecache. For now, ignore exits.
+ assert_compiles(<<~RUBY, exits: :any)
+ str_arg = "b".encode(Encoding::ASCII)
+ def str_cat_ascii(arg)
+ s = String.new(encoding: Encoding::ASCII)
+ 10.times { s << arg }
+ s
+ end
+
+ str_cat_ascii(str_arg) == str_arg * 10
+ RUBY
+ end
+
def test_opt_length_in_method
assert_compiles(<<~RUBY, insns: %i[opt_length], result: 5)
def foo(str)
@@ -646,7 +672,7 @@ class TestYJIT < Test::Unit::TestCase
disasm = stats[:disasm]
# Check that exit counts are as expected
- # Full stats are only available when RUBY_DEBUG enabled
+ # Full stats are only available when --enable-yjit=dev
if runtime_stats[:all_stats]
recorded_exits = runtime_stats.select { |k, v| k.to_s.start_with?("exit_") }
recorded_exits = recorded_exits.reject { |k, v| v == 0 }
@@ -658,7 +684,7 @@ class TestYJIT < Test::Unit::TestCase
end
end
- # Only available when RUBY_DEBUG enabled
+ # Only available when --enable-yjit=dev
if runtime_stats[:all_stats]
missed_insns = insns.dup
@@ -675,13 +701,18 @@ class TestYJIT < Test::Unit::TestCase
end
end
+ def script_shell_encode(s)
+ # We can't pass utf-8-encoded characters directly in a shell arg. But we can use Ruby \u constants.
+ s.chars.map { |c| c.ascii_only? ? c : "\\u%x" % c.codepoints[0] }.join
+ end
+
def eval_with_jit(script, call_threshold: 1, timeout: 1000)
args = [
"--disable-gems",
"--yjit-call-threshold=#{call_threshold}",
"--yjit-stats"
]
- args << "-e" << script
+ args << "-e" << script_shell_encode(script)
stats_r, stats_w = IO.pipe
out, err, status = EnvUtil.invoke_ruby(args,
'', true, true, timeout: timeout, ios: {3 => stats_w}