< prev index next >

src/java.base/share/classes/java/lang/invoke/VarHandles.java

Print this page




 286             return new VarHandleByteArrayAsDoubles.ByteBufferHandle(be);
 287         }
 288         else if (viewComponentType == float.class) {
 289             return new VarHandleByteArrayAsFloats.ByteBufferHandle(be);
 290         }
 291 
 292         throw new UnsupportedOperationException();
 293     }
 294 
 295     /**
 296      * Creates a memory access VarHandle.
 297      *
 298      * Resulting VarHandle will take a memory address as first argument,
 299      * and a certain number of coordinate {@code long} parameters, depending on the length
 300      * of the {@code strides} argument array.
 301      *
 302      * Coordinates are multiplied with corresponding scale factors ({@code strides}) and added
 303      * to a single fixed offset to compute an effective offset from the given MemoryAddress for the access.
 304      *
 305      * @param carrier the Java carrier type.
 306      * @param alignment alignment requirement to be checked upon access. In bytes. Must be a power of 2.
 307      * @param byteOrder the byte order.
 308      * @param offset a constant offset for the access.
 309      * @param strides the scale factors with which to multiply given access coordinates.
 310      * @return the created VarHandle.
 311      */
 312     static VarHandle makeMemoryAddressViewHandle(Class<?> carrier, long alignment,
 313                                                  ByteOrder byteOrder, long offset, long[] strides) {
 314         if (!carrier.isPrimitive() || carrier == void.class || carrier == boolean.class) {
 315             throw new IllegalArgumentException("Invalid carrier: " + carrier.getName());
 316         }
 317         long size = Wrapper.forPrimitiveType(carrier).bitWidth() / 8;
 318         boolean be = byteOrder == ByteOrder.BIG_ENDIAN;
 319 
 320         Map<Integer, MethodHandle> carrierFactory = ADDRESS_FACTORIES.get(carrier);
 321         MethodHandle fac = carrierFactory.computeIfAbsent(strides.length,
 322                 dims -> new AddressVarHandleGenerator(carrier, dims)
 323                             .generateHandleFactory());
 324 
 325         try {
 326             return (VarHandle)fac.invoke(be, size, offset, alignment - 1, strides);
 327         } catch (Throwable ex) {
 328             throw new IllegalStateException(ex);
 329         }
 330     }
 331 
 332 //    /**
 333 //     * A helper program to generate the VarHandleGuards class with a set of
 334 //     * static guard methods each of which corresponds to a particular shape and
 335 //     * performs a type check of the symbolic type descriptor with the VarHandle
 336 //     * type descriptor before linking/invoking to the underlying operation as
 337 //     * characterized by the operation member name on the VarForm of the
 338 //     * VarHandle.
 339 //     * <p>
 340 //     * The generated class essentially encapsulates pre-compiled LambdaForms,
 341 //     * one for each method, for the most set of common method signatures.
 342 //     * This reduces static initialization costs, footprint costs, and circular
 343 //     * dependencies that may arise if a class is generated per LambdaForm.
 344 //     * <p>
 345 //     * A maximum of L*T*S methods will be generated where L is the number of
 346 //     * access modes kinds (or unique operation signatures) and T is the number




 286             return new VarHandleByteArrayAsDoubles.ByteBufferHandle(be);
 287         }
 288         else if (viewComponentType == float.class) {
 289             return new VarHandleByteArrayAsFloats.ByteBufferHandle(be);
 290         }
 291 
 292         throw new UnsupportedOperationException();
 293     }
 294 
 295     /**
 296      * Creates a memory access VarHandle.
 297      *
 298      * Resulting VarHandle will take a memory address as first argument,
 299      * and a certain number of coordinate {@code long} parameters, depending on the length
 300      * of the {@code strides} argument array.
 301      *
 302      * Coordinates are multiplied with corresponding scale factors ({@code strides}) and added
 303      * to a single fixed offset to compute an effective offset from the given MemoryAddress for the access.
 304      *
 305      * @param carrier the Java carrier type.
 306      * @param alignmentMask alignment requirement to be checked upon access. In bytes. Expressed as a mask.
 307      * @param byteOrder the byte order.
 308      * @param offset a constant offset for the access.
 309      * @param strides the scale factors with which to multiply given access coordinates.
 310      * @return the created VarHandle.
 311      */
 312     static VarHandle makeMemoryAddressViewHandle(Class<?> carrier, long alignmentMask,
 313                                                  ByteOrder byteOrder, long offset, long[] strides) {
 314         if (!carrier.isPrimitive() || carrier == void.class || carrier == boolean.class) {
 315             throw new IllegalArgumentException("Invalid carrier: " + carrier.getName());
 316         }
 317         long size = Wrapper.forPrimitiveType(carrier).bitWidth() / 8;
 318         boolean be = byteOrder == ByteOrder.BIG_ENDIAN;
 319 
 320         Map<Integer, MethodHandle> carrierFactory = ADDRESS_FACTORIES.get(carrier);
 321         MethodHandle fac = carrierFactory.computeIfAbsent(strides.length,
 322                 dims -> new AddressVarHandleGenerator(carrier, dims)
 323                             .generateHandleFactory());
 324 
 325         try {
 326             return (VarHandle)fac.invoke(be, size, offset, alignmentMask, strides);
 327         } catch (Throwable ex) {
 328             throw new IllegalStateException(ex);
 329         }
 330     }
 331 
 332 //    /**
 333 //     * A helper program to generate the VarHandleGuards class with a set of
 334 //     * static guard methods each of which corresponds to a particular shape and
 335 //     * performs a type check of the symbolic type descriptor with the VarHandle
 336 //     * type descriptor before linking/invoking to the underlying operation as
 337 //     * characterized by the operation member name on the VarForm of the
 338 //     * VarHandle.
 339 //     * <p>
 340 //     * The generated class essentially encapsulates pre-compiled LambdaForms,
 341 //     * one for each method, for the most set of common method signatures.
 342 //     * This reduces static initialization costs, footprint costs, and circular
 343 //     * dependencies that may arise if a class is generated per LambdaForm.
 344 //     * <p>
 345 //     * A maximum of L*T*S methods will be generated where L is the number of
 346 //     * access modes kinds (or unique operation signatures) and T is the number


< prev index next >