Skip to content

Commit

Permalink
[GR-18163] Store the conversion from native to managed string inside …
Browse files Browse the repository at this point in the history
…the RubyString when matching regexps

PullRequest: truffleruby/4315
  • Loading branch information
eregon committed Jul 22, 2024
2 parents 938589f + 8b3e47b commit 16fdb0a
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Performance:

* Fix inline caching for Regexp creation from Strings (#3492, @andrykonchin, @eregon).
* Optimize `Integer#pow` method for small modulus values (#3544, @andrykonchin).
* Avoid repeated copies from native to managed string when matching Regexps on a native string (#2193, @eregon).

Changes:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
import org.truffleruby.core.kernel.KernelNodes.SameOrEqualNode;
import org.truffleruby.core.regexp.RegexpNodes.ToSNode;
import org.truffleruby.core.string.ATStringWithEncoding;
import org.truffleruby.core.string.StringHelperNodes.StringToTruffleStringInplaceNode;
import org.truffleruby.core.string.TStringBuilder;
import org.truffleruby.core.string.TStringWithEncoding;
import org.truffleruby.core.string.RubyString;
Expand Down Expand Up @@ -897,6 +898,7 @@ static Object matchInRegionTRegex(
boolean atStart,
int startPos,
boolean createMatchData,
@Cached StringToTruffleStringInplaceNode stringToTruffleStringInplaceNode,
@Cached TruffleString.SwitchEncodingNode switchEncodingNode,
@Cached InlinedConditionProfile createMatchDataProfile,
@Cached InlinedConditionProfile matchFoundProfile,
Expand All @@ -916,11 +918,12 @@ static Object matchInRegionTRegex(
@Cached LazyMatchInRegionNode fallbackMatchInRegionNode,
@Cached LazyTruffleStringSubstringByteIndexNode substringByteIndexNode,
@Bind("this") Node node) {
final Object tRegex;
stringToTruffleStringInplaceNode.execute(node, string);
final RubyEncoding negotiatedEncoding = prepareRegexpEncodingNode.executePrepare(node, regexp, string);
var tstring = switchEncodingNode.execute(libString.getTString(string), negotiatedEncoding.tencoding);
final int byteLength = tstring.byteLength(negotiatedEncoding.tencoding);

final Object tRegex;
if (tRegexIncompatibleProfile
.profile(node, toPos < fromPos || toPos != byteLength || fromPos < 0) ||
tRegexCouldNotCompileProfile.profile(node, (tRegex = tRegexCompileNode.executeTRegexCompile(
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/org/truffleruby/core/string/StringHelperNodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -621,4 +621,26 @@ static RubyString stringAppend(Node node, Object string, Object other,
}
}

/** Stores the TruffleString back in the Ruby String to avoid repeated copies from native to managed */
@GenerateInline
@GenerateCached(false)
public abstract static class StringToTruffleStringInplaceNode extends RubyBaseNode {

public abstract TruffleString execute(Node node, Object string);

@Specialization
static TruffleString immutable(ImmutableRubyString string) {
return string.tstring;
}

@Specialization
static TruffleString mutable(RubyString string,
@Cached RubyStringLibrary libString,
@Cached(inline = false) TruffleString.AsTruffleStringNode asTruffleStringNode) {
TruffleString tstring = asTruffleStringNode.execute(string.tstring, libString.getTEncoding(string));
string.setTString(tstring);
return tstring;
}
}

}

0 comments on commit 16fdb0a

Please sign in to comment.