mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8308248: Revisit alignment of layout constants on 32-bit platforms
Reviewed-by: psandoz, pminborg
This commit is contained in:
parent
80ef5c228b
commit
44218b1c9e
6 changed files with 62 additions and 39 deletions
|
@ -264,12 +264,6 @@ import jdk.internal.vm.annotation.ForceInline;
|
|||
* 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. For example:
|
||||
* <ul>
|
||||
* <li>The starting physical address of a {@code long[]} array will be 8-byte aligned (e.g. 1000), so that successive long elements
|
||||
* occur at 8-byte aligned addresses (e.g., 1000, 1008, 1016, 1024, etc.) A heap segment backed by a {@code long[]} array
|
||||
* can be accessed at offsets 0, 8, 16, 24, etc under an 8-byte alignment constraint. In addition, the segment can be
|
||||
* accessed at offsets 0, 4, 8, 12, etc under a 4-byte alignment constraint, because the target addresses
|
||||
* (1000, 1004, 1008, 1012) are 4-byte aligned. And, the segment can be accessed at offsets 0, 2, 4, 6, etc under a
|
||||
* 2-byte alignment constraint, because the target addresses (e.g. 1000, 1002, 1004, 1006) are 2-byte aligned.</li>
|
||||
* <li>The starting physical address of a {@code short[]} array will be 2-byte aligned (e.g. 1006) so that successive
|
||||
* short elements occur at 2-byte aligned addresses (e.g. 1006, 1008, 1010, 1012, etc). A heap segment backed by a
|
||||
* {@code short[]} array can be accessed at offsets 0, 2, 4, 6, etc under a 2-byte alignment constraint. The segment cannot
|
||||
|
@ -278,10 +272,22 @@ import jdk.internal.vm.annotation.ForceInline;
|
|||
* to physical address 1007. Similarly, the segment cannot be accessed at any offset under an 8-byte alignment constraint,
|
||||
* because because there is no guarantee that the target address would be 8-byte aligned, e.g., offset 2 would correspond
|
||||
* to physical address 1008 but offset 4 would correspond to physical address 1010.</li>
|
||||
* <li>The starting physical address of a {@code long[]} array will be 8-byte aligned (e.g. 1000) on 64-bit platforms,
|
||||
* so that successive long elements occur at 8-byte aligned addresses (e.g., 1000, 1008, 1016, 1024, etc.) On 64-bit platforms,
|
||||
* a heap segment backed by a {@code long[]} array can be accessed at offsets 0, 8, 16, 24, etc under an 8-byte alignment
|
||||
* constraint. In addition, the segment can be accessed at offsets 0, 4, 8, 12, etc under a 4-byte alignment constraint,
|
||||
* because the target addresses (1000, 1004, 1008, 1012) are 4-byte aligned. And, the segment can be accessed at offsets
|
||||
* 0, 2, 4, 6, etc under a 2-byte alignment constraint, because the target addresses (e.g. 1000, 1002, 1004, 1006) are 2-byte aligned.</li>
|
||||
* <li>The starting physical address of a {@code long[]} array will be 4-byte aligned (e.g. 1000) on 32-bit platforms,
|
||||
* so that successive long elements occur at 4-byte aligned addresses (e.g., 1004, 1008, 1012, 1016, etc.) On 32-bit
|
||||
* platforms, a heap segment backed by a {@code long[]} array can be accessed at offsets 0, 4, 8, 12, etc under a 4-byte
|
||||
* alignment constraint, because the target addresses (1000, 1004, 1008, 1012) are 4-byte aligned. And, the segment
|
||||
* can be accessed at offsets 0, 2, 4, 6, etc under a 2-byte alignment constraint, because the target addresses
|
||||
* (e.g. 1000, 1002, 1004, 1006) are 2-byte aligned.</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* In other words, heap segments feature a <em>maximum</em> alignment which is derived from the size of the elements of
|
||||
* the Java array backing the segment, as shown in the following table:
|
||||
* In other words, heap segments feature a (platform-dependent) <em>maximum</em> alignment which is derived from the
|
||||
* size of the elements of the Java array backing the segment, as shown in the following table:
|
||||
*
|
||||
* <blockquote><table class="plain">
|
||||
* <caption style="display:none">Maximum alignment of heap segments</caption>
|
||||
|
@ -293,21 +299,21 @@ import jdk.internal.vm.annotation.ForceInline;
|
|||
* </thead>
|
||||
* <tbody>
|
||||
* <tr><th scope="row" style="font-weight:normal">{@code boolean[]}</th>
|
||||
* <td style="text-align:center;">{@code 1}</td></tr>
|
||||
* <td style="text-align:center;">{@code ValueLayout.JAVA_BOOLEAN.byteAlignment()}</td></tr>
|
||||
* <tr><th scope="row" style="font-weight:normal">{@code byte[]}</th>
|
||||
* <td style="text-align:center;">{@code 1}</td></tr>
|
||||
* <td style="text-align:center;">{@code ValueLayout.JAVA_BYTE.byteAlignment()}</td></tr>
|
||||
* <tr><th scope="row" style="font-weight:normal">{@code char[]}</th>
|
||||
* <td style="text-align:center;">{@code 2}</td></tr>
|
||||
* <td style="text-align:center;">{@code ValueLayout.JAVA_CHAR.byteAlignment()}</td></tr>
|
||||
* <tr><th scope="row" style="font-weight:normal">{@code short[]}</th>
|
||||
* <td style="text-align:center;">{@code 2}</td></tr>
|
||||
* <td style="text-align:center;">{@code ValueLayout.JAVA_SHORT.byteAlignment()}</td></tr>
|
||||
* <tr><th scope="row" style="font-weight:normal">{@code int[]}</th>
|
||||
* <td style="text-align:center;">{@code 4}</td></tr>
|
||||
* <td style="text-align:center;">{@code ValueLayout.JAVA_INT.byteAlignment()}</td></tr>
|
||||
* <tr><th scope="row" style="font-weight:normal">{@code float[]}</th>
|
||||
* <td style="text-align:center;">{@code 4}</td></tr>
|
||||
* <td style="text-align:center;">{@code ValueLayout.JAVA_FLOAT.byteAlignment()}</td></tr>
|
||||
* <tr><th scope="row" style="font-weight:normal">{@code long[]}</th>
|
||||
* <td style="text-align:center;">{@code 8}</td></tr>
|
||||
* <td style="text-align:center;">{@code ValueLayout.JAVA_LONG.byteAlignment()}</td></tr>
|
||||
* <tr><th scope="row" style="font-weight:normal">{@code double[]}</th>
|
||||
* <td style="text-align:center;">{@code 8}</td></tr>
|
||||
* <td style="text-align:center;">{@code ValueLayout.JAVA_DOUBLE.byteAlignment()}</td></tr>
|
||||
* </tbody>
|
||||
* </table></blockquote>
|
||||
*
|
||||
|
@ -318,22 +324,25 @@ import jdk.internal.vm.annotation.ForceInline;
|
|||
*
|
||||
* {@snippet lang=java :
|
||||
* MemorySegment byteSegment = MemorySegment.ofArray(new byte[10]);
|
||||
* byteSegment.get(ValueLayout.JAVA_INT, 0); // fails: layout alignment is 4, segment max alignment is 1
|
||||
* byteSegment.get(ValueLayout.JAVA_INT, 0); // fails: ValueLayout.JAVA_INT.byteAlignment() > ValueLayout.JAVA_BYTE.byteAlignment()
|
||||
* }
|
||||
*
|
||||
* 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:
|
||||
* 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:
|
||||
*
|
||||
* {@snippet lang=java :
|
||||
* MemorySegment longSegment = MemorySegment.ofArray(new long[10]);
|
||||
* longSegment.get(ValueLayout.JAVA_INT, 0); // ok: layout alignment is 4, segment max alignment is 8
|
||||
* longSegment.get(ValueLayout.JAVA_INT, 0); // ok: ValueLayout.JAVA_INT.byteAlignment() <= ValueLayout.JAVA_LONG.byteAlignment()
|
||||
* }
|
||||
*
|
||||
* Alternatively, they can invoke the access operation with an <em>unaligned layout</em>.
|
||||
* All unaligned layout constants (e.g. {@link ValueLayout#JAVA_INT_UNALIGNED}) have their alignment constraint set to 1:
|
||||
* {@snippet lang=java :
|
||||
* MemorySegment byteSegment = MemorySegment.ofArray(new byte[10]);
|
||||
* byteSegment.get(ValueLayout.JAVA_INT_UNALIGNED, 0); // ok: layout alignment is 1, segment max alignment is 1
|
||||
* byteSegment.get(ValueLayout.JAVA_INT_UNALIGNED, 0); // ok: ValueLayout.JAVA_INT_UNALIGNED.byteAlignment() == ValueLayout.JAVA_BYTE.byteAlignment()
|
||||
* }
|
||||
*
|
||||
* <h2 id="wrapping-addresses">Zero-length memory segments</h2>
|
||||
|
|
|
@ -485,7 +485,8 @@ public sealed interface ValueLayout extends MemoryLayout permits
|
|||
|
||||
/**
|
||||
* A value layout constant whose size is the same as that of a Java {@code long},
|
||||
* bit alignment set to 64, and byte order set to {@link ByteOrder#nativeOrder()}.
|
||||
* (platform-dependent) bit alignment set to {@code ADDRESS.bitSize()},
|
||||
* and byte order set to {@link ByteOrder#nativeOrder()}.
|
||||
*/
|
||||
OfLong JAVA_LONG = ValueLayouts.OfLongImpl.of(ByteOrder.nativeOrder());
|
||||
|
||||
|
@ -497,7 +498,8 @@ public sealed interface ValueLayout extends MemoryLayout permits
|
|||
|
||||
/**
|
||||
* A value layout constant whose size is the same as that of a Java {@code double},
|
||||
* bit alignment set to 64, and byte order set to {@link ByteOrder#nativeOrder()}.
|
||||
* (platform-dependent) bit alignment set to {@code ADDRESS.bitSize()},
|
||||
* and byte order set to {@link ByteOrder#nativeOrder()}.
|
||||
*/
|
||||
OfDouble JAVA_DOUBLE = ValueLayouts.OfDoubleImpl.of(ByteOrder.nativeOrder());
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue