Skip to content

Commit 450eb38

Browse files
committed
TruffleStrings: add more diagnostic information to crashes in tests
1 parent 4cbcc29 commit 450eb38

File tree

2 files changed

+36
-14
lines changed

2 files changed

+36
-14
lines changed

truffle/src/com.oracle.truffle.api.strings.test/src/com/oracle/truffle/api/strings/test/TStringTestBase.java

+21-9
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,18 @@ public boolean contentEquals(byte[] array) {
202202
}
203203

204204
public interface TestStrings {
205+
206+
default void runWithErrorDecorator(AbstractTruffleString a, byte[] array, TruffleString.CodeRange codeRange, boolean isValid, TruffleString.Encoding encoding, int[] codepoints,
207+
int[] byteIndices) {
208+
try {
209+
run(a, array, codeRange, isValid, encoding, codepoints, byteIndices);
210+
} catch (Throwable t) {
211+
String msg = String.format("string: %s, array: %s, codeRange: %s, isValid: %b, encoding: %s, codepoints: %s, byteIndices: %s", a.toStringDebug(),
212+
Arrays.toString(array), codeRange, isValid, encoding, Arrays.toString(codepoints), Arrays.toString(byteIndices));
213+
throw new RuntimeException(msg, t);
214+
}
215+
}
216+
205217
void run(AbstractTruffleString a, byte[] array, TruffleString.CodeRange codeRange, boolean isValid, TruffleString.Encoding encoding, int[] codepoints, int[] byteIndices) throws Exception;
206218
}
207219

@@ -409,17 +421,17 @@ public static void forAllStrings(TruffleString.Encoding[] encodings, boolean con
409421
byte[] encodedValidPadded = pad(dat.encodedValid);
410422
TruffleString substring = TruffleString.fromByteArrayUncached(encodedValidPadded, 1, dat.encodedValid.length, encoding, false);
411423
TruffleString nativeSubstring = TruffleString.fromNativePointerUncached(PointerObject.create(encodedValidPadded), 1, dat.encodedValid.length, encoding, false);
412-
test.run(substring.concatUncached(nativeSubstring, encoding, true), concatBytes, codeRangeValid, true, encoding, concatCodepoints, concatByteIndices);
424+
test.runWithErrorDecorator(substring.concatUncached(nativeSubstring, encoding, true), concatBytes, codeRangeValid, true, encoding, concatCodepoints, concatByteIndices);
413425
if (isAsciiCompatible(encoding)) {
414426
byte[] array = encoding == UTF_32 ? lazyLongBytesUTF32 : encoding == UTF_16 ? lazyLongBytesUTF16 : lazyLongBytes;
415-
test.run(TruffleString.fromLongUncached(10, encoding, true), array, TruffleString.CodeRange.ASCII, true, encoding, lazyLongCodePoints, byteIndices01);
427+
test.runWithErrorDecorator(TruffleString.fromLongUncached(10, encoding, true), array, TruffleString.CodeRange.ASCII, true, encoding, lazyLongCodePoints, byteIndices01);
416428
}
417429
}
418430
}
419431
}
420432

421-
protected static void checkStringVariants(byte[] array, TruffleString.CodeRange codeRange, boolean isValid, TruffleString.Encoding encoding, int[] codepoints, int[] byteIndices, TestStrings test)
422-
throws Exception {
433+
protected static void checkStringVariants(byte[] array, TruffleString.CodeRange codeRange, boolean isValid, TruffleString.Encoding encoding, int[] codepoints, int[] byteIndices,
434+
TestStrings test) {
423435
byte[] arrayPadded = pad(array);
424436
for (AbstractTruffleString string : new AbstractTruffleString[]{
425437
TruffleString.fromByteArrayUncached(array, 0, array.length, encoding, false),
@@ -434,9 +446,9 @@ protected static void checkStringVariants(byte[] array, TruffleString.CodeRange
434446
MutableTruffleString.fromNativePointerUncached(PointerObject.create(arrayPadded), 1, array.length, encoding, false),
435447
MutableTruffleString.fromNativePointerUncached(PointerObject.create(arrayPadded), 1, array.length, encoding, true),
436448
}) {
437-
test.run(string, array, codeRange, isValid, encoding, codepoints, byteIndices);
449+
test.runWithErrorDecorator(string, array, codeRange, isValid, encoding, codepoints, byteIndices);
438450
if ((encoding == UTF_16 || encoding == UTF_32) && string.isImmutable() && string.isManaged()) {
439-
test.run(((TruffleString) string).asNativeUncached(PointerObject::create, encoding, true, false), array, codeRange, isValid, encoding, codepoints, byteIndices);
451+
test.runWithErrorDecorator(((TruffleString) string).asNativeUncached(PointerObject::create, encoding, true, false), array, codeRange, isValid, encoding, codepoints, byteIndices);
440452
}
441453
}
442454
if (encoding == UTF_16LE) {
@@ -450,7 +462,7 @@ protected static void checkStringVariants(byte[] array, TruffleString.CodeRange
450462
Assert.assertSame(codeRangeImprecise, codeRange);
451463
}
452464
}
453-
test.run(fromJavaString, array, codeRange, isValid, encoding, codepoints, byteIndices);
465+
test.runWithErrorDecorator(fromJavaString, array, codeRange, isValid, encoding, codepoints, byteIndices);
454466
}
455467
if (codeRange == TruffleString.CodeRange.ASCII && isAsciiCompatible(encoding)) {
456468
byte[] bytesUTF16 = new byte[(codepoints.length + 1) * 2];
@@ -460,7 +472,7 @@ protected static void checkStringVariants(byte[] array, TruffleString.CodeRange
460472
TStringTestUtil.writeValue(bytesUTF16, 1, codepoints.length, 0xffff);
461473
TruffleString string = TruffleString.fromByteArrayUncached(bytesUTF16, 0, bytesUTF16.length, UTF_16, false).substringByteIndexUncached(0, bytesUTF16.length - 2, UTF_16,
462474
true).switchEncodingUncached(encoding);
463-
test.run(string, array, codeRange, isValid, encoding, codepoints, byteIndices);
475+
test.runWithErrorDecorator(string, array, codeRange, isValid, encoding, codepoints, byteIndices);
464476
}
465477
if (codeRange == TruffleString.CodeRange.ASCII && isAsciiCompatible(encoding) || codeRange == TruffleString.CodeRange.LATIN_1 && isUTF16(encoding)) {
466478
byte[] bytesUTF32 = new byte[(codepoints.length + 1) * 4];
@@ -470,7 +482,7 @@ protected static void checkStringVariants(byte[] array, TruffleString.CodeRange
470482
TStringTestUtil.writeValue(bytesUTF32, 2, codepoints.length, 0x10ffff);
471483
TruffleString string = TruffleString.fromByteArrayUncached(bytesUTF32, 0, bytesUTF32.length, UTF_32, false).substringByteIndexUncached(0, bytesUTF32.length - 4, UTF_32,
472484
true).switchEncodingUncached(encoding);
473-
test.run(string, array, codeRange, isValid, encoding, codepoints, byteIndices);
485+
test.runWithErrorDecorator(string, array, codeRange, isValid, encoding, codepoints, byteIndices);
474486
}
475487
}
476488

truffle/src/com.oracle.truffle.api.strings/src/com/oracle/truffle/api/strings/AbstractTruffleString.java

+15-5
Original file line numberDiff line numberDiff line change
@@ -1364,19 +1364,29 @@ public final String toString() {
13641364
@SuppressWarnings("unused")
13651365
@TruffleBoundary
13661366
public final String toStringDebug() {
1367-
return String.format("TString(%s, %s, off: %d, len: %d, str: %d, cpLen: %d, \"%s\")",
1368-
TruffleString.Encoding.get(encoding()), TSCodeRange.toString(codeRange()), offset(), length(), stride(), codePointLength(), toJavaStringUncached());
1367+
Object curData = data;
1368+
String dataString;
1369+
if (curData instanceof byte[] || curData instanceof NativePointer || curData instanceof String) {
1370+
dataString = String.format("\"%s\"", toJavaStringUncached());
1371+
} else if (curData instanceof LazyLong lazyLong) {
1372+
dataString = String.format("LazyLong(%d)", lazyLong.value);
1373+
} else {
1374+
LazyConcat lazyConcat = (LazyConcat) curData;
1375+
dataString = String.format("Concat(%s, %s)", lazyConcat.left.toStringDebug(), lazyConcat.right.toStringDebug());
1376+
}
1377+
return String.format("TString(%s, %s, off: %d, len: %d, str: %d, cpLen: %d, data: %s)",
1378+
TruffleString.Encoding.get(encoding()), TSCodeRange.toString(codeRange()), offset(), length(), stride(), codePointLength(), dataString);
13691379
}
13701380

13711381
@TruffleBoundary
13721382
byte[] materializeLazy(Node node, Object thisData) {
1373-
if (thisData instanceof AbstractTruffleString.LazyConcat) {
1383+
if (thisData instanceof LazyConcat) {
13741384
// note: the write to data is racy, and we deliberately read it from the TString
13751385
// object again after the race to de-duplicate simultaneously generated arrays
1376-
setData(AbstractTruffleString.LazyConcat.flatten(node, (TruffleString) this));
1386+
setData(LazyConcat.flatten(node, (TruffleString) this));
13771387
return (byte[]) data;
13781388
} else {
1379-
AbstractTruffleString.LazyLong lazyLong = (AbstractTruffleString.LazyLong) thisData;
1389+
LazyLong lazyLong = (LazyLong) thisData;
13801390
// same pattern as in #doLazyConcat: racy write to data.bytes and read the result
13811391
// again to de-duplicate
13821392
if (lazyLong.bytes == null) {

0 commit comments

Comments
 (0)