Skip to content

Commit 8dada73

Browse files
committed
8345120: A likely bug in StringSupport::chunkedStrlenShort
Reviewed-by: mcimadamore
1 parent 659f70b commit 8dada73

File tree

5 files changed

+271
-205
lines changed

5 files changed

+271
-205
lines changed

src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java

+4
Original file line numberDiff line numberDiff line change
@@ -889,23 +889,27 @@ public void setAtIndex(AddressLayout layout, long index, MemorySegment value) {
889889
layout.varHandle().set((MemorySegment)this, index * layout.byteSize(), value);
890890
}
891891

892+
@ForceInline
892893
@Override
893894
public String getString(long offset) {
894895
return getString(offset, sun.nio.cs.UTF_8.INSTANCE);
895896
}
896897

898+
@ForceInline
897899
@Override
898900
public String getString(long offset, Charset charset) {
899901
Objects.requireNonNull(charset);
900902
return StringSupport.read(this, offset, charset);
901903
}
902904

905+
@ForceInline
903906
@Override
904907
public void setString(long offset, String str) {
905908
Objects.requireNonNull(str);
906909
setString(offset, str, sun.nio.cs.UTF_8.INSTANCE);
907910
}
908911

912+
@ForceInline
909913
@Override
910914
public void setString(long offset, String str, Charset charset) {
911915
Objects.requireNonNull(charset);

src/java.base/share/classes/jdk/internal/foreign/SegmentBulkOperations.java

+31-31
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import jdk.internal.misc.ScopedMemoryAccess;
2929
import jdk.internal.util.Architecture;
3030
import jdk.internal.util.ArraysSupport;
31-
import jdk.internal.util.ByteArrayLittleEndian;
3231
import jdk.internal.vm.annotation.ForceInline;
3332
import jdk.internal.vm.annotation.Stable;
3433

@@ -50,6 +49,7 @@ public final class SegmentBulkOperations {
5049
private SegmentBulkOperations() {}
5150

5251
private static final ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess();
52+
private static final long LONG_MASK = ~7L; // The last three bits are zero
5353

5454
// All the threshold values below MUST be a power of two and should preferably be
5555
// greater or equal to 2^3.
@@ -75,21 +75,21 @@ public static MemorySegment fill(AbstractMemorySegmentImpl dst, byte value) {
7575
int offset = 0;
7676
// 0...0X...X000
7777
final int limit = (int) (dst.length & (NATIVE_THRESHOLD_FILL - 8));
78-
for (; offset < limit; offset += 8) {
78+
for (; offset < limit; offset += Long.BYTES) {
7979
SCOPED_MEMORY_ACCESS.putLongUnaligned(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + offset, longValue, !Architecture.isLittleEndian());
8080
}
8181
int remaining = (int) dst.length - limit;
8282
// 0...0X00
83-
if (remaining >= 4) {
83+
if (remaining >= Integer.BYTES) {
8484
SCOPED_MEMORY_ACCESS.putIntUnaligned(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + offset, (int) longValue, !Architecture.isLittleEndian());
85-
offset += 4;
86-
remaining -= 4;
85+
offset += Integer.BYTES;
86+
remaining -= Integer.BYTES;
8787
}
8888
// 0...00X0
89-
if (remaining >= 2) {
89+
if (remaining >= Short.BYTES) {
9090
SCOPED_MEMORY_ACCESS.putShortUnaligned(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + offset, (short) longValue, !Architecture.isLittleEndian());
91-
offset += 2;
92-
remaining -= 2;
91+
offset += Short.BYTES;
92+
remaining -= Short.BYTES;
9393
}
9494
// 0...000X
9595
if (remaining == 1) {
@@ -123,26 +123,26 @@ public static void copy(AbstractMemorySegmentImpl src, long srcOffset,
123123
// is an overlap, we could tolerate one particular direction of overlap (but not the other).
124124

125125
// 0...0X...X000
126-
final int limit = (int) (size & (NATIVE_THRESHOLD_COPY - 8));
126+
final int limit = (int) (size & (NATIVE_THRESHOLD_COPY - Long.BYTES));
127127
int offset = 0;
128-
for (; offset < limit; offset += 8) {
128+
for (; offset < limit; offset += Long.BYTES) {
129129
final long v = SCOPED_MEMORY_ACCESS.getLongUnaligned(src.sessionImpl(), src.unsafeGetBase(), src.unsafeGetOffset() + srcOffset + offset, !Architecture.isLittleEndian());
130130
SCOPED_MEMORY_ACCESS.putLongUnaligned(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + dstOffset + offset, v, !Architecture.isLittleEndian());
131131
}
132132
int remaining = (int) size - offset;
133133
// 0...0X00
134-
if (remaining >= 4) {
134+
if (remaining >= Integer.BYTES) {
135135
final int v = SCOPED_MEMORY_ACCESS.getIntUnaligned(src.sessionImpl(), src.unsafeGetBase(),src.unsafeGetOffset() + srcOffset + offset, !Architecture.isLittleEndian());
136136
SCOPED_MEMORY_ACCESS.putIntUnaligned(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + dstOffset + offset, v, !Architecture.isLittleEndian());
137-
offset += 4;
138-
remaining -= 4;
137+
offset += Integer.BYTES;
138+
remaining -= Integer.BYTES;
139139
}
140140
// 0...00X0
141-
if (remaining >= 2) {
141+
if (remaining >= Short.BYTES) {
142142
final short v = SCOPED_MEMORY_ACCESS.getShortUnaligned(src.sessionImpl(), src.unsafeGetBase(), src.unsafeGetOffset() + srcOffset + offset, !Architecture.isLittleEndian());
143143
SCOPED_MEMORY_ACCESS.putShortUnaligned(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + dstOffset + offset, v, !Architecture.isLittleEndian());
144-
offset += 2;
145-
remaining -=2;
144+
offset += Short.BYTES;
145+
remaining -= Short.BYTES;
146146
}
147147
// 0...000X
148148
if (remaining == 1) {
@@ -202,9 +202,9 @@ public static int contentHash(AbstractMemorySegmentImpl segment, long fromOffset
202202
return 1;
203203
}
204204
int result = 1;
205-
final long longBytes = length & ((1L << 62) - 8);
205+
final long longBytes = length & LONG_MASK;
206206
final long limit = fromOffset + longBytes;
207-
for (; fromOffset < limit; fromOffset += 8) {
207+
for (; fromOffset < limit; fromOffset += Long.BYTES) {
208208
long val = SCOPED_MEMORY_ACCESS.getLongUnaligned(segment.sessionImpl(), segment.unsafeGetBase(), segment.unsafeGetOffset() + fromOffset, !Architecture.isLittleEndian());
209209
result = result * POWERS_OF_31[7]
210210
+ ((byte) (val >>> 56)) * POWERS_OF_31[6]
@@ -218,24 +218,24 @@ public static int contentHash(AbstractMemorySegmentImpl segment, long fromOffset
218218
}
219219
int remaining = (int) (length - longBytes);
220220
// 0...0X00
221-
if (remaining >= 4) {
221+
if (remaining >= Integer.BYTES) {
222222
int val = SCOPED_MEMORY_ACCESS.getIntUnaligned(segment.sessionImpl(), segment.unsafeGetBase(), segment.unsafeGetOffset() + fromOffset, !Architecture.isLittleEndian());
223223
result = result * POWERS_OF_31[3]
224224
+ ((byte) (val >>> 24)) * POWERS_OF_31[2]
225225
+ ((byte) (val >>> 16)) * POWERS_OF_31[1]
226226
+ ((byte) (val >>> 8)) * POWERS_OF_31[0]
227227
+ ((byte) val);
228-
fromOffset += 4;
229-
remaining -= 4;
228+
fromOffset += Integer.BYTES;
229+
remaining -= Integer.BYTES;
230230
}
231231
// 0...00X0
232-
if (remaining >= 2) {
232+
if (remaining >= Short.BYTES) {
233233
short val = SCOPED_MEMORY_ACCESS.getShortUnaligned(segment.sessionImpl(), segment.unsafeGetBase(), segment.unsafeGetOffset() + fromOffset, !Architecture.isLittleEndian());
234234
result = result * POWERS_OF_31[1]
235235
+ ((byte) (val >>> 8)) * POWERS_OF_31[0]
236236
+ ((byte) val);
237-
fromOffset += 2;
238-
remaining -= 2;
237+
fromOffset += Short.BYTES;
238+
remaining -= Short.BYTES;
239239
}
240240
// 0...000X
241241
if (remaining == 1) {
@@ -288,7 +288,7 @@ private static long mismatch(AbstractMemorySegmentImpl src, long srcFromOffset,
288288
long start, int length, boolean srcAndDstBytesDiffer) {
289289
int offset = 0;
290290
final int limit = length & (NATIVE_THRESHOLD_MISMATCH - 8);
291-
for (; offset < limit; offset += 8) {
291+
for (; offset < limit; offset += Long.BYTES) {
292292
final long s = SCOPED_MEMORY_ACCESS.getLongUnaligned(src.sessionImpl(), src.unsafeGetBase(), src.unsafeGetOffset() + srcFromOffset + offset, false);
293293
final long d = SCOPED_MEMORY_ACCESS.getLongUnaligned(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + dstFromOffset + offset, false);
294294
if (s != d) {
@@ -298,24 +298,24 @@ private static long mismatch(AbstractMemorySegmentImpl src, long srcFromOffset,
298298
int remaining = length - offset;
299299

300300
// 0...0X00
301-
if (remaining >= 4) {
301+
if (remaining >= Integer.BYTES) {
302302
final int s = SCOPED_MEMORY_ACCESS.getIntUnaligned(src.sessionImpl(), src.unsafeGetBase(), src.unsafeGetOffset() + srcFromOffset + offset, false);
303303
final int d = SCOPED_MEMORY_ACCESS.getIntUnaligned(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + dstFromOffset + offset, false);
304304
if (s != d) {
305305
return start + offset + mismatch(s, d);
306306
}
307-
offset += 4;
308-
remaining -= 4;
307+
offset += Integer.BYTES;
308+
remaining -= Integer.BYTES;
309309
}
310310
// 0...00X0
311-
if (remaining >= 2) {
311+
if (remaining >= Short.BYTES) {
312312
final short s = SCOPED_MEMORY_ACCESS.getShortUnaligned(src.sessionImpl(), src.unsafeGetBase(), src.unsafeGetOffset() + srcFromOffset + offset, false);
313313
final short d = SCOPED_MEMORY_ACCESS.getShortUnaligned(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + dstFromOffset + offset, false);
314314
if (s != d) {
315315
return start + offset + mismatch(s, d);
316316
}
317-
offset += 2;
318-
remaining -= 2;
317+
offset += Short.BYTES;
318+
remaining -= Short.BYTES;
319319
}
320320
// 0...000X
321321
if (remaining == 1) {

0 commit comments

Comments
 (0)