< prev index next >

src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryHandles.java

Print this page

        

*** 79,96 **** * <em>static</em> constants which are can be acquired through the {@link MemoryHandles#withOffset(VarHandle, long)} * and the {@link MemoryHandles#withStride(VarHandle, long)} combinators, respectively. * * <h2><a id="memaccess-mode"></a>Alignment and access modes</h2> * ! * Memory access may be <em>aligned</em> or <em>misaligned</em> for the given carrier {@code T}, ! * with respect to the underlying memory address, {@code A} say, which is the final address (computed by the formula described above) ! * at which the memory dereference operation occurs. ! * ! * If access is misaligned then access for anything other than the {@code get} and {@code set} access modes will result ! * in an {@code IllegalStateException}. In such cases atomic access is only guaranteed with respect to the largest power ! * of two that divides the GCD of {@code A} and the size (in bytes) of {@code T}. ! * If access is aligned then following access modes are supported and are * guaranteed to support atomic access: * <ul> * <li>read write access modes for all {@code T}, with the exception of * access modes {@code get} and {@code set} for {@code long} and * {@code double} on 32-bit platforms. --- 79,92 ---- * <em>static</em> constants which are can be acquired through the {@link MemoryHandles#withOffset(VarHandle, long)} * and the {@link MemoryHandles#withStride(VarHandle, long)} combinators, respectively. * * <h2><a id="memaccess-mode"></a>Alignment and access modes</h2> * ! * A memory access var handle is associated with an access size {@code S} and an alignment constraint {@code B} ! * (both expressed in bytes). We say that a memory access operation is <em>fully aligned</em> if it occurs ! * at a memory address {@code A} which is compatible with both alignment constraints {@code S} and {@code B}. ! * If access is fully aligned then following access modes are supported and are * guaranteed to support atomic access: * <ul> * <li>read write access modes for all {@code T}, with the exception of * access modes {@code get} and {@code set} for {@code long} and * {@code double} on 32-bit platforms.
*** 103,117 **** * numeric types for certain currently unsupported access modes.) * <li>bitwise atomic update access modes for {@code int} and {@code long}. * (Future major platform releases of the JDK may support additional * numeric types for certain currently unsupported access modes.) * </ul> ! * <p> * If {@code T} is {@code float} or {@code double} then atomic * update access modes compare values using their bitwise representation * (see {@link Float#floatToRawIntBits} and * {@link Double#doubleToRawLongBits}, respectively). */ public final class MemoryHandles { private final static JavaLangInvokeAccess JLI = SharedSecrets.getJavaLangInvokeAccess(); --- 99,121 ---- * numeric types for certain currently unsupported access modes.) * <li>bitwise atomic update access modes for {@code int} and {@code long}. * (Future major platform releases of the JDK may support additional * numeric types for certain currently unsupported access modes.) * </ul> ! * * If {@code T} is {@code float} or {@code double} then atomic * update access modes compare values using their bitwise representation * (see {@link Float#floatToRawIntBits} and * {@link Double#doubleToRawLongBits}, respectively). + * <p> + * Alternatively, a memory access operation is <em>partially aligned</em> if it occurs at a memory address {@code A} + * which is only compatible with the alignment constraint {@code B}; in such cases, access for anything other than the + * {@code get} and {@code set} access modes will result in an {@code IllegalStateException}. If access is partially aligned, + * atomic access is only guaranteed with respect to the largest power of two that divides the GCD of {@code A} and {@code S}. + * <p> + * Finally, in all other cases, we say that a memory access operation is <em>misaligned</em>; in such cases an + * {@code IllegalStateException} is thrown, irrespective of the access mode being used. */ public final class MemoryHandles { private final static JavaLangInvokeAccess JLI = SharedSecrets.getJavaLangInvokeAccess();
*** 168,178 **** if (alignmentBytes <= 0 || (alignmentBytes & (alignmentBytes - 1)) != 0) { // is power of 2? throw new IllegalArgumentException("Bad alignment: " + alignmentBytes); } ! return JLI.memoryAddressViewVarHandle(carrier, alignmentBytes, byteOrder, 0, new long[]{}); } /** * Creates a memory access var handle with a fixed offset added to the accessed offset. That is, * if the target memory access var handle accesses a memory location at offset <em>O</em>, the new memory access var --- 172,182 ---- if (alignmentBytes <= 0 || (alignmentBytes & (alignmentBytes - 1)) != 0) { // is power of 2? throw new IllegalArgumentException("Bad alignment: " + alignmentBytes); } ! return JLI.memoryAddressViewVarHandle(carrier, alignmentBytes - 1, byteOrder, 0, new long[]{}); } /** * Creates a memory access var handle with a fixed offset added to the accessed offset. That is, * if the target memory access var handle accesses a memory location at offset <em>O</em>, the new memory access var
*** 192,210 **** public static VarHandle withOffset(VarHandle target, long bytesOffset) { if (bytesOffset < 0) { throw new IllegalArgumentException("Illegal offset: " + bytesOffset); } ! long align = JLI.memoryAddressAlignment(target); ! if (bytesOffset % align != 0) { ! throw new IllegalArgumentException("Offset " + bytesOffset + " does not conform to alignment " + align); } return JLI.memoryAddressViewVarHandle( JLI.memoryAddressCarrier(target), ! align, JLI.memoryAddressByteOrder(target), JLI.memoryAddressOffset(target) + bytesOffset, JLI.memoryAddressStrides(target)); } --- 196,214 ---- public static VarHandle withOffset(VarHandle target, long bytesOffset) { if (bytesOffset < 0) { throw new IllegalArgumentException("Illegal offset: " + bytesOffset); } ! long alignMask = JLI.memoryAddressAlignmentMask(target); ! if ((bytesOffset & alignMask) != 0) { ! throw new IllegalArgumentException("Offset " + bytesOffset + " does not conform to alignment " + (alignMask + 1)); } return JLI.memoryAddressViewVarHandle( JLI.memoryAddressCarrier(target), ! alignMask, JLI.memoryAddressByteOrder(target), JLI.memoryAddressOffset(target) + bytesOffset, JLI.memoryAddressStrides(target)); }
*** 228,254 **** public static VarHandle withStride(VarHandle target, long bytesStride) { if (bytesStride == 0) { throw new IllegalArgumentException("Stride must be positive: " + bytesStride); } ! long align = JLI.memoryAddressAlignment(target); ! if (bytesStride % align != 0) { ! throw new IllegalArgumentException("Stride " + bytesStride + " does not conform to alignment " + align); } long offset = JLI.memoryAddressOffset(target); - Class<?> carrier = JLI.memoryAddressCarrier(target); long[] strides = JLI.memoryAddressStrides(target); long[] newStrides = new long[strides.length + 1]; System.arraycopy(strides, 0, newStrides, 1, strides.length); newStrides[0] = bytesStride; return JLI.memoryAddressViewVarHandle( JLI.memoryAddressCarrier(target), ! align, JLI.memoryAddressByteOrder(target), offset, newStrides); } --- 232,257 ---- public static VarHandle withStride(VarHandle target, long bytesStride) { if (bytesStride == 0) { throw new IllegalArgumentException("Stride must be positive: " + bytesStride); } ! long alignMask = JLI.memoryAddressAlignmentMask(target); ! if ((bytesStride & alignMask) != 0) { ! throw new IllegalArgumentException("Stride " + bytesStride + " does not conform to alignment " + (alignMask + 1)); } long offset = JLI.memoryAddressOffset(target); long[] strides = JLI.memoryAddressStrides(target); long[] newStrides = new long[strides.length + 1]; System.arraycopy(strides, 0, newStrides, 1, strides.length); newStrides[0] = bytesStride; return JLI.memoryAddressViewVarHandle( JLI.memoryAddressCarrier(target), ! alignMask, JLI.memoryAddressByteOrder(target), offset, newStrides); }
< prev index next >