< prev index next >

test/jdk/java/foreign/NativeTestHelper.java

Print this page

 69             MH_SAVER = MethodHandles.lookup().findStatic(NativeTestHelper.class, "saver",
 70                     MethodType.methodType(Object.class, Object[].class, List.class, AtomicReference.class, SegmentAllocator.class, int.class));
 71         } catch (ReflectiveOperationException e) {
 72             throw new ExceptionInInitializerError(e);
 73         }
 74     }
 75 
 76     public static boolean isIntegral(MemoryLayout layout) {
 77         return layout instanceof ValueLayout valueLayout && isIntegral(valueLayout.carrier());
 78     }
 79 
 80     static boolean isIntegral(Class<?> clazz) {
 81         return clazz == byte.class || clazz == char.class || clazz == short.class
 82                 || clazz == int.class || clazz == long.class;
 83     }
 84 
 85     public static boolean isPointer(MemoryLayout layout) {
 86         return layout instanceof ValueLayout valueLayout && valueLayout.carrier() == MemorySegment.class;
 87     }
 88 


 89     // the constants below are useful aliases for C types. The type/carrier association is only valid for 64-bit platforms.
 90 
 91     /**
 92      * The layout for the {@code bool} C type
 93      */
 94     public static final ValueLayout.OfBoolean C_BOOL = ValueLayout.JAVA_BOOLEAN;
 95     /**
 96      * The layout for the {@code char} C type
 97      */
 98     public static final ValueLayout.OfByte C_CHAR = ValueLayout.JAVA_BYTE;
 99     /**
100      * The layout for the {@code short} C type
101      */
102     public static final ValueLayout.OfShort C_SHORT = ValueLayout.JAVA_SHORT;
103     /**
104      * The layout for the {@code int} C type
105      */
106     public static final ValueLayout.OfInt C_INT = ValueLayout.JAVA_INT;
107 
108     /**
109      * The layout for the {@code long long} C type.
110      */
111     public static final ValueLayout.OfLong C_LONG_LONG = ValueLayout.JAVA_LONG;
112     /**
113      * The layout for the {@code float} C type
114      */
115     public static final ValueLayout.OfFloat C_FLOAT = ValueLayout.JAVA_FLOAT;
116     /**
117      * The layout for the {@code double} C type
118      */
119     public static final ValueLayout.OfDouble C_DOUBLE = ValueLayout.JAVA_DOUBLE;
120     /**
121      * The {@code T*} native type.
122      */
123     public static final AddressLayout C_POINTER = ValueLayout.ADDRESS
124             .withTargetLayout(MemoryLayout.sequenceLayout(C_CHAR));
125 
126     public static final Linker LINKER = Linker.nativeLinker();

















127 
128     private static final MethodHandle FREE = LINKER.downcallHandle(
129             LINKER.defaultLookup().find("free").get(), FunctionDescriptor.ofVoid(C_POINTER));
130 
131     private static final MethodHandle MALLOC = LINKER.downcallHandle(
132             LINKER.defaultLookup().find("malloc").get(), FunctionDescriptor.of(C_POINTER, C_LONG_LONG));
133 
134     public static void freeMemory(MemorySegment address) {
135         try {
136             FREE.invokeExact(address);
137         } catch (Throwable ex) {
138             throw new IllegalStateException(ex);
139         }
140     }
141 
142     public static MemorySegment allocateMemory(long size) {
143         try {
144             return (MemorySegment) MALLOC.invokeExact(size);
145         } catch (Throwable ex) {
146             throw new IllegalStateException(ex);

231             double value = random.nextDouble();
232             return new TestValue(value, actual -> assertEquals(actual, value));
233         }
234 
235         throw new IllegalStateException("Unexpected layout: " + layout);
236     }
237 
238     private static Consumer<Object> initField(RandomGenerator random, MemorySegment container, MemoryLayout containerLayout,
239                                               MemoryLayout fieldLayout, MemoryLayout.PathElement fieldPath,
240                                               SegmentAllocator allocator) {
241         TestValue fieldValue = genTestValue(random, fieldLayout, allocator);
242         Consumer<Object> fieldCheck = fieldValue.check();
243         if (fieldLayout instanceof GroupLayout || fieldLayout instanceof SequenceLayout) {
244             UnaryOperator<MemorySegment> slicer = slicer(containerLayout, fieldPath);
245             MemorySegment slice = slicer.apply(container);
246             slice.copyFrom((MemorySegment) fieldValue.value());
247             return actual -> fieldCheck.accept(slicer.apply((MemorySegment) actual));
248         } else {
249             VarHandle accessor = containerLayout.varHandle(fieldPath);
250             //set value
251             accessor.set(container, fieldValue.value());
252             return actual -> fieldCheck.accept(accessor.get((MemorySegment) actual));
253         }
254     }
255 
256     private static UnaryOperator<MemorySegment> slicer(MemoryLayout containerLayout, MemoryLayout.PathElement fieldPath) {
257         MethodHandle slicer = containerLayout.sliceHandle(fieldPath);
258         return container -> {
259               try {
260                 return (MemorySegment) slicer.invokeExact(container);
261             } catch (Throwable e) {
262                 throw new IllegalStateException(e);
263             }
264         };
265     }
266 
267     private static void assertEquals(Object actual, Object expected) {
268         if (actual.getClass() != expected.getClass()) {
269             throw new AssertionError("Type mismatch: " + actual.getClass() + " != " + expected.getClass());
270         }
271         if (!actual.equals(expected)) {
272             throw new AssertionError("Not equal: " + actual + " != " + expected);
273         }
274     }
275 
276     /**
277      * Make an upcall stub that saves its arguments into the given 'ref' array
278      *
279      * @param fd function descriptor for the upcall stub
280      * @param capturedArgs box to save arguments in

 69             MH_SAVER = MethodHandles.lookup().findStatic(NativeTestHelper.class, "saver",
 70                     MethodType.methodType(Object.class, Object[].class, List.class, AtomicReference.class, SegmentAllocator.class, int.class));
 71         } catch (ReflectiveOperationException e) {
 72             throw new ExceptionInInitializerError(e);
 73         }
 74     }
 75 
 76     public static boolean isIntegral(MemoryLayout layout) {
 77         return layout instanceof ValueLayout valueLayout && isIntegral(valueLayout.carrier());
 78     }
 79 
 80     static boolean isIntegral(Class<?> clazz) {
 81         return clazz == byte.class || clazz == char.class || clazz == short.class
 82                 || clazz == int.class || clazz == long.class;
 83     }
 84 
 85     public static boolean isPointer(MemoryLayout layout) {
 86         return layout instanceof ValueLayout valueLayout && valueLayout.carrier() == MemorySegment.class;
 87     }
 88 
 89     public static final Linker LINKER = Linker.nativeLinker();
 90 
 91     // the constants below are useful aliases for C types. The type/carrier association is only valid for 64-bit platforms.
 92 
 93     /**
 94      * The layout for the {@code bool} C type
 95      */
 96     public static final ValueLayout.OfBoolean C_BOOL = (ValueLayout.OfBoolean) LINKER.canonicalLayouts().get("bool");
 97     /**
 98      * The layout for the {@code char} C type
 99      */
100     public static final ValueLayout.OfByte C_CHAR = (ValueLayout.OfByte) LINKER.canonicalLayouts().get("char");
101     /**
102      * The layout for the {@code short} C type
103      */
104     public static final ValueLayout.OfShort C_SHORT = (ValueLayout.OfShort) LINKER.canonicalLayouts().get("short");
105     /**
106      * The layout for the {@code int} C type
107      */
108     public static final ValueLayout.OfInt C_INT = (ValueLayout.OfInt) LINKER.canonicalLayouts().get("int");
109 
110     /**
111      * The layout for the {@code long long} C type.
112      */
113     public static final ValueLayout.OfLong C_LONG_LONG = (ValueLayout.OfLong) LINKER.canonicalLayouts().get("long long");
114     /**
115      * The layout for the {@code float} C type
116      */
117     public static final ValueLayout.OfFloat C_FLOAT = (ValueLayout.OfFloat) LINKER.canonicalLayouts().get("float");
118     /**
119      * The layout for the {@code double} C type
120      */
121     public static final ValueLayout.OfDouble C_DOUBLE = (ValueLayout.OfDouble) LINKER.canonicalLayouts().get("double");
122     /**
123      * The {@code T*} native type.
124      */
125     public static final AddressLayout C_POINTER = ((AddressLayout) LINKER.canonicalLayouts().get("void*"))
126             .withTargetLayout(MemoryLayout.sequenceLayout(Long.MAX_VALUE, C_CHAR));
127     /**
128      * The layout for the {@code size_t} C type
129      */
130     public static final ValueLayout C_SIZE_T = (ValueLayout) LINKER.canonicalLayouts().get("size_t");
131 
132     // Common layout shared by some tests
133     // struct S_PDI { void* p0; double p1; int p2; };
134     public static final MemoryLayout S_PDI_LAYOUT = switch ((int) ValueLayout.ADDRESS.byteSize()) {
135         case 8 -> MemoryLayout.structLayout(
136             C_POINTER.withName("p0"),
137             C_DOUBLE.withName("p1"),
138             C_INT.withName("p2"),
139             MemoryLayout.paddingLayout(4));
140         case 4 -> MemoryLayout.structLayout(
141             C_POINTER.withName("p0"),
142             C_DOUBLE.withName("p1"),
143             C_INT.withName("p2"));
144         default -> throw new UnsupportedOperationException("Unsupported address size");
145     };
146 
147     private static final MethodHandle FREE = LINKER.downcallHandle(
148             LINKER.defaultLookup().find("free").get(), FunctionDescriptor.ofVoid(C_POINTER));
149 
150     private static final MethodHandle MALLOC = LINKER.downcallHandle(
151             LINKER.defaultLookup().find("malloc").get(), FunctionDescriptor.of(C_POINTER, C_LONG_LONG));
152 
153     public static void freeMemory(MemorySegment address) {
154         try {
155             FREE.invokeExact(address);
156         } catch (Throwable ex) {
157             throw new IllegalStateException(ex);
158         }
159     }
160 
161     public static MemorySegment allocateMemory(long size) {
162         try {
163             return (MemorySegment) MALLOC.invokeExact(size);
164         } catch (Throwable ex) {
165             throw new IllegalStateException(ex);

250             double value = random.nextDouble();
251             return new TestValue(value, actual -> assertEquals(actual, value));
252         }
253 
254         throw new IllegalStateException("Unexpected layout: " + layout);
255     }
256 
257     private static Consumer<Object> initField(RandomGenerator random, MemorySegment container, MemoryLayout containerLayout,
258                                               MemoryLayout fieldLayout, MemoryLayout.PathElement fieldPath,
259                                               SegmentAllocator allocator) {
260         TestValue fieldValue = genTestValue(random, fieldLayout, allocator);
261         Consumer<Object> fieldCheck = fieldValue.check();
262         if (fieldLayout instanceof GroupLayout || fieldLayout instanceof SequenceLayout) {
263             UnaryOperator<MemorySegment> slicer = slicer(containerLayout, fieldPath);
264             MemorySegment slice = slicer.apply(container);
265             slice.copyFrom((MemorySegment) fieldValue.value());
266             return actual -> fieldCheck.accept(slicer.apply((MemorySegment) actual));
267         } else {
268             VarHandle accessor = containerLayout.varHandle(fieldPath);
269             //set value
270             accessor.set(container, 0L, fieldValue.value());
271             return actual -> fieldCheck.accept(accessor.get((MemorySegment) actual, 0L));
272         }
273     }
274 
275     private static UnaryOperator<MemorySegment> slicer(MemoryLayout containerLayout, MemoryLayout.PathElement fieldPath) {
276         MethodHandle slicer = containerLayout.sliceHandle(fieldPath);
277         return container -> {
278               try {
279                 return (MemorySegment) slicer.invokeExact(container, 0L);
280             } catch (Throwable e) {
281                 throw new IllegalStateException(e);
282             }
283         };
284     }
285 
286     private static void assertEquals(Object actual, Object expected) {
287         if (actual.getClass() != expected.getClass()) {
288             throw new AssertionError("Type mismatch: " + actual.getClass() + " != " + expected.getClass());
289         }
290         if (!actual.equals(expected)) {
291             throw new AssertionError("Not equal: " + actual + " != " + expected);
292         }
293     }
294 
295     /**
296      * Make an upcall stub that saves its arguments into the given 'ref' array
297      *
298      * @param fd function descriptor for the upcall stub
299      * @param capturedArgs box to save arguments in
< prev index next >