8321467: MemorySegment.setString(long, String, Charset) throws IAE(Misaligned access)

Reviewed-by: pminborg
This commit is contained in:
Maurizio Cimadamore 2023-12-07 12:51:42 +00:00
parent c087e9174e
commit 42bb852696
2 changed files with 50 additions and 13 deletions

View File

@ -82,7 +82,7 @@ public final class StringSupport {
private static void writeShort(MemorySegment segment, long offset, Charset charset, String string) {
int bytes = copyBytes(string, segment, charset, offset);
segment.set(JAVA_SHORT, offset + bytes, (short)0);
segment.set(JAVA_SHORT_UNALIGNED, offset + bytes, (short)0);
}
private static String readInt(MemorySegment segment, long offset, Charset charset) {
@ -94,7 +94,7 @@ public final class StringSupport {
private static void writeInt(MemorySegment segment, long offset, Charset charset, String string) {
int bytes = copyBytes(string, segment, charset, offset);
segment.set(JAVA_INT, offset + bytes, 0);
segment.set(JAVA_INT_UNALIGNED, offset + bytes, 0);
}
/**
@ -222,7 +222,7 @@ public final class StringSupport {
int offset = 0;
for (; offset < headCount; offset += Short.BYTES) {
short curr = segment.get(JAVA_SHORT, start + offset);
short curr = segment.get(JAVA_SHORT_UNALIGNED, start + offset);
if (curr == 0) {
return offset;
}

View File

@ -22,8 +22,6 @@
*
*/
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.foreign.Arena;
import java.lang.foreign.FunctionDescriptor;
import java.lang.foreign.Linker;
@ -33,16 +31,12 @@ import java.lang.foreign.SegmentAllocator;
import java.lang.foreign.ValueLayout;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.Field;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.function.Consumer;
import java.util.function.UnaryOperator;
import jdk.internal.foreign.StringSupport;
@ -333,6 +327,27 @@ public class TestStringEncoding {
}
}
@Test(dataProvider = "charsetsAndSegments")
public void testStringGetWithCharset(Charset charset, MemorySegment segment) {
for (int offset = 0 ; offset < Long.BYTES ; offset++) {
segment.getString(offset, charset);
}
}
@Test(dataProvider = "charsetsAndSegments")
public void testStringSetWithCharset(Charset charset, MemorySegment segment) {
for (int offset = 0 ; offset < Long.BYTES ; offset++) {
segment.setString(offset, "H", charset);
}
}
@Test(dataProvider = "charsetsAndSegments")
public void testStringAllocateFromWithCharset(Charset charset, MemorySegment segment) {
for (int offset = 0 ; offset < Long.BYTES ; offset++) {
SegmentAllocator.prefixAllocator(segment.asSlice(offset)).allocateFrom("H", charset);
}
}
@DataProvider
public static Object[][] strings() {
return new Object[][]{
@ -361,7 +376,7 @@ public class TestStringEncoding {
.allMatch(c -> Character.isLetterOrDigit((char) c));
}
boolean isStandard(Charset charset) {
static boolean isStandard(Charset charset) {
for (Field standardCharset : StandardCharsets.class.getDeclaredFields()) {
try {
if (standardCharset.get(null) == charset) {
@ -374,9 +389,9 @@ public class TestStringEncoding {
return false;
}
List<Charset> standardCharsets() {
static List<Charset> standardCharsets() {
return Charset.availableCharsets().values().stream()
.filter(this::isStandard)
.filter(TestStringEncoding::isStandard)
.toList();
}
@ -456,4 +471,26 @@ public class TestStringEncoding {
}
}
static MemorySegment[] heapSegments() {
return new MemorySegment[]{
MemorySegment.ofArray(new byte[80]),
MemorySegment.ofArray(new char[40]),
MemorySegment.ofArray(new short[40]),
MemorySegment.ofArray(new int[20]),
MemorySegment.ofArray(new float[20]),
MemorySegment.ofArray(new long[10]),
MemorySegment.ofArray(new double[10])
};
}
@DataProvider
public static Object[][] charsetsAndSegments() {
List<Object[]> values = new ArrayList<>();
for (Charset charset : standardCharsets()) {
for (MemorySegment heapSegment : heapSegments()) {
values.add(new Object[] { charset, heapSegment });
}
}
return values.toArray(Object[][]::new);
}
}