-
-
Notifications
You must be signed in to change notification settings - Fork 925
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Truffle] Extract areComparable() into its own node for String#==.
- 9.4.12.0
- 9.4.11.0
- 9.4.10.0
- 9.4.9.0
- 9.4.8.0
- 9.4.7.0
- 9.4.6.0
- 9.4.5.0
- 9.4.4.0
- 9.4.3.0
- 9.4.2.0
- 9.4.1.0
- 9.4.0.0
- 9.3.15.0
- 9.3.14.0
- 9.3.13.0
- 9.3.12.0
- 9.3.11.0
- 9.3.10.0
- 9.3.9.0
- 9.3.8.0
- 9.3.7.0
- 9.3.6.0
- 9.3.5.0
- 9.3.4.0
- 9.3.3.0
- 9.3.2.0
- 9.3.1.0
- 9.3.0.0
- 9.2.21.0
- 9.2.20.1
- 9.2.20.0
- 9.2.19.0
- 9.2.18.0
- 9.2.17.0
- 9.2.16.0
- 9.2.15.0
- 9.2.14.0
- 9.2.13.0
- 9.2.12.0
- 9.2.11.1
- 9.2.11.0
- 9.2.10.0
- 9.2.9.0
- 9.2.8.0
- 9.2.7.0
- 9.2.6.0
- 9.2.5.0
- 9.2.4.1
- 9.2.4.0
- 9.2.3.0
- 9.2.2.0
- 9.2.1.0
- 9.2.0.0
- 9.1.17.0
- 9.1.16.0
- 9.1.15.0
- 9.1.14.0
- 9.1.13.0
- 9.1.12.0
- 9.1.11.0
- 9.1.10.0
- 9.1.9.0
- 9.1.8.0
- 9.1.7.0
- 9.1.6.0
- 9.1.5.0
- 9.1.4.0
- 9.1.3.0
Showing
1 changed file
with
68 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -124,6 +124,7 @@ | |
import org.jruby.truffle.core.rope.RopeNodesFactory; | ||
import org.jruby.truffle.core.rope.RopeOperations; | ||
import org.jruby.truffle.core.rope.SubstringRope; | ||
import org.jruby.truffle.core.string.StringNodesFactory.StringAreComparableNodeGen; | ||
import org.jruby.truffle.language.NotProvided; | ||
import org.jruby.truffle.language.RubyGuards; | ||
import org.jruby.truffle.language.RubyNode; | ||
|
@@ -2957,13 +2958,71 @@ private String formatError(int start) { | |
|
||
} | ||
|
||
@NodeChildren({ @NodeChild("first"), @NodeChild("second") }) | ||
public static abstract class StringAreComparableNode extends RubyNode { | ||
|
||
public abstract boolean executeAreComparable(DynamicObject first, DynamicObject second); | ||
|
||
@Specialization | ||
protected boolean areComparable(DynamicObject first, DynamicObject second, | ||
@Cached("createBinaryProfile()") ConditionProfile sameEncodingProfile, | ||
@Cached("createBinaryProfile()") ConditionProfile firstStringEmptyProfile, | ||
@Cached("createBinaryProfile()") ConditionProfile secondStringEmptyProfile, | ||
@Cached("createBinaryProfile()") ConditionProfile firstStringCR7BitProfile, | ||
@Cached("createBinaryProfile()") ConditionProfile secondStringCR7BitProfile, | ||
@Cached("createBinaryProfile()") ConditionProfile firstStringAsciiCompatible, | ||
@Cached("createBinaryProfile()") ConditionProfile secondStringAsciiCompatible) { | ||
final Rope firstRope = Layouts.STRING.getRope(first); | ||
final Rope secondRope = Layouts.STRING.getRope(second); | ||
|
||
if (sameEncodingProfile.profile(firstRope.getEncoding() == secondRope.getEncoding())) { | ||
return true; | ||
} | ||
|
||
if (firstStringEmptyProfile.profile(firstRope.isEmpty())) { | ||
return true; | ||
} | ||
|
||
if (secondStringEmptyProfile.profile(secondRope.isEmpty())) { | ||
return true; | ||
} | ||
|
||
final CodeRange firstCodeRange = firstRope.getCodeRange(); | ||
final CodeRange secondCodeRange = secondRope.getCodeRange(); | ||
|
||
if (firstStringCR7BitProfile.profile(firstCodeRange == CodeRange.CR_7BIT)) { | ||
if (secondStringCR7BitProfile.profile(secondCodeRange == CodeRange.CR_7BIT)) { | ||
return true; | ||
} | ||
|
||
if (secondStringAsciiCompatible.profile(secondRope.getEncoding().isAsciiCompatible())) { | ||
return true; | ||
} | ||
} | ||
|
||
if (secondStringCR7BitProfile.profile(secondCodeRange == CodeRange.CR_7BIT)) { | ||
if (firstStringAsciiCompatible.profile(firstRope.getEncoding().isAsciiCompatible())) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
} | ||
|
||
@Primitive(name = "string_equal", needsSelf = true) | ||
@ImportStatic(StringGuards.class) | ||
public static abstract class StringEqualPrimitiveNode extends PrimitiveArrayArgumentsNode { | ||
|
||
@Child StringAreComparableNode areComparableNode; | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
eregon
Author
Member
|
||
|
||
public abstract boolean executeStringEqual(DynamicObject string, DynamicObject other); | ||
|
||
@Specialization(guards = "ropeReferenceEqual(string, other)") | ||
@Specialization(guards = { | ||
"isRubyString(other)", | ||
"ropeReferenceEqual(string, other)" | ||
}) | ||
public boolean stringEqualsRopeEquals(DynamicObject string, DynamicObject other) { | ||
return true; | ||
} | ||
|
@@ -2981,33 +3040,19 @@ public boolean stringEqualsBytesEquals(DynamicObject string, DynamicObject other | |
"isRubyString(other)", | ||
"!ropeReferenceEqual(string, other)", | ||
"!bytesReferenceEqual(string, other)", | ||
"!areComparable(string, other, sameEncodingProfile, firstStringEmptyProfile, secondStringEmptyProfile, firstStringCR7BitProfile, secondStringCR7BitProfile, firstStringAsciiCompatible, secondStringAsciiCompatible)" | ||
"!areComparable(string, other)" | ||
}) | ||
public boolean stringEqualNotComparable(DynamicObject string, DynamicObject other, | ||
@Cached("createBinaryProfile()") ConditionProfile sameEncodingProfile, | ||
@Cached("createBinaryProfile()") ConditionProfile firstStringEmptyProfile, | ||
@Cached("createBinaryProfile()") ConditionProfile secondStringEmptyProfile, | ||
@Cached("createBinaryProfile()") ConditionProfile firstStringCR7BitProfile, | ||
@Cached("createBinaryProfile()") ConditionProfile secondStringCR7BitProfile, | ||
@Cached("createBinaryProfile()") ConditionProfile firstStringAsciiCompatible, | ||
@Cached("createBinaryProfile()") ConditionProfile secondStringAsciiCompatible) { | ||
public boolean stringEqualNotComparable(DynamicObject string, DynamicObject other) { | ||
return false; | ||
} | ||
|
||
@Specialization(guards = { | ||
"isRubyString(other)", | ||
"!ropeReferenceEqual(string, other)", | ||
"!bytesReferenceEqual(string, other)", | ||
"areComparable(string, other, sameEncodingProfile, firstStringEmptyProfile, secondStringEmptyProfile, firstStringCR7BitProfile, secondStringCR7BitProfile, firstStringAsciiCompatible, secondStringAsciiCompatible)" | ||
"areComparable(string, other)" | ||
}) | ||
public boolean equal(DynamicObject string, DynamicObject other, | ||
@Cached("createBinaryProfile()") ConditionProfile sameEncodingProfile, | ||
@Cached("createBinaryProfile()") ConditionProfile firstStringEmptyProfile, | ||
@Cached("createBinaryProfile()") ConditionProfile secondStringEmptyProfile, | ||
@Cached("createBinaryProfile()") ConditionProfile firstStringCR7BitProfile, | ||
@Cached("createBinaryProfile()") ConditionProfile secondStringCR7BitProfile, | ||
@Cached("createBinaryProfile()") ConditionProfile firstStringAsciiCompatible, | ||
@Cached("createBinaryProfile()") ConditionProfile secondStringAsciiCompatible, | ||
@Cached("createBinaryProfile()") ConditionProfile differentSizeProfile) { | ||
|
||
final Rope a = Layouts.STRING.getRope(string); | ||
|
@@ -3020,65 +3065,20 @@ public boolean equal(DynamicObject string, DynamicObject other, | |
return a.equals(b); | ||
} | ||
|
||
protected boolean areComparable(DynamicObject first, DynamicObject second, | ||
ConditionProfile sameEncodingProfile, | ||
ConditionProfile firstStringEmptyProfile, | ||
ConditionProfile secondStringEmptyProfile, | ||
ConditionProfile firstStringCR7BitProfile, | ||
ConditionProfile secondStringCR7BitProfile, | ||
ConditionProfile firstStringAsciiCompatible, | ||
ConditionProfile secondStringAsciiCompatible) { | ||
assert RubyGuards.isRubyString(first); | ||
assert RubyGuards.isRubyString(second); | ||
|
||
final Rope firstRope = Layouts.STRING.getRope(first); | ||
final Rope secondRope = Layouts.STRING.getRope(second); | ||
|
||
if (sameEncodingProfile.profile(firstRope.getEncoding() == secondRope.getEncoding())) { | ||
return true; | ||
} | ||
|
||
if (firstStringEmptyProfile.profile(firstRope.isEmpty())) { | ||
return true; | ||
} | ||
|
||
if (secondStringEmptyProfile.profile(secondRope.isEmpty())) { | ||
return true; | ||
} | ||
|
||
final CodeRange firstCodeRange = firstRope.getCodeRange(); | ||
final CodeRange secondCodeRange = secondRope.getCodeRange(); | ||
|
||
if (firstStringCR7BitProfile.profile(firstCodeRange == CodeRange.CR_7BIT)) { | ||
if (secondStringCR7BitProfile.profile(secondCodeRange == CodeRange.CR_7BIT)) { | ||
return true; | ||
} | ||
|
||
if (secondStringAsciiCompatible.profile(secondRope.getEncoding().isAsciiCompatible())) { | ||
return true; | ||
} | ||
} | ||
|
||
if (secondStringCR7BitProfile.profile(secondCodeRange == CodeRange.CR_7BIT)) { | ||
if (firstStringAsciiCompatible.profile(firstRope.getEncoding().isAsciiCompatible())) { | ||
return true; | ||
} | ||
protected boolean areComparable(DynamicObject first, DynamicObject second) { | ||
if (areComparableNode == null) { | ||
CompilerDirectives.transferToInterpreterAndInvalidate(); | ||
areComparableNode = insert(StringAreComparableNodeGen.create(null, null)); | ||
} | ||
|
||
return false; | ||
return areComparableNode.executeAreComparable(first, second); | ||
} | ||
|
||
protected static boolean ropeReferenceEqual(DynamicObject first, DynamicObject second) { | ||
assert RubyGuards.isRubyString(first); | ||
assert RubyGuards.isRubyString(second); | ||
|
||
return rope(first) == rope(second); | ||
} | ||
|
||
protected static boolean bytesReferenceEqual(DynamicObject first, DynamicObject second) { | ||
assert RubyGuards.isRubyString(first); | ||
assert RubyGuards.isRubyString(second); | ||
|
||
final Rope firstRope = rope(first); | ||
final Rope secondRope = rope(second); | ||
|
||
|
Wouldn't this be better
@Cached
on each specialisation?