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 |