Skip to content

Commit cbd0cb3

Browse files
committed
NegotiateCompatibleStringEncodingNode supports DSL inlining
1 parent 8b33e16 commit cbd0cb3

File tree

4 files changed

+54
-57
lines changed

4 files changed

+54
-57
lines changed

src/main/java/org/truffleruby/core/encoding/EncodingNodes.java

Lines changed: 36 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import org.truffleruby.core.array.RubyArray;
3434
import org.truffleruby.core.cast.ToRubyEncodingNode;
3535
import org.truffleruby.core.encoding.EncodingNodesFactory.NegotiateCompatibleEncodingNodeGen;
36-
import org.truffleruby.core.encoding.EncodingNodesFactory.NegotiateCompatibleStringEncodingNodeGen;
3736
import org.truffleruby.core.klass.RubyClass;
3837
import org.truffleruby.core.proc.RubyProc;
3938
import org.truffleruby.core.string.RubyString;
@@ -69,23 +68,18 @@ protected boolean isAsciiCompatible(RubyEncoding encoding) {
6968

7069
// MRI: enc_compatible_str and enc_compatible_latter
7170
@ImportStatic(TruffleString.CodeRange.class)
71+
@GenerateCached(false)
72+
@GenerateInline
7273
public abstract static class NegotiateCompatibleStringEncodingNode extends RubyBaseNode {
7374

74-
@Child TruffleString.GetByteCodeRangeNode codeRangeNode;
75-
76-
@NeverDefault
77-
public static NegotiateCompatibleStringEncodingNode create() {
78-
return NegotiateCompatibleStringEncodingNodeGen.create();
79-
}
80-
81-
public abstract RubyEncoding execute(AbstractTruffleString first, RubyEncoding firstEncoding,
75+
public abstract RubyEncoding execute(Node node, AbstractTruffleString first, RubyEncoding firstEncoding,
8276
AbstractTruffleString second, RubyEncoding secondEncoding);
8377

8478
@Specialization(guards = {
8579
"firstEncoding == cachedEncoding",
8680
"secondEncoding == cachedEncoding",
8781
}, limit = "getCacheLimit()")
88-
protected RubyEncoding negotiateSameEncodingCached(
82+
protected static RubyEncoding negotiateSameEncodingCached(
8983
AbstractTruffleString first,
9084
RubyEncoding firstEncoding,
9185
AbstractTruffleString second,
@@ -98,7 +92,7 @@ protected RubyEncoding negotiateSameEncodingCached(
9892

9993

10094
@Specialization(guards = "firstEncoding == secondEncoding", replaces = "negotiateSameEncodingCached")
101-
protected RubyEncoding negotiateSameEncodingUncached(
95+
protected static RubyEncoding negotiateSameEncodingUncached(
10296
AbstractTruffleString first,
10397
RubyEncoding firstEncoding,
10498
AbstractTruffleString second,
@@ -112,13 +106,14 @@ protected RubyEncoding negotiateSameEncodingUncached(
112106
"firstEncoding != secondEncoding",
113107
"firstEncoding == cachedEncoding",
114108
"isStandardEncoding(cachedEncoding)",
115-
"getCodeRange(second, secondEncoding) == ASCII"
109+
"codeRangeNode.execute(second, secondEncoding.tencoding) == ASCII"
116110
}, limit = "NUMBER_OF_STANDARD_ENCODINGS")
117-
protected RubyEncoding negotiateStandardEncodingAndCr7Bit(
111+
protected static RubyEncoding negotiateStandardEncodingAndCr7Bit(
118112
AbstractTruffleString first,
119113
RubyEncoding firstEncoding,
120114
AbstractTruffleString second,
121115
RubyEncoding secondEncoding,
116+
@Cached(inline = false) @Shared TruffleString.GetByteCodeRangeNode codeRangeNode,
122117
@Cached("firstEncoding") RubyEncoding cachedEncoding) {
123118
// Encoding negotiation of two strings is most often between strings with the same encoding. The next most
124119
// frequent case is two strings with different encodings, but each being one of the standard/default runtime
@@ -135,35 +130,39 @@ protected RubyEncoding negotiateStandardEncodingAndCr7Bit(
135130
"second.isEmpty() == isSecondEmpty",
136131
"cachedFirstEncoding == firstEncoding",
137132
"cachedSecondEncoding == secondEncoding",
138-
"getCodeRange(first, firstEncoding) == firstCodeRange",
139-
"getCodeRange(second, secondEncoding) == secondCodeRange" },
133+
"firstCodeRange == firstCodeRangeCached",
134+
"secondCodeRange == secondCodeRangeCached" },
140135
limit = "getCacheLimit()")
141-
protected RubyEncoding negotiateEncodingCached(
136+
protected static RubyEncoding negotiateEncodingCached(
142137
AbstractTruffleString first,
143138
RubyEncoding firstEncoding,
144139
AbstractTruffleString second,
145140
RubyEncoding secondEncoding,
146141
@Cached("first.isEmpty()") boolean isFirstEmpty,
147142
@Cached("second.isEmpty()") boolean isSecondEmpty,
148-
@Cached("getCodeRange(first, firstEncoding)") TruffleString.CodeRange firstCodeRange,
149-
@Cached("getCodeRange(second, secondEncoding)") TruffleString.CodeRange secondCodeRange,
143+
@Cached(inline = false) @Shared TruffleString.GetByteCodeRangeNode codeRangeNode,
144+
@Bind("codeRangeNode.execute(first, firstEncoding.tencoding)") TruffleString.CodeRange firstCodeRange,
145+
@Bind("codeRangeNode.execute(second, secondEncoding.tencoding)") TruffleString.CodeRange secondCodeRange,
146+
@Cached("firstCodeRange") TruffleString.CodeRange firstCodeRangeCached,
147+
@Cached("secondCodeRange") TruffleString.CodeRange secondCodeRangeCached,
150148
@Cached("firstEncoding") RubyEncoding cachedFirstEncoding,
151149
@Cached("secondEncoding") RubyEncoding cachedSecondEncoding,
152-
@Cached("compatibleEncodingForStrings(first, firstEncoding, second, secondEncoding)") RubyEncoding negotiatedEncoding) {
150+
@Cached("compatibleEncodingForStrings(first, firstEncoding, second, secondEncoding, codeRangeNode)") RubyEncoding negotiatedEncoding) {
153151
assert first.isCompatibleToUncached(firstEncoding.tencoding) &&
154152
second.isCompatibleToUncached(secondEncoding.tencoding);
155153
return negotiatedEncoding;
156154
}
157155

158156
@Specialization(guards = "firstEncoding != secondEncoding", replaces = "negotiateEncodingCached")
159-
protected RubyEncoding negotiateEncodingUncached(
157+
protected static RubyEncoding negotiateEncodingUncached(
160158
AbstractTruffleString first,
161159
RubyEncoding firstEncoding,
162160
AbstractTruffleString second,
163-
RubyEncoding secondEncoding) {
161+
RubyEncoding secondEncoding,
162+
@Cached(inline = false) @Shared TruffleString.GetByteCodeRangeNode codeRangeNode) {
164163
assert first.isCompatibleToUncached(firstEncoding.tencoding) &&
165164
second.isCompatibleToUncached(secondEncoding.tencoding);
166-
return compatibleEncodingForStrings(first, firstEncoding, second, secondEncoding);
165+
return compatibleEncodingForStrings(first, firstEncoding, second, secondEncoding, codeRangeNode);
167166
}
168167

169168
/** This method returns non-null if either:
@@ -173,8 +172,10 @@ protected RubyEncoding negotiateEncodingUncached(
173172
* </ul>
174173
*/
175174
@TruffleBoundary
176-
protected RubyEncoding compatibleEncodingForStrings(AbstractTruffleString first, RubyEncoding firstEncoding,
177-
AbstractTruffleString second, RubyEncoding secondEncoding) {
175+
protected static RubyEncoding compatibleEncodingForStrings(AbstractTruffleString first,
176+
RubyEncoding firstEncoding,
177+
AbstractTruffleString second, RubyEncoding secondEncoding,
178+
TruffleString.GetByteCodeRangeNode codeRangeNode) {
178179
// MRI: enc_compatible_latter
179180
assert firstEncoding != secondEncoding : "this method assumes the encodings are different";
180181

@@ -183,7 +184,7 @@ protected RubyEncoding compatibleEncodingForStrings(AbstractTruffleString first,
183184
}
184185
if (first.isEmpty()) {
185186
return (firstEncoding.isAsciiCompatible &&
186-
StringGuards.is7Bit(second, secondEncoding, getCodeRangeNode()))
187+
StringGuards.is7Bit(second, secondEncoding, codeRangeNode))
187188
? firstEncoding
188189
: secondEncoding;
189190
}
@@ -192,10 +193,10 @@ protected RubyEncoding compatibleEncodingForStrings(AbstractTruffleString first,
192193
return null;
193194
}
194195

195-
if (StringGuards.is7Bit(second, secondEncoding, getCodeRangeNode())) {
196+
if (StringGuards.is7Bit(second, secondEncoding, codeRangeNode)) {
196197
return firstEncoding;
197198
}
198-
if (StringGuards.is7Bit(first, firstEncoding, getCodeRangeNode())) {
199+
if (StringGuards.is7Bit(first, firstEncoding, codeRangeNode)) {
199200
return secondEncoding;
200201
}
201202

@@ -206,19 +207,6 @@ protected int getCacheLimit() {
206207
return getLanguage().options.ENCODING_COMPATIBLE_QUERY_CACHE;
207208
}
208209

209-
protected TruffleString.CodeRange getCodeRange(AbstractTruffleString string, RubyEncoding encoding) {
210-
return getCodeRangeNode().execute(string, encoding.tencoding);
211-
}
212-
213-
private TruffleString.GetByteCodeRangeNode getCodeRangeNode() {
214-
if (codeRangeNode == null) {
215-
CompilerDirectives.transferToInterpreterAndInvalidate();
216-
codeRangeNode = insert(TruffleString.GetByteCodeRangeNode.create());
217-
}
218-
219-
return codeRangeNode;
220-
}
221-
222210
protected static final int NUMBER_OF_STANDARD_ENCODINGS = 3;
223211

224212
/** Indicates whether the encoding is one of the runtime-default encodings. Many (most?) applications do not
@@ -267,13 +255,15 @@ protected RubyEncoding negotiateSameEncodingUncached(Object first, Object second
267255
}
268256

269257
@Specialization(guards = { "libFirst.isRubyString(first)", "libSecond.isRubyString(second)" }, limit = "1")
270-
protected RubyEncoding negotiateStringStringEncoding(Object first, Object second,
258+
protected static RubyEncoding negotiateStringStringEncoding(Object first, Object second,
271259
@Cached @Shared RubyStringLibrary libFirst,
272260
@Cached @Shared RubyStringLibrary libSecond,
273-
@Cached NegotiateCompatibleStringEncodingNode negotiateNode) {
261+
@Cached NegotiateCompatibleStringEncodingNode negotiateNode,
262+
@Bind("this") Node node) {
274263
final RubyEncoding firstEncoding = libFirst.getEncoding(first);
275264
final RubyEncoding secondEncoding = libSecond.getEncoding(second);
276265
return negotiateNode.execute(
266+
node,
277267
libFirst.getTString(first),
278268
firstEncoding,
279269
libSecond.getTString(second),
@@ -454,7 +444,7 @@ protected Object areCompatible(Object first, Object second,
454444
@Cached RubyStringLibrary libSecond,
455445
@Cached NegotiateCompatibleStringEncodingNode negotiateCompatibleStringEncodingNode,
456446
@Cached InlinedConditionProfile noNegotiatedEncodingProfile) {
457-
final RubyEncoding negotiatedEncoding = negotiateCompatibleStringEncodingNode.execute(
447+
final RubyEncoding negotiatedEncoding = negotiateCompatibleStringEncodingNode.execute(this,
458448
libFirst.getTString(first), libFirst.getEncoding(first),
459449
libSecond.getTString(second), libSecond.getEncoding(second));
460450

@@ -783,7 +773,8 @@ protected static RubyEncoding checkEncodingStringString(Object first, Object sec
783773
final RubyEncoding secondEncoding = libSecond.getEncoding(second);
784774

785775
final RubyEncoding negotiatedEncoding = negotiateCompatibleStringEncodingNode
786-
.execute(libFirst.getTString(first), firstEncoding, libSecond.getTString(second), secondEncoding);
776+
.execute(node, libFirst.getTString(first), firstEncoding, libSecond.getTString(second),
777+
secondEncoding);
787778

788779
if (negotiatedEncoding == null) {
789780
errorProfile.enter(node);
@@ -813,7 +804,7 @@ protected static RubyEncoding checkEncoding(
813804
RubyEncoding secondEncoding,
814805
@Cached InlinedBranchProfile errorProfile,
815806
@Cached NegotiateCompatibleStringEncodingNode negotiateCompatibleEncodingNode) {
816-
var negotiatedEncoding = negotiateCompatibleEncodingNode.execute(first, firstEncoding, second,
807+
var negotiatedEncoding = negotiateCompatibleEncodingNode.execute(node, first, firstEncoding, second,
817808
secondEncoding);
818809

819810
if (negotiatedEncoding == null) {

src/main/java/org/truffleruby/core/inlined/InlinedEqualNode.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
package org.truffleruby.core.inlined;
1111

1212
import com.oracle.truffle.api.Assumption;
13+
import com.oracle.truffle.api.dsl.Bind;
1314
import com.oracle.truffle.api.dsl.Cached;
15+
import com.oracle.truffle.api.nodes.Node;
1416
import org.truffleruby.RubyLanguage;
1517
import org.truffleruby.core.encoding.EncodingNodes;
1618
import org.truffleruby.core.string.StringHelperNodes;
@@ -67,17 +69,18 @@ protected boolean doubleLong(double a, long b) {
6769
"lookupNode.lookupProtected(frame, a, METHOD) == coreMethods().STRING_EQUAL"
6870
},
6971
assumptions = "assumptions", limit = "1")
70-
protected boolean stringEqual(VirtualFrame frame, Object a, Object b,
72+
protected static boolean stringEqual(VirtualFrame frame, Object a, Object b,
7173
@Cached RubyStringLibrary libA,
7274
@Cached RubyStringLibrary libB,
7375
@Cached LookupMethodOnSelfNode lookupNode,
7476
@Cached EncodingNodes.NegotiateCompatibleStringEncodingNode negotiateCompatibleStringEncodingNode,
75-
@Cached StringHelperNodes.StringEqualInternalNode stringEqualInternalNode) {
77+
@Cached StringHelperNodes.StringEqualInternalNode stringEqualInternalNode,
78+
@Bind("this") Node node) {
7679
var tstringA = libA.getTString(a);
7780
var encA = libA.getEncoding(a);
7881
var tstringB = libB.getTString(b);
7982
var encB = libB.getEncoding(b);
80-
var compatibleEncoding = negotiateCompatibleStringEncodingNode.execute(tstringA, encA, tstringB, encB);
83+
var compatibleEncoding = negotiateCompatibleStringEncodingNode.execute(node, tstringA, encA, tstringB, encB);
8184
return stringEqualInternalNode.executeInternal(tstringA, tstringB, compatibleEncoding);
8285
}
8386

src/main/java/org/truffleruby/core/string/StringHelperNodes.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public abstract boolean execute(AbstractTruffleString tstring, RubyEncoding enco
108108
protected boolean equal(AbstractTruffleString a, RubyEncoding encA, TruffleString b, RubyEncoding encB,
109109
@Cached EncodingNodes.NegotiateCompatibleStringEncodingNode negotiateCompatibleStringEncodingNode,
110110
@Cached StringEqualInternalNode stringEqualInternalNode) {
111-
var compatibleEncoding = negotiateCompatibleStringEncodingNode.execute(a, encA, b, encB);
111+
var compatibleEncoding = negotiateCompatibleStringEncodingNode.execute(this, a, encA, b, encB);
112112
return stringEqualInternalNode.executeInternal(a, b, compatibleEncoding);
113113
}
114114
}
@@ -308,9 +308,10 @@ protected Object deleteBangEmpty(RubyString string, Object[] args) {
308308
}
309309

310310
@Specialization
311-
protected Object deleteBangString(RubyString string, TStringWithEncoding[] args,
312-
@Cached DeleteBangStringsNode deleteBangStringsNode) {
313-
return deleteBangStringsNode.execute(this, string, args);
311+
protected static Object deleteBangString(RubyString string, TStringWithEncoding[] args,
312+
@Cached DeleteBangStringsNode deleteBangStringsNode,
313+
@Bind("this") Node node) {
314+
return deleteBangStringsNode.execute(node, string, args);
314315
}
315316
}
316317

src/main/java/org/truffleruby/core/string/StringNodes.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -304,16 +304,18 @@ public abstract static class EqualCoreMethodNode extends CoreMethodArrayArgument
304304
@Child private BooleanCastNode booleanCastNode;
305305

306306
@Specialization(guards = "libB.isRubyString(b)", limit = "1")
307-
protected boolean equalString(Object a, Object b,
307+
protected static boolean equalString(Object a, Object b,
308308
@Cached RubyStringLibrary libA,
309309
@Cached RubyStringLibrary libB,
310310
@Cached NegotiateCompatibleStringEncodingNode negotiateCompatibleStringEncodingNode,
311-
@Cached StringHelperNodes.StringEqualInternalNode stringEqualInternalNode) {
311+
@Cached StringHelperNodes.StringEqualInternalNode stringEqualInternalNode,
312+
@Bind("this") Node node) {
312313
var tstringA = libA.getTString(a);
313314
var encA = libA.getEncoding(a);
314315
var tstringB = libB.getTString(b);
315316
var encB = libB.getEncoding(b);
316-
var compatibleEncoding = negotiateCompatibleStringEncodingNode.execute(tstringA, encA, tstringB, encB);
317+
var compatibleEncoding = negotiateCompatibleStringEncodingNode.execute(node, tstringA, encA, tstringB,
318+
encB);
317319
return stringEqualInternalNode.executeInternal(tstringA, tstringB, compatibleEncoding);
318320
}
319321

@@ -781,7 +783,7 @@ protected static Object caseCmpSingleByte(Node node, Object string, Object other
781783
@Cached(inline = false) TruffleString.GetInternalByteArrayNode byteArrayOtherNode) {
782784
// Taken from org.jruby.RubyString#casecmp19.
783785

784-
final RubyEncoding encoding = negotiateCompatibleEncodingNode.execute(selfTString, selfEncoding,
786+
final RubyEncoding encoding = negotiateCompatibleEncodingNode.execute(node, selfTString, selfEncoding,
785787
otherTString, otherEncoding);
786788
if (incompatibleEncodingProfile.profile(node, encoding == null)) {
787789
return nil;
@@ -813,7 +815,7 @@ protected static Object caseCmp(Node node, Object string, Object other,
813815
@Bind("libOther.getEncoding(other)") RubyEncoding otherEncoding) {
814816
// Taken from org.jruby.RubyString#casecmp19
815817

816-
final RubyEncoding encoding = negotiateCompatibleEncodingNode.execute(selfTString, selfEncoding,
818+
final RubyEncoding encoding = negotiateCompatibleEncodingNode.execute(node, selfTString, selfEncoding,
817819
otherTString, otherEncoding);
818820

819821
if (incompatibleEncodingProfile.profile(node, encoding == null)) {

0 commit comments

Comments
 (0)