Skip to content

Commit 47e5274

Browse files
committed
Adding LazyTranslateInteropExceptionNode, LazyDispatchNode and LazyTruffleStringSubStringByteIndexNode
1 parent 1b3c003 commit 47e5274

File tree

3 files changed

+98
-47
lines changed

3 files changed

+98
-47
lines changed

src/main/java/org/truffleruby/core/regexp/TruffleRegexpNodes.java

Lines changed: 64 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@
2626
import com.oracle.truffle.api.TruffleSafepoint;
2727
import com.oracle.truffle.api.dsl.Bind;
2828
import com.oracle.truffle.api.dsl.Fallback;
29+
import com.oracle.truffle.api.dsl.GenerateCached;
30+
import com.oracle.truffle.api.dsl.GenerateInline;
2931
import com.oracle.truffle.api.dsl.ImportStatic;
32+
import com.oracle.truffle.api.dsl.NeverDefault;
3033
import com.oracle.truffle.api.interop.InteropException;
3134
import com.oracle.truffle.api.interop.InteropLibrary;
3235
import com.oracle.truffle.api.library.CachedLibrary;
@@ -65,8 +68,8 @@
6568
import org.truffleruby.core.string.StringNodes.StringAppendPrimitiveNode;
6669
import org.truffleruby.core.string.StringOperations;
6770
import org.truffleruby.core.string.StringUtils;
71+
import org.truffleruby.interop.LazyTranslateInteropExceptionNode;
6872
import org.truffleruby.interop.TranslateInteropExceptionNode;
69-
import org.truffleruby.interop.TranslateInteropExceptionNodeGen;
7073
import org.truffleruby.language.LazyWarnNode;
7174
import org.truffleruby.language.RubyBaseNode;
7275
import org.truffleruby.language.RubyGuards;
@@ -83,6 +86,7 @@
8386
import com.oracle.truffle.api.nodes.ExplodeLoop;
8487
import com.oracle.truffle.api.nodes.Node;
8588
import com.oracle.truffle.api.profiles.ConditionProfile;
89+
import org.truffleruby.language.dispatch.LazyDispatchNode;
8690
import org.truffleruby.language.library.RubyStringLibrary;
8791
import org.truffleruby.language.objects.AllocationTracing;
8892
import org.truffleruby.parser.RubyDeferredWarnings;
@@ -752,6 +756,7 @@ private <K, V> void buildAndSetDistributionHash(HashStoreLibrary hashStoreLibrar
752756
@Primitive(name = "regexp_match_in_region", lowerFixnum = { 2, 3, 5 })
753757
public abstract static class MatchInRegionNode extends PrimitiveArrayArgumentsNode {
754758

759+
@NeverDefault
755760
public static MatchInRegionNode create() {
756761
return TruffleRegexpNodesFactory.MatchInRegionNodeFactory.create(null);
757762
}
@@ -826,16 +831,43 @@ protected static Object matchInRegion(
826831
}
827832
}
828833

829-
@Primitive(name = "regexp_match_in_region_tregex", lowerFixnum = { 2, 3, 5 })
830-
public abstract static class MatchInRegionTRegexNode extends PrimitiveArrayArgumentsNode {
834+
@GenerateCached(false)
835+
@GenerateInline(inlineByDefault = true)
836+
public abstract static class LazyMatchInRegionNode extends RubyBaseNode {
831837

832-
@Child MatchInRegionNode fallbackMatchInRegionNode;
833-
@Child DispatchNode warnOnFallbackNode;
838+
public final MatchInRegionNode get(Node node) {
839+
return execute(node);
840+
}
841+
842+
protected abstract MatchInRegionNode execute(Node node);
843+
844+
@Specialization
845+
protected static MatchInRegionNode doLazy(
846+
@Cached(inline = false) MatchInRegionNode matchInRegionNode) {
847+
return matchInRegionNode;
848+
}
849+
}
850+
851+
@GenerateCached(false)
852+
@GenerateInline(inlineByDefault = true)
853+
public abstract static class LazyTruffleStringSubstringByteIndexNode extends RubyBaseNode {
854+
855+
public final TruffleString.SubstringByteIndexNode get(Node node) {
856+
return execute(node);
857+
}
858+
859+
protected abstract TruffleString.SubstringByteIndexNode execute(Node node);
860+
861+
@Specialization
862+
protected static TruffleString.SubstringByteIndexNode doLazy(
863+
@Cached(inline = false) TruffleString.SubstringByteIndexNode substringByteIndexNode) {
864+
return substringByteIndexNode;
865+
}
866+
}
834867

835-
@Child DispatchNode stringDupNode;
836-
@Child TranslateInteropExceptionNode translateInteropExceptionNode;
868+
@Primitive(name = "regexp_match_in_region_tregex", lowerFixnum = { 2, 3, 5 })
869+
public abstract static class MatchInRegionTRegexNode extends PrimitiveArrayArgumentsNode {
837870

838-
@Child TruffleString.SubstringByteIndexNode substringByteIndexNode;
839871

840872
@Specialization(guards = "libString.isRubyString(string)", limit = "1")
841873
protected Object matchInRegionTRegex(
@@ -858,7 +890,12 @@ protected Object matchInRegionTRegex(
858890
@Cached PrepareRegexpEncodingNode prepareRegexpEncodingNode,
859891
@Cached TRegexCompileNode tRegexCompileNode,
860892
@Cached RubyStringLibrary libString,
861-
@Cached(inline = false) IntValueProfile groupCountProfile) {
893+
@Cached(inline = false) IntValueProfile groupCountProfile,
894+
@Cached LazyDispatchNode warnOnFallbackNode,
895+
@Cached LazyDispatchNode stringDupNode,
896+
@Cached LazyTranslateInteropExceptionNode lazyTranslateInteropExceptionNode,
897+
@Cached LazyMatchInRegionNode fallbackMatchInRegionNode,
898+
@Cached LazyTruffleStringSubstringByteIndexNode substringByteIndexNode) {
862899
final Object tRegex;
863900
final RubyEncoding negotiatedEncoding = prepareRegexpEncodingNode.executePrepare(regexp, string);
864901
var tstring = switchEncodingNode.execute(libString.getTString(string), negotiatedEncoding.tencoding);
@@ -878,7 +915,9 @@ protected Object matchInRegionTRegex(
878915
toPos,
879916
atStart,
880917
startPos,
881-
createMatchData);
918+
createMatchData,
919+
warnOnFallbackNode.get(this),
920+
fallbackMatchInRegionNode.get(this));
882921
}
883922

884923
if (getContext().getOptions().REGEXP_INSTRUMENT_MATCH) {
@@ -900,11 +939,7 @@ protected Object matchInRegionTRegex(
900939
assert fromPos == startPos;
901940
fromIndex = 0;
902941

903-
if (substringByteIndexNode == null) {
904-
CompilerDirectives.transferToInterpreterAndInvalidate();
905-
substringByteIndexNode = insert(TruffleString.SubstringByteIndexNode.create());
906-
}
907-
tstringToMatch = substringByteIndexNode.execute(tstring, startPos, toPos - startPos,
942+
tstringToMatch = substringByteIndexNode.get(this).execute(tstring, startPos, toPos - startPos,
908943
negotiatedEncoding.tencoding, true);
909944
} else {
910945
tstringToMatch = tstring;
@@ -917,15 +952,17 @@ protected Object matchInRegionTRegex(
917952
tstringToMatch = tstring;
918953
execMethod = "execBoolean";
919954
}
920-
921-
final Object result = invoke(regexInterop, tRegex, execMethod, tstringToMatch, fromIndex);
955+
final Object result = invoke(regexInterop, tRegex, execMethod, lazyTranslateInteropExceptionNode.get(this),
956+
tstringToMatch, fromIndex);
922957

923958
if (createMatchDataProfile.profile(createMatchData)) {
924-
final boolean isMatch = (boolean) readMember(resultInterop, result, "isMatch");
959+
final boolean isMatch = (boolean) readMember(resultInterop, result, "isMatch",
960+
lazyTranslateInteropExceptionNode.get(this));
925961

926962
if (matchFoundProfile.profile(isMatch)) {
927963
final int groupCount = groupCountProfile
928-
.profile((int) readMember(regexInterop, tRegex, "groupCount"));
964+
.profile((int) readMember(regexInterop, tRegex, "groupCount",
965+
lazyTranslateInteropExceptionNode.get(this)));
929966
final Region region = new Region(groupCount);
930967

931968
try {
@@ -938,7 +975,7 @@ protected Object matchInRegionTRegex(
938975
profileAndReportLoopCount(loopProfile, groupCount);
939976
}
940977

941-
return createMatchData(regexp, dupString(string), region, result);
978+
return createMatchData(regexp, dupString(string, stringDupNode.get(this)), region, result);
942979
} else {
943980
return nil;
944981
}
@@ -948,12 +985,9 @@ protected Object matchInRegionTRegex(
948985
}
949986

950987
private Object fallbackToJoni(RubyRegexp regexp, Object string, RubyEncoding encoding, int fromPos, int toPos,
951-
boolean atStart, int startPos, boolean createMatchData) {
988+
boolean atStart, int startPos, boolean createMatchData, DispatchNode warnOnFallbackNode,
989+
MatchInRegionNode fallbackMatchInRegionNode) {
952990
if (getContext().getOptions().WARN_TRUFFLE_REGEX_MATCH_FALLBACK) {
953-
if (warnOnFallbackNode == null) {
954-
CompilerDirectives.transferToInterpreterAndInvalidate();
955-
warnOnFallbackNode = insert(DispatchNode.create());
956-
}
957991

958992
warnOnFallbackNode.call(
959993
getContext().getCoreLibrary().truffleRegexpOperationsModule,
@@ -968,11 +1002,6 @@ private Object fallbackToJoni(RubyRegexp regexp, Object string, RubyEncoding enc
9681002
startPos });
9691003
}
9701004

971-
if (fallbackMatchInRegionNode == null) {
972-
CompilerDirectives.transferToInterpreterAndInvalidate();
973-
fallbackMatchInRegionNode = insert(MatchInRegionNode.create());
974-
}
975-
9761005
return fallbackMatchInRegionNode
9771006
.executeMatchInRegion(regexp, string, fromPos, toPos, atStart, startPos, createMatchData);
9781007
}
@@ -989,36 +1018,25 @@ private Object createMatchData(RubyRegexp regexp, Object string, Region region,
9891018
return matchData;
9901019
}
9911020

992-
private Object readMember(InteropLibrary interop, Object receiver, String name) {
1021+
private Object readMember(InteropLibrary interop, Object receiver, String name,
1022+
TranslateInteropExceptionNode translateInteropExceptionNode) {
9931023
try {
9941024
return interop.readMember(receiver, name);
9951025
} catch (InteropException e) {
996-
if (translateInteropExceptionNode == null) {
997-
CompilerDirectives.transferToInterpreterAndInvalidate();
998-
translateInteropExceptionNode = insert(TranslateInteropExceptionNodeGen.create());
999-
}
10001026
throw translateInteropExceptionNode.execute(e);
10011027
}
10021028
}
10031029

1004-
private Object invoke(InteropLibrary interop, Object receiver, String member, Object... args) {
1030+
private Object invoke(InteropLibrary interop, Object receiver, String member,
1031+
TranslateInteropExceptionNode translateInteropExceptionNode, Object... args) {
10051032
try {
10061033
return interop.invokeMember(receiver, member, args);
10071034
} catch (InteropException e) {
1008-
if (translateInteropExceptionNode == null) {
1009-
CompilerDirectives.transferToInterpreterAndInvalidate();
1010-
translateInteropExceptionNode = insert(TranslateInteropExceptionNodeGen.create());
1011-
}
10121035
throw translateInteropExceptionNode.executeInInvokeMember(e, receiver, args);
10131036
}
10141037
}
10151038

1016-
private Object dupString(Object string) {
1017-
if (stringDupNode == null) {
1018-
CompilerDirectives.transferToInterpreterAndInvalidate();
1019-
stringDupNode = insert(DispatchNode.create());
1020-
}
1021-
1039+
private Object dupString(Object string, DispatchNode stringDupNode) {
10221040
return stringDupNode.call(string, "dup");
10231041
}
10241042
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved. This
3+
* code is released under a tri EPL/GPL/LGPL license. You can use it,
4+
* redistribute it and/or modify it under the terms of the:
5+
*
6+
* Eclipse Public License version 2.0, or
7+
* GNU General Public License version 2, or
8+
* GNU Lesser General Public License version 2.1.
9+
*/
10+
package org.truffleruby.interop;
11+
12+
import com.oracle.truffle.api.dsl.Cached;
13+
import com.oracle.truffle.api.dsl.GenerateCached;
14+
import com.oracle.truffle.api.dsl.GenerateInline;
15+
import com.oracle.truffle.api.dsl.Specialization;
16+
import com.oracle.truffle.api.nodes.Node;
17+
import org.truffleruby.language.RubyBaseNode;
18+
19+
@GenerateCached(false)
20+
@GenerateInline(inlineByDefault = true)
21+
public abstract class LazyTranslateInteropExceptionNode extends RubyBaseNode {
22+
23+
public final TranslateInteropExceptionNode get(Node node) {
24+
return execute(node);
25+
}
26+
27+
protected abstract TranslateInteropExceptionNode execute(Node node);
28+
29+
@Specialization
30+
protected static TranslateInteropExceptionNode doLazy(
31+
@Cached(inline = false) TranslateInteropExceptionNode translateInteropExceptionNode) {
32+
return translateInteropExceptionNode;
33+
}
34+
}

src/main/java/org/truffleruby/language/dispatch/LazyDispatchNode.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
@GenerateInline(inlineByDefault = true)
2121
public abstract class LazyDispatchNode extends RubyBaseNode {
2222

23-
2423
public final DispatchNode get(Node node) {
2524
return execute(node);
2625
}

0 commit comments

Comments
 (0)