Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make load path cache work on TruffleRuby #450

Merged
merged 2 commits into from
Jul 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu]
ruby: ['2.6', '2.7', '3.0', '3.1', '3.2', 'ruby-head', 'debug', 'truffleruby']
ruby: ['2.6', '2.7', '3.0', '3.1', '3.2', 'ruby-head', 'debug', 'truffleruby', 'truffleruby-head']
runs-on: ${{ matrix.os }}-latest
steps:
- uses: actions/checkout@v2
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Unreleased

* Support YAML and JSON CompileCache on TruffleRuby.
* Support LoadPathCache on TruffleRuby.

# 1.16.0

Expand Down
5 changes: 3 additions & 2 deletions lib/bootsnap/compile_cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ def self.permission_error(path)
end

def self.supported?
# only enable on 'ruby' (MRI), POSIX (darwin, linux, *bsd), Windows (RubyInstaller2) and >= 2.3.0
%w[ruby truffleruby].include?(RUBY_ENGINE) && RUBY_PLATFORM.match?(/darwin|linux|bsd|mswin|mingw|cygwin/)
# only enable on 'ruby' (MRI) and TruffleRuby for POSIX (darwin, linux, *bsd), Windows (RubyInstaller2)
%w[ruby truffleruby].include?(RUBY_ENGINE) &&
RUBY_PLATFORM.match?(/darwin|linux|bsd|mswin|mingw|cygwin/)
end
end
end
13 changes: 11 additions & 2 deletions lib/bootsnap/load_path_cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,17 @@ def unload!
end

def supported?
RUBY_ENGINE == "ruby" &&
RUBY_PLATFORM =~ /darwin|linux|bsd|mswin|mingw|cygwin/
if RUBY_PLATFORM.match?(/darwin|linux|bsd|mswin|mingw|cygwin/)
case RUBY_ENGINE
when "truffleruby"
# https://github.com/oracle/truffleruby/issues/3131
RUBY_ENGINE_VERSION >= "23.1.0"
when "ruby"
true
else
false
end
end
end
end
end
Expand Down
8 changes: 8 additions & 0 deletions lib/bootsnap/load_path_cache/cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,16 @@ def load_dir(dir)
@mutex.synchronize { @dirs[dir] }
end

TRUFFLERUBY_LIB_DIR_PREFIX = if RUBY_ENGINE == "truffleruby"
"#{File.join(RbConfig::CONFIG['libdir'], 'truffle')}#{File::SEPARATOR}"
rwstauner marked this conversation as resolved.
Show resolved Hide resolved
end

# { 'enumerator' => nil, 'enumerator.so' => nil, ... }
BUILTIN_FEATURES = $LOADED_FEATURES.each_with_object({}) do |feat, features|
if TRUFFLERUBY_LIB_DIR_PREFIX && feat.start_with?(TRUFFLERUBY_LIB_DIR_PREFIX)
feat = feat.byteslice(TRUFFLERUBY_LIB_DIR_PREFIX.bytesize..-1)
end

# Builtin features are of the form 'enumerator.so'.
# All others include paths.
next unless feat.size < 20 && !feat.include?("/")
Expand Down
12 changes: 12 additions & 0 deletions test/integration/kernel_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ class KernelTest < Minitest::Test
include TmpdirHelper

def test_require_symlinked_file_twice
skip("https://github.com/oracle/truffleruby/issues/3138") if truffleruby?

setup_symlinked_files
if RUBY_VERSION >= "3.1"
# Fixed in https://github.com/ruby/ruby/commit/79a4484a072e9769b603e7b4fbdb15b1d7eccb15 (Ruby 3.1)
Expand Down Expand Up @@ -41,6 +43,8 @@ def test_require_symlinked_file_twice_aliased
end

def test_require_relative_symlinked_file_twice
skip("https://github.com/oracle/truffleruby/issues/3138") if truffleruby?

setup_symlinked_files
if RUBY_VERSION >= "3.1"
# Fixed in https://github.com/ruby/ruby/commit/79a4484a072e9769b603e7b4fbdb15b1d7eccb15 (Ruby 3.1)
Expand Down Expand Up @@ -83,6 +87,8 @@ def test_require_relative_and_then_require_symlinked_file
end

def test_require_deep_symlinked_file_twice
skip("https://github.com/oracle/truffleruby/issues/3138") if truffleruby?

setup_symlinked_files
if RUBY_VERSION >= "3.1"
# Fixed in https://github.com/ruby/ruby/commit/79a4484a072e9769b603e7b4fbdb15b1d7eccb15 (Ruby 3.1)
Expand Down Expand Up @@ -116,6 +122,8 @@ def test_require_deep_symlinked_file_twice_aliased
end

def test_require_relative_deep_symlinked_file_twice
skip("https://github.com/oracle/truffleruby/issues/3138") if truffleruby?

setup_symlinked_files
if RUBY_VERSION >= "3.1"
# Fixed in https://github.com/ruby/ruby/commit/79a4484a072e9769b603e7b4fbdb15b1d7eccb15 (Ruby 3.1)
Expand Down Expand Up @@ -211,5 +219,9 @@ def setup_symlinked_files
RUBY
File.symlink("real", "symlink")
end

def truffleruby?
RUBY_ENGINE == "truffleruby"
end
end
end
36 changes: 29 additions & 7 deletions test/load_path_cache/cache_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,21 @@ def test_builtin_features
assert_equal false, cache.find("thread")
assert_equal false, cache.find("thread.rb")
assert_equal false, cache.find("enumerator")
assert_equal false, cache.find("enumerator.so")

if RUBY_PLATFORM =~ /darwin/
assert_equal false, cache.find("enumerator.bundle")
if truffleruby?
assert_equal false, cache.find("enumerator.rb")
else
assert_same FALLBACK_SCAN, cache.find("enumerator.bundle")
assert_equal false, cache.find("enumerator.so")
if RUBY_PLATFORM =~ /darwin/
assert_equal false, cache.find("enumerator.bundle")
else
assert_same FALLBACK_SCAN, cache.find("enumerator.bundle")
end
end

bundle = RUBY_PLATFORM =~ /darwin/ ? "bundle" : "so"

# These are not present in TruffleRuby but that means they will still return falsey.
refute(cache.find("thread.#{bundle}"))
refute(cache.find("enumerator.rb"))
refute(cache.find("encdb.#{bundle}"))
Expand Down Expand Up @@ -165,9 +170,15 @@ def test_path_encoding
require path
internal_path = $LOADED_FEATURES.last
assert_equal(OS_ASCII_PATH_ENCODING, internal_path.encoding)
assert_equal(OS_ASCII_PATH_ENCODING, path.encoding)
# TruffleRuby object is a copy and the encoding resets to utf-8.
assert_equal(OS_ASCII_PATH_ENCODING, path.encoding) unless truffleruby?
File.write(path, "")
assert_same path, internal_path

if truffleruby?
assert_equal path, internal_path

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comparison different from CRuby due to oracle/truffleruby#3138?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, i haven't filed an issue on truffleruby for it yet, but on CRuby $LOADED_FEATURES.last is the same (frozen) string object, but on TruffleRuby this is not the case (it's a different string object, not frozen).

else
assert_same path, internal_path
end

utf8_path = cache.find("béé")
assert_equal("#{@dir1}/béé.rb", utf8_path)
Expand All @@ -176,9 +187,20 @@ def test_path_encoding
assert_equal(Encoding::UTF_8, internal_utf8_path.encoding)
assert_equal(Encoding::UTF_8, utf8_path.encoding)
File.write(utf8_path, "")
assert_same utf8_path, internal_utf8_path

if truffleruby?
assert_equal utf8_path, internal_utf8_path
else
assert_same utf8_path, internal_utf8_path
end
end
end

private

def truffleruby?
RUBY_ENGINE == "truffleruby"
end
end
end
end