Skip to content

Commit 73fd090

Browse files
committed
[GR-65392] TruffleString from long value optimizations.
PullRequest: graal/20939
2 parents 5a88a79 + b256871 commit 73fd090

File tree

8 files changed

+399
-180
lines changed

8 files changed

+399
-180
lines changed

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

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -86,8 +86,30 @@ public void testFromCodePoint() throws Exception {
8686
@Test
8787
public void testFromLong() throws Exception {
8888
forAllEncodings((TruffleString.Encoding encoding) -> {
89-
for (long l : new long[]{Long.MIN_VALUE, Long.MIN_VALUE + 1, ((long) Integer.MIN_VALUE) - 1, Integer.MIN_VALUE, Integer.MIN_VALUE + 1, Short.MIN_VALUE, -12345, -1, 0,
90-
1, 12345, Short.MAX_VALUE, Integer.MAX_VALUE - 1, Integer.MAX_VALUE, ((long) Integer.MAX_VALUE) + 1, Long.MAX_VALUE - 1, Long.MAX_VALUE}) {
89+
var testValues = new long[]{
90+
Long.MIN_VALUE,
91+
Long.MIN_VALUE + 1L,
92+
Integer.MIN_VALUE - 1L,
93+
Integer.MIN_VALUE,
94+
Integer.MIN_VALUE + 1L,
95+
Short.MIN_VALUE,
96+
-12345,
97+
-100,
98+
-10,
99+
-1,
100+
0,
101+
1,
102+
10,
103+
100,
104+
12345,
105+
3101342585L, // hashCode() == 0
106+
Short.MAX_VALUE,
107+
Integer.MAX_VALUE - 1L,
108+
Integer.MAX_VALUE,
109+
Integer.MAX_VALUE + 1L,
110+
Long.MAX_VALUE - 1L,
111+
Long.MAX_VALUE};
112+
for (long l : testValues) {
91113
if (isAsciiCompatible(encoding)) {
92114
TruffleString eager = fromLongUncached(l, encoding, false);
93115
Assert.assertEquals(l, eager.parseLongUncached());
@@ -98,6 +120,17 @@ public void testFromLong() throws Exception {
98120
Assert.assertEquals(l, eager.parseIntUncached());
99121
Assert.assertEquals(l, lazy.parseIntUncached());
100122
}
123+
124+
String javaString = Long.toString(l);
125+
Assert.assertEquals(maskZero(javaString.hashCode()), eager.hashCodeUncached(encoding));
126+
Assert.assertEquals(maskZero(javaString.hashCode()), lazy.hashCodeUncached(encoding));
127+
TruffleString expectedString = TruffleString.fromJavaStringUncached(javaString, encoding);
128+
Assert.assertEquals(maskZero(javaString.hashCode()), expectedString.hashCodeUncached(encoding));
129+
Assert.assertEquals(javaString.hashCode(), expectedString.toJavaStringUncached().hashCode());
130+
Assert.assertEquals(eager, expectedString);
131+
Assert.assertEquals(lazy, expectedString);
132+
Assert.assertEquals(javaString.length(), eager.byteLength(TruffleString.Encoding.US_ASCII));
133+
Assert.assertEquals(javaString.length(), lazy.byteLength(TruffleString.Encoding.US_ASCII));
101134
} else {
102135
expectUnsupportedOperationException(() -> fromLongUncached(l, encoding, false));
103136
expectUnsupportedOperationException(() -> fromLongUncached(l, encoding, true));
@@ -106,6 +139,13 @@ public void testFromLong() throws Exception {
106139
});
107140
}
108141

142+
static int maskZero(int hash) {
143+
if (hash == 0) {
144+
return -1;
145+
}
146+
return hash;
147+
}
148+
109149
@Test
110150
public void testFromByteArray() throws Exception {
111151
byte[] empty = {};

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

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -63,8 +63,6 @@
6363
import com.oracle.truffle.api.CompilerDirectives;
6464
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
6565
import com.oracle.truffle.api.nodes.Node;
66-
import com.oracle.truffle.api.profiles.InlinedBranchProfile;
67-
import com.oracle.truffle.api.profiles.InlinedConditionProfile;
6866
import com.oracle.truffle.api.strings.TruffleString.Encoding;
6967

7068
/**
@@ -131,7 +129,9 @@ public abstract sealed class AbstractTruffleString permits TruffleString, Mutabl
131129
*/
132130
int hashCode;
133131

134-
AbstractTruffleString(Object data, int offset, int length, int stride, Encoding encoding, int flags, int codePointLength, int codeRange) {
132+
static final int MASKED_ZERO_HASH_CODE = -1;
133+
134+
AbstractTruffleString(Object data, int offset, int length, int stride, Encoding encoding, int flags, int codePointLength, int codeRange, int hashCode) {
135135
validateData(data, offset, length, stride);
136136
assert isByte(stride);
137137
assert isByte(flags);
@@ -145,6 +145,7 @@ public abstract sealed class AbstractTruffleString permits TruffleString, Mutabl
145145
this.flags = (byte) flags;
146146
this.codeRange = (byte) codeRange;
147147
this.codePointLength = codePointLength;
148+
this.hashCode = hashCode;
148149
}
149150

150151
static boolean isByte(int i) {
@@ -1289,10 +1290,9 @@ public final boolean equals(Object obj) {
12891290
if (this == obj) {
12901291
return true;
12911292
}
1292-
if (!(obj instanceof AbstractTruffleString)) {
1293+
if (!(obj instanceof AbstractTruffleString b)) {
12931294
return false;
12941295
}
1295-
AbstractTruffleString b = (AbstractTruffleString) obj;
12961296
int enc = encoding();
12971297
if (enc != b.encoding()) {
12981298
if (!b.isLooselyCompatibleTo(enc, TruffleString.Encoding.getMaxCompatibleCodeRange(enc), b.codeRange())) {
@@ -1302,14 +1302,7 @@ public final boolean equals(Object obj) {
13021302
return false;
13031303
}
13041304
}
1305-
return TruffleString.EqualNode.checkContentEquals(TruffleString.EqualNode.getUncached(), this, b,
1306-
InlinedConditionProfile.getUncached(),
1307-
InlinedConditionProfile.getUncached(),
1308-
InlinedConditionProfile.getUncached(),
1309-
InlinedConditionProfile.getUncached(),
1310-
InlinedConditionProfile.getUncached(),
1311-
InlinedBranchProfile.getUncached(),
1312-
InlinedConditionProfile.getUncached());
1305+
return TruffleString.EqualNode.checkContentEqualsUncached(this, b);
13131306
}
13141307

13151308
/**

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -71,7 +71,7 @@
7171
public final class MutableTruffleString extends AbstractTruffleString {
7272

7373
private MutableTruffleString(Object data, int offset, int length, int stride, int codePointLength, Encoding encoding) {
74-
super(data, offset, length, stride, encoding, 0, codePointLength, TSCodeRange.getUnknownCodeRangeForEncoding(encoding.id));
74+
super(data, offset, length, stride, encoding, 0, codePointLength, TSCodeRange.getUnknownCodeRangeForEncoding(encoding.id), 0);
7575
assert data instanceof byte[] || data instanceof NativePointer;
7676
}
7777

0 commit comments

Comments
 (0)