diff --git a/src/java.base/share/classes/java/lang/foreign/MemorySegment.java b/src/java.base/share/classes/java/lang/foreign/MemorySegment.java index faf28b01bf0..a58595cb541 100644 --- a/src/java.base/share/classes/java/lang/foreign/MemorySegment.java +++ b/src/java.base/share/classes/java/lang/foreign/MemorySegment.java @@ -305,8 +305,7 @@ import jdk.internal.vm.annotation.ForceInline; * and/or garbage collection behavior). *
* In practice, the Java runtime lays out arrays in memory so that each n-byte element - * occurs at an n-byte aligned physical address (except for {@code long[]} and - * {@code double[]}, where alignment is platform-dependent, as explained below). The + * occurs at an n-byte aligned physical address. The * runtime preserves this invariant even if the array is relocated during garbage * collection. Access operations rely on this invariant to determine if the specified * offset in a heap segment refers to an aligned address in physical memory. @@ -325,26 +324,17 @@ import jdk.internal.vm.annotation.ForceInline; * would correspond to physical address 1008 but offset 4 would correspond to * physical address 1010. *
- * In other words, heap segments feature a (platform-dependent) maximum
+ * In other words, heap segments feature a maximum
* alignment which is derived from the size of the elements of the Java array backing the
* segment, as shown in the following table:
*
@@ -389,10 +379,7 @@ import jdk.internal.vm.annotation.ForceInline;
* In such circumstances, clients have two options. They can use a heap segment backed
* by a different array type (e.g. {@code long[]}), capable of supporting greater maximum
* alignment. More specifically, the maximum alignment associated with {@code long[]} is
- * set to {@code ValueLayout.JAVA_LONG.byteAlignment()} which is a platform-dependent
- * value (set to {@code ValueLayout.ADDRESS.byteSize()}). That is, {@code long[]}) is
- * guaranteed to provide at least 8-byte alignment in 64-bit platforms, but only 4-byte
- * alignment in 32-bit platforms:
+ * set to {@code ValueLayout.JAVA_LONG.byteAlignment()}, which is 8 bytes:
*
* {@snippet lang=java :
* MemorySegment longSegment = MemorySegment.ofArray(new long[10]);
diff --git a/src/java.base/share/classes/java/lang/foreign/ValueLayout.java b/src/java.base/share/classes/java/lang/foreign/ValueLayout.java
index e8740be387c..77bfe0e0209 100644
--- a/src/java.base/share/classes/java/lang/foreign/ValueLayout.java
+++ b/src/java.base/share/classes/java/lang/foreign/ValueLayout.java
@@ -47,9 +47,6 @@ import jdk.internal.foreign.layout.ValueLayouts;
* For instance, the byte order of these constants is set to the
* {@linkplain ByteOrder#nativeOrder() native byte order}, thus making it easy
* to work with other APIs, such as arrays and {@link java.nio.ByteBuffer}.
- * Moreover, the alignment constraint of {@link ValueLayout#JAVA_LONG} and
- * {@link ValueLayout#JAVA_DOUBLE} is set to 8 bytes on 64-bit platforms,
- * but only to 4 bytes on 32-bit platforms.
*
* @implSpec implementing classes and subclasses are immutable, thread-safe and
* value-based.
diff --git a/src/java.base/share/classes/jdk/internal/foreign/HeapMemorySegmentImpl.java b/src/java.base/share/classes/jdk/internal/foreign/HeapMemorySegmentImpl.java
index e1ea65ff308..0b95c43b440 100644
--- a/src/java.base/share/classes/jdk/internal/foreign/HeapMemorySegmentImpl.java
+++ b/src/java.base/share/classes/jdk/internal/foreign/HeapMemorySegmentImpl.java
@@ -49,9 +49,6 @@ import jdk.internal.vm.annotation.ForceInline;
abstract sealed class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl {
// Constants defining the maximum alignment supported by various kinds of heap arrays.
- // While for most arrays, the maximum alignment is constant (the size, in bytes, of the array elements),
- // note that the alignment of a long[]/double[] depends on the platform: it's 4-byte on x86, but 8 bytes on x64
- // (as specified by the JAVA_LONG layout constant).
private static final long MAX_ALIGN_BYTE_ARRAY = ValueLayout.JAVA_BYTE.byteAlignment();
private static final long MAX_ALIGN_SHORT_ARRAY = ValueLayout.JAVA_SHORT.byteAlignment();
diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/fallback/FallbackLinker.java b/src/java.base/share/classes/jdk/internal/foreign/abi/fallback/FallbackLinker.java
index 77c81c6dd58..d617e535dd6 100644
--- a/src/java.base/share/classes/jdk/internal/foreign/abi/fallback/FallbackLinker.java
+++ b/src/java.base/share/classes/jdk/internal/foreign/abi/fallback/FallbackLinker.java
@@ -307,8 +307,8 @@ public final class FallbackLinker extends AbstractLinker {
Map.entry("bool", JAVA_BOOLEAN),
Map.entry("char", JAVA_BYTE),
Map.entry("float", JAVA_FLOAT),
- Map.entry("long long", JAVA_LONG),
- Map.entry("double", JAVA_DOUBLE),
+ Map.entry("long long", JAVA_LONG.withByteAlignment(LibFallback.longLongAlign())),
+ Map.entry("double", JAVA_DOUBLE.withByteAlignment(LibFallback.doubleAlign())),
Map.entry("void*", ADDRESS),
// platform-dependent sizes
Map.entry("size_t", FFIType.SIZE_T),
diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/fallback/LibFallback.java b/src/java.base/share/classes/jdk/internal/foreign/abi/fallback/LibFallback.java
index b0b6bac3d64..58d6baf8525 100644
--- a/src/java.base/share/classes/jdk/internal/foreign/abi/fallback/LibFallback.java
+++ b/src/java.base/share/classes/jdk/internal/foreign/abi/fallback/LibFallback.java
@@ -73,6 +73,8 @@ final class LibFallback {
static int intSize() { return NativeConstants.SIZEOF_INT; }
static int longSize() {return NativeConstants.SIZEOF_LONG; }
static int wcharSize() {return NativeConstants.SIZEOF_WCHAR; }
+ static int longLongAlign() { return NativeConstants.ALIGNOF_LONG_LONG; }
+ static int doubleAlign() { return NativeConstants.ALIGNOF_DOUBLE; }
static short structTag() { return NativeConstants.STRUCT_TAG; }
@@ -242,6 +244,9 @@ final class LibFallback {
private static native int ffi_sizeof_long();
private static native int ffi_sizeof_wchar();
+ private static native int alignof_long_long();
+ private static native int alignof_double();
+
// put these in a separate class to avoid an UnsatisfiedLinkError
// when LibFallback is initialized but the library is not present
private static final class NativeConstants {
@@ -263,6 +268,8 @@ final class LibFallback {
static final int SIZEOF_LONG = ffi_sizeof_long();
static final int SIZEOF_WCHAR = ffi_sizeof_wchar();
+ static final int ALIGNOF_LONG_LONG = alignof_long_long();
+ static final int ALIGNOF_DOUBLE = alignof_double();
static final MemorySegment VOID_TYPE = MemorySegment.ofAddress(ffi_type_void());
static final short STRUCT_TAG = ffi_type_struct();
diff --git a/src/java.base/share/classes/jdk/internal/foreign/layout/ValueLayouts.java b/src/java.base/share/classes/jdk/internal/foreign/layout/ValueLayouts.java
index cc61ed41a98..4b41c80f2eb 100644
--- a/src/java.base/share/classes/jdk/internal/foreign/layout/ValueLayouts.java
+++ b/src/java.base/share/classes/jdk/internal/foreign/layout/ValueLayouts.java
@@ -278,7 +278,7 @@ public final class ValueLayouts {
}
public static OfLong of(ByteOrder order) {
- return new OfLongImpl(order, ADDRESS_SIZE_BYTES, Optional.empty());
+ return new OfLongImpl(order, Long.BYTES, Optional.empty());
}
}
@@ -294,7 +294,7 @@ public final class ValueLayouts {
}
public static OfDouble of(ByteOrder order) {
- return new OfDoubleImpl(order, ADDRESS_SIZE_BYTES, Optional.empty());
+ return new OfDoubleImpl(order, Double.BYTES, Optional.empty());
}
}
diff --git a/src/java.base/share/native/libfallbackLinker/fallbackLinker.c b/src/java.base/share/native/libfallbackLinker/fallbackLinker.c
index 39d869adb63..2ee64fb05bc 100644
--- a/src/java.base/share/native/libfallbackLinker/fallbackLinker.c
+++ b/src/java.base/share/native/libfallbackLinker/fallbackLinker.c
@@ -28,6 +28,7 @@
#include