8329997: Add provisions for checking memory segment alignment constraints

Reviewed-by: jvernee, mcimadamore
This commit is contained in:
Per Minborg 2024-04-18 11:22:47 +00:00
parent 60b65e6090
commit b648ed0a08
4 changed files with 133 additions and 6 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -44,7 +44,6 @@ import java.util.stream.Stream;
import jdk.internal.foreign.AbstractMemorySegmentImpl;
import jdk.internal.foreign.MemorySessionImpl;
import jdk.internal.foreign.SegmentFactories;
import jdk.internal.foreign.Utils;
import jdk.internal.javac.Restricted;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.vm.annotation.ForceInline;
@ -95,6 +94,11 @@ import jdk.internal.vm.annotation.ForceInline;
* address of the region of memory which backs the segment.</li>
* </ul>
* <p>
* Every memory segment has a {@linkplain #maxByteAlignment() maximum byte alignment},
* expressed as a {@code long} value. The maximum alignment is always a power of two,
* derived from the segment address, and the segment type, as explained in more detail
* <a href="#segment-alignment">below</a>.
* <p>
* Every memory segment has a {@linkplain #byteSize() size}. The size of a heap segment
* is derived from the Java array from which it is obtained. This size is predictable
* across Java runtimes. The size of a native segment is either passed explicitly
@ -394,6 +398,14 @@ import jdk.internal.vm.annotation.ForceInline;
* byteSegment.get(ValueLayout.JAVA_INT_UNALIGNED, 0); // ok: ValueLayout.JAVA_INT_UNALIGNED.byteAlignment() == ValueLayout.JAVA_BYTE.byteAlignment()
* }
*
* Clients can use the {@linkplain MemorySegment#maxByteAlignment()} method to check if
* a memory segment supports the alignment constraint of a memory layout, as follows:
* {@snippet lang=java:
* MemoryLayout layout = ...
* MemorySegment segment = ...
* boolean isAligned = segment.maxByteAlignment() >= layout.byteAlignment();
* }
*
* <h2 id="wrapping-addresses">Zero-length memory segments</h2>
*
* When interacting with <a href="package-summary.html#ffa">foreign functions</a>, it is
@ -589,6 +601,26 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
*/
long byteSize();
/**
* {@return the <a href="#segment-alignment">maximum byte alignment</a>
* associated with this memory segment}
* <p>
* The returned alignment is always a power of two and is derived from
* the segment {@linkplain #address() address()} and, if it is a heap segment,
* the type of the {@linkplain #heapBase() backing heap storage}.
* <p>
* This method can be used to ensure that a segment is sufficiently aligned
* with a layout:
* {@snippet lang=java:
* MemoryLayout layout = ...
* MemorySegment segment = ...
* if (segment.maxByteAlignment() < layout.byteAlignment()) {
* // Take action (e.g. throw an Exception)
* }
* }
*/
long maxByteAlignment();
/**
* Returns a slice of this memory segment, at the given offset. The returned
* segment's address is the address of this segment plus the given offset;
@ -1424,6 +1456,9 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
/**
* A zero-length native segment modelling the {@code NULL} address. Equivalent to
* {@code MemorySegment.ofAddress(0L)}.
* <p>
* The {@linkplain MemorySegment#maxByteAlignment() maximum byte alignment} for
* the {@code NULL} segment is of 2<sup>62</sup>.
*/
MemorySegment NULL = MemorySegment.ofAddress(0L);