< prev index next >

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

Print this page

        

@@ -79,18 +79,14 @@
  * <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
+ * 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,15 +99,23 @@
  *     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).
+ * <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,11 +172,11 @@
         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[]{});
+        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,19 +196,19 @@
     public static VarHandle withOffset(VarHandle target, long bytesOffset) {
         if (bytesOffset < 0) {
             throw new IllegalArgumentException("Illegal offset: " + bytesOffset);
         }
 
-        long align = JLI.memoryAddressAlignment(target);
+        long alignMask = JLI.memoryAddressAlignmentMask(target);
 
-        if (bytesOffset % align != 0) {
-            throw new IllegalArgumentException("Offset " + bytesOffset + " does not conform to alignment " + align);
+        if ((bytesOffset & alignMask) != 0) {
+            throw new IllegalArgumentException("Offset " + bytesOffset + " does not conform to alignment " + (alignMask + 1));
         }
 
         return JLI.memoryAddressViewVarHandle(
                 JLI.memoryAddressCarrier(target),
-                align,
+                alignMask,
                 JLI.memoryAddressByteOrder(target),
                 JLI.memoryAddressOffset(target) + bytesOffset,
                 JLI.memoryAddressStrides(target));
     }
 

@@ -228,27 +232,26 @@
     public static VarHandle withStride(VarHandle target, long bytesStride) {
         if (bytesStride == 0) {
             throw new IllegalArgumentException("Stride must be positive: " + bytesStride);
         }
 
-        long align = JLI.memoryAddressAlignment(target);
+        long alignMask = JLI.memoryAddressAlignmentMask(target);
 
-        if (bytesStride % align != 0) {
-            throw new IllegalArgumentException("Stride " + bytesStride + " does not conform to alignment " + align);
+        if ((bytesStride & alignMask) != 0) {
+            throw new IllegalArgumentException("Stride " + bytesStride + " does not conform to alignment " + (alignMask + 1));
         }
 
         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,
+                alignMask,
                 JLI.memoryAddressByteOrder(target),
                 offset,
                 newStrides);
     }
 
< prev index next >