Skip to content

Commit

Permalink
[Truffle] Avoid splicing together empty strings.
Browse files Browse the repository at this point in the history
A semi-common case is using String#slice! to truncate a string. In this case we'd like to model the operation as a simple substring. However, splicing assumed a string would be inserted in the middle of another and thus generated superfluous ropes for the truncation case.
nirvdrum committed Apr 21, 2016
1 parent 2de4aa9 commit 84a785c
Showing 1 changed file with 17 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1448,7 +1448,9 @@ public Object spliceAppend(DynamicObject string, DynamicObject other, int splice
}

@Specialization(guards = { "!indexAtEitherBounds(string, spliceByteIndex)", "isRubyString(other)", "isRubyEncoding(rubyEncoding)", "!isRopeBuffer(string)" })
public DynamicObject splice(DynamicObject string, DynamicObject other, int spliceByteIndex, int byteCountToReplace, DynamicObject rubyEncoding) {
public DynamicObject splice(DynamicObject string, DynamicObject other, int spliceByteIndex, int byteCountToReplace, DynamicObject rubyEncoding,
@Cached("createBinaryProfile()") ConditionProfile insertStringIsEmptyProfile,
@Cached("createBinaryProfile()") ConditionProfile splitRightIsEmptyProfile) {
if (leftMakeSubstringNode == null) {
CompilerDirectives.transferToInterpreter();
leftMakeSubstringNode = insert(RopeNodesFactory.MakeSubstringNodeGen.create(null, null, null));
@@ -1476,8 +1478,20 @@ public DynamicObject splice(DynamicObject string, DynamicObject other, int splic

final Rope splitLeft = leftMakeSubstringNode.executeMake(source, 0, spliceByteIndex);
final Rope splitRight = rightMakeSubstringNode.executeMake(source, rightSideStartingIndex, source.byteLength() - rightSideStartingIndex);
final Rope joinedLeft = leftMakeConcatNode.executeMake(splitLeft, insert, encoding);
final Rope joinedRight = rightMakeConcatNode.executeMake(joinedLeft, splitRight, encoding);

final Rope joinedLeft;
if (insertStringIsEmptyProfile.profile(insert.isEmpty())) {
joinedLeft = splitLeft;
} else {
joinedLeft = leftMakeConcatNode.executeMake(splitLeft, insert, encoding);
}

final Rope joinedRight;
if (splitRightIsEmptyProfile.profile(splitRight.isEmpty())) {
joinedRight = joinedLeft;
} else {
joinedRight = rightMakeConcatNode.executeMake(joinedLeft, splitRight, encoding);
}

StringOperations.setRope(string, joinedRight);

0 comments on commit 84a785c

Please sign in to comment.