Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 7b166bc88a1b
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: a9567d0ccc99
Choose a head ref
  • 2 commits
  • 3 files changed
  • 1 contributor

Commits on Jan 30, 2016

  1. Copy the full SHA
    4b95c69 View commit details
  2. [Truffle] There's no need to force_encoding in Array#pack.

    While this may have had value with ByteLists, it seems to just duplicate work for Ropes. Moreover, StringSupport.force_encoding is a slow-path helper, so we should avoid it on fast paths if possible.
    nirvdrum committed Jan 30, 2016
    Copy the full SHA
    a9567d0 View commit details
96 changes: 91 additions & 5 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/RopeNodes.java
Original file line number Diff line number Diff line change
@@ -6,6 +6,10 @@
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*
*
* Some of the code in this class is modified from org.jruby.util.StringSupport,
* licensed under the same EPL1.0/GPL 2.0/LGPL 2.1 used throughout.
*/

package org.jruby.truffle.nodes.core;
@@ -318,9 +322,34 @@ public LeafRope makeAsciiOnlyLeafRope(byte[] bytes, Encoding encoding, int codeR
return new AsciiOnlyLeafRope(bytes, encoding);
}

@Specialization(guards = "isValid(codeRange)")
@Specialization(guards = { "isValid(codeRange)", "isFixedWidth(encoding)" })
public LeafRope makeValidLeafRopeFixedWidthEncoding(byte[] bytes, Encoding encoding, int codeRange) {
final int characterLength = bytes.length / encoding.minLength();

return new ValidLeafRope(bytes, encoding, characterLength);
}

@Specialization(guards = { "isValid(codeRange)", "!isFixedWidth(encoding)" })
public LeafRope makeValidLeafRope(byte[] bytes, Encoding encoding, int codeRange) {
final int characterLength = RopeOperations.strLength(encoding, bytes, 0, bytes.length);
// Exctracted from StringSupport.strLength.

int characterLength = 0;
int p = 0;
int e = bytes.length;

while (p < e) {
if (Encoding.isAscii(bytes[p])) {
int q = StringSupport.searchNonAscii(bytes, p, e);
if (q == -1) {
characterLength += (e - p);
break;
}
characterLength += q - p;
p = q;
}
p += StringSupport.encFastMBCLen(bytes, p, e, encoding);
characterLength++;
}

return new ValidLeafRope(bytes, encoding, characterLength);
}
@@ -330,7 +359,32 @@ public LeafRope makeInvalidLeafRope(byte[] bytes, Encoding encoding, int codeRan
return new InvalidLeafRope(bytes, encoding);
}

@Specialization(guards = { "isUnknown(codeRange)", "isBinaryString(encoding)" })
@Specialization(guards = { "isUnknown(codeRange)", "isEmpty(bytes)" })
public LeafRope makeUnknownLeafRopeEmpty(byte[] bytes, Encoding encoding, int codeRange,
@Cached("createBinaryProfile()") ConditionProfile isUTF8,
@Cached("createBinaryProfile()") ConditionProfile isUSAscii,
@Cached("createBinaryProfile()") ConditionProfile isAscii8Bit,
@Cached("createBinaryProfile()") ConditionProfile isAsciiCompatible) {
if (isUTF8.profile(encoding == UTF8Encoding.INSTANCE)) {
return RopeOperations.EMPTY_UTF8_ROPE;
}

if (isUSAscii.profile(encoding == USASCIIEncoding.INSTANCE)) {
return RopeOperations.EMPTY_US_ASCII_ROPE;
}

if (isAscii8Bit.profile(encoding == ASCIIEncoding.INSTANCE)) {
return RopeOperations.EMPTY_ASCII_8BIT_ROPE;
}

if (isAsciiCompatible.profile(encoding.isAsciiCompatible())) {
return new AsciiOnlyLeafRope(bytes, encoding);
}

return new ValidLeafRope(bytes, encoding, 0);
}

@Specialization(guards = { "isUnknown(codeRange)", "!isEmpty(bytes)", "isBinaryString(encoding)" })
public LeafRope makeUnknownLeafRopeBinary(byte[] bytes, Encoding encoding, int codeRange,
@Cached("createBinaryProfile()") ConditionProfile discovered7BitProfile) {
int newCodeRange = StringSupport.CR_7BIT;
@@ -348,11 +402,30 @@ public LeafRope makeUnknownLeafRopeBinary(byte[] bytes, Encoding encoding, int c
return new ValidLeafRope(bytes, encoding, bytes.length);
}

@Specialization(guards = { "isUnknown(codeRange)", "!isBinaryString(encoding)" })
@Specialization(guards = { "isUnknown(codeRange)", "!isEmpty(bytes)", "!isBinaryString(encoding)", "isAsciiCompatible(encoding)" })
public LeafRope makeUnknownLeafRopeAsciiCompatible(byte[] bytes, Encoding encoding, int codeRange,
@Cached("createBinaryProfile()") ConditionProfile discovered7BitProfile,
@Cached("createBinaryProfile()") ConditionProfile discoveredValidProfile) {
final long packedLengthAndCodeRange = StringSupport.strLengthWithCodeRangeAsciiCompatible(encoding, bytes, 0, bytes.length);
final int newCodeRange = StringSupport.unpackArg(packedLengthAndCodeRange);
final int characterLength = StringSupport.unpackResult(packedLengthAndCodeRange);

if (discovered7BitProfile.profile(newCodeRange == StringSupport.CR_7BIT)) {
return new AsciiOnlyLeafRope(bytes, encoding);
}

if (discoveredValidProfile.profile(newCodeRange == StringSupport.CR_VALID)) {
return new ValidLeafRope(bytes, encoding, characterLength);
}

return new InvalidLeafRope(bytes, encoding);
}

@Specialization(guards = { "isUnknown(codeRange)", "!isEmpty(bytes)", "!isBinaryString(encoding)", "!isAsciiCompatible(encoding)" })
public LeafRope makeUnknownLeafRope(byte[] bytes, Encoding encoding, int codeRange,
@Cached("createBinaryProfile()") ConditionProfile discovered7BitProfile,
@Cached("createBinaryProfile()") ConditionProfile discoveredValidProfile) {
final long packedLengthAndCodeRange = RopeOperations.calculateCodeRangeAndLength(encoding, bytes, 0, bytes.length);
final long packedLengthAndCodeRange = StringSupport.strLengthWithCodeRangeNonAsciiCompatible(encoding, bytes, 0, bytes.length);
final int newCodeRange = StringSupport.unpackArg(packedLengthAndCodeRange);
final int characterLength = StringSupport.unpackResult(packedLengthAndCodeRange);

@@ -386,6 +459,19 @@ protected static boolean isUnknown(int codeRange) {
protected static boolean isBinaryString(Encoding encoding) {
return encoding == ASCIIEncoding.INSTANCE;
}

protected static boolean isEmpty(byte[] bytes) {
return bytes.length == 0;
}

protected static boolean isAsciiCompatible(Encoding encoding) {
return encoding.isAsciiCompatible();
}

protected static boolean isFixedWidth(Encoding encoding) {
return encoding.isFixedWidth();
}

}

@NodeChildren({
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@
import com.oracle.truffle.api.utilities.BranchProfile;
import com.oracle.truffle.api.utilities.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.Encoding;
import org.jcodings.specific.ASCIIEncoding;
import org.jcodings.specific.USASCIIEncoding;
import org.jcodings.specific.UTF8Encoding;
@@ -2469,27 +2470,29 @@ private DynamicObject finishPack(int formatLength, PackResult result) {
bytes = Arrays.copyOf(bytes, result.getOutputLength());
}

final Rope rope = makeLeafRopeNode.executeMake(bytes, ASCIIEncoding.INSTANCE, StringSupport.CR_UNKNOWN);
final DynamicObject string = createString(rope);

final Encoding encoding;
if (formatLength == 0) {
StringOperations.forceEncoding(string, USASCIIEncoding.INSTANCE);
encoding = USASCIIEncoding.INSTANCE;
} else {
switch (result.getEncoding()) {
case DEFAULT:
case ASCII_8BIT:
encoding = ASCIIEncoding.INSTANCE;
break;
case US_ASCII:
StringOperations.forceEncoding(string, USASCIIEncoding.INSTANCE);
encoding = USASCIIEncoding.INSTANCE;
break;
case UTF_8:
StringOperations.forceEncoding(string, UTF8Encoding.INSTANCE);
encoding = UTF8Encoding.INSTANCE;
break;
default:
throw new UnsupportedOperationException();
}
}

final Rope rope = makeLeafRopeNode.executeMake(bytes, encoding, StringSupport.CR_UNKNOWN);
final DynamicObject string = createString(rope);

if (result.isTainted()) {
if (taintNode == null) {
CompilerDirectives.transferToInterpreter();
Original file line number Diff line number Diff line change
@@ -31,9 +31,9 @@

public class RopeOperations {

public static final Rope EMPTY_ASCII_8BIT_ROPE = create(new byte[] {}, ASCIIEncoding.INSTANCE, StringSupport.CR_7BIT);
public static final Rope EMPTY_US_ASCII_ROPE = create(new byte [] {}, USASCIIEncoding.INSTANCE, StringSupport.CR_7BIT);
public static final Rope EMPTY_UTF8_ROPE = create(new byte[] {}, UTF8Encoding.INSTANCE, StringSupport.CR_7BIT);
public static final LeafRope EMPTY_ASCII_8BIT_ROPE = create(new byte[] {}, ASCIIEncoding.INSTANCE, StringSupport.CR_7BIT);
public static final LeafRope EMPTY_US_ASCII_ROPE = create(new byte [] {}, USASCIIEncoding.INSTANCE, StringSupport.CR_7BIT);
public static final LeafRope EMPTY_UTF8_ROPE = create(new byte[] {}, UTF8Encoding.INSTANCE, StringSupport.CR_7BIT);

public static LeafRope create(byte[] bytes, Encoding encoding, int codeRange) {
int characterLength = -1;