Skip to content

Commit

Permalink
Optimize feature loading when require is called with absolute .rb path
Browse files Browse the repository at this point in the history
If require is called with an absolute path like `/path/to/thing.rb`
we can try that as is first rather than trying `.rb.rb` and `.rb.so` first.

Add require specs for absolute paths:
- with no extension (RB ext and C ext)
- .so becomes .bundle on darwin
  • Loading branch information
rwstauner committed Sep 30, 2023
1 parent f1c7d51 commit 0026103
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 18 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Compatibility:
Performance:

* Optimize calls with `ruby2_keywords` forwarding by deciding it per call site instead of per callee thanks to [my fix in CRuby 3.2](https://bugs.ruby-lang.org/issues/18625) (@eregon).
* Optimize feature loading when require is called with an absolute path to a .rb file (@rwstauner).

Changes:

Expand Down
21 changes: 21 additions & 0 deletions spec/ruby/core/kernel/shared/require.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,27 @@
ScratchPad.recorded.should == []
end

it "loads .rb file when passed absolute path without extension" do
path = File.expand_path "load_fixture", CODE_LOADING_DIR
@object.send(@method, path).should be_true
# This should _not_ be [:no_ext]
ScratchPad.recorded.should == [:loaded]
end

it "loads c-extension file when passed absolute path without extension when no .rb is present" do
path = File.join CODE_LOADING_DIR, "a", "load_fixture"
@object.send(@method, path).should be_true
ScratchPad.recorded.first.to_s.should =~ /^ext_/
end

platform_is :darwin do
it "loads .bundle file when passed absolute path with .so" do
path = File.join CODE_LOADING_DIR, "a", "load_fixture.so"
@object.send(@method, path).should be_true
ScratchPad.recorded.should == [:ext_bundle]
end
end

# Can't make a file unreadable on these platforms
platform_is_not :windows, :cygwin do
as_user do
Expand Down
38 changes: 20 additions & 18 deletions src/main/java/org/truffleruby/language/loader/FeatureLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -379,27 +379,29 @@ private String translateIfNativePath(String feature) {
private String findFeatureWithAndWithoutExtension(String path) {
assert new File(path).isAbsolute();

if (path.endsWith(".so")) {
final String pathWithNativeExt = translateIfNativePath(path);
final String asCExt = findFeatureWithExactPath(pathWithNativeExt);
if (asCExt != null) {
return asCExt;
if (hasExtension(path)) {
if (path.endsWith(".so")) {
final String pathWithNativeExt = translateIfNativePath(path);
final String asCExt = findFeatureWithExactPath(pathWithNativeExt);
if (asCExt != null) {
return asCExt;
}
}
}

final String asRuby = findFeatureWithExactPath(path + TruffleRuby.EXTENSION);
if (asRuby != null) {
return asRuby;
}

final String asCExt = findFeatureWithExactPath(path + RubyLanguage.CEXT_EXTENSION);
if (asCExt != null) {
return asCExt;
}
final String withoutExtension = findFeatureWithExactPath(path);
if (withoutExtension != null) {
return withoutExtension;
}
} else {
final String asRuby = findFeatureWithExactPath(path + TruffleRuby.EXTENSION);
if (asRuby != null) {
return asRuby;
}

final String withoutExtension = findFeatureWithExactPath(path);
if (withoutExtension != null) {
return withoutExtension;
final String asCExt = findFeatureWithExactPath(path + RubyLanguage.CEXT_EXTENSION);
if (asCExt != null) {
return asCExt;
}
}

return null;
Expand Down

0 comments on commit 0026103

Please sign in to comment.