< prev index next >

test/jdk/java/foreign/TestUpcallHighArity.java

Print this page

 16  *  2 along with this work; if not, write to the Free Software Foundation,
 17  *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  *  or visit www.oracle.com if you need additional information or have any
 21  *  questions.
 22  *
 23  */
 24 
 25 /*
 26  * @test
 27  * @requires ((os.arch == "amd64" | os.arch == "x86_64") & sun.arch.data.model == "64") | os.arch == "aarch64"
 28  * @modules jdk.incubator.foreign/jdk.internal.foreign
 29  * @build NativeTestHelper CallGeneratorHelper TestUpcallHighArity
 30  *
 31  * @run testng/othervm/native
 32  *   --enable-native-access=ALL-UNNAMED
 33  *   TestUpcallHighArity
 34  */
 35 

 36 import jdk.incubator.foreign.CLinker;
 37 import jdk.incubator.foreign.FunctionDescriptor;

 38 import jdk.incubator.foreign.SymbolLookup;
 39 import jdk.incubator.foreign.MemoryAddress;
 40 import jdk.incubator.foreign.MemoryLayout;
 41 import jdk.incubator.foreign.MemorySegment;
 42 import jdk.incubator.foreign.ResourceScope;
 43 import org.testng.annotations.DataProvider;
 44 import org.testng.annotations.Test;
 45 
 46 import java.lang.invoke.MethodHandle;
 47 import java.lang.invoke.MethodHandles;
 48 import java.lang.invoke.MethodType;
 49 import java.util.List;
 50 import java.util.concurrent.atomic.AtomicReference;
 51 
 52 import static jdk.incubator.foreign.CLinker.*;
 53 import static org.testng.Assert.assertEquals;
 54 
 55 public class TestUpcallHighArity extends CallGeneratorHelper {
 56     static final MethodHandle MH_do_upcall;
 57     static final MethodHandle MH_passAndSave;
 58     static final CLinker LINKER = CLinker.getInstance();
 59 
 60     // struct S_PDI { void* p0; double p1; int p2; };
 61     static final MemoryLayout S_PDI_LAYOUT = MemoryLayout.structLayout(
 62         C_POINTER.withName("p0"),
 63         C_DOUBLE.withName("p1"),
 64         C_INT.withName("p2")
 65     );
 66 
 67     static {
 68         try {
 69             System.loadLibrary("TestUpcallHighArity");
 70             SymbolLookup lookup = SymbolLookup.loaderLookup();
 71             MH_do_upcall = LINKER.downcallHandle(
 72                 lookup.lookup("do_upcall").get(),
 73                 MethodType.methodType(void.class, MemoryAddress.class,
 74                     MemorySegment.class, int.class, double.class, MemoryAddress.class,
 75                     MemorySegment.class, int.class, double.class, MemoryAddress.class,
 76                     MemorySegment.class, int.class, double.class, MemoryAddress.class,
 77                     MemorySegment.class, int.class, double.class, MemoryAddress.class),
 78                 FunctionDescriptor.ofVoid(C_POINTER,
 79                     S_PDI_LAYOUT, C_INT, C_DOUBLE, C_POINTER,
 80                     S_PDI_LAYOUT, C_INT, C_DOUBLE, C_POINTER,
 81                     S_PDI_LAYOUT, C_INT, C_DOUBLE, C_POINTER,
 82                     S_PDI_LAYOUT, C_INT, C_DOUBLE, C_POINTER)
 83             );
 84             MH_passAndSave = MethodHandles.lookup().findStatic(TestUpcallHighArity.class, "passAndSave",
 85                     MethodType.methodType(void.class, Object[].class, AtomicReference.class));
 86         } catch (ReflectiveOperationException e) {
 87             throw new InternalError(e);
 88         }
 89     }
 90 
 91     static void passAndSave(Object[] o, AtomicReference<Object[]> ref) {
 92         for (int i = 0; i < o.length; i++) {
 93             if (o[i] instanceof MemorySegment) {
 94                 MemorySegment ms = (MemorySegment) o[i];
 95                 MemorySegment copy = MemorySegment.allocateNative(ms.byteSize(), ResourceScope.newImplicitScope());
 96                 copy.copyFrom(ms);
 97                 o[i] = copy;
 98             }
 99         }
100         ref.set(o);
101     }
102 
103     @Test(dataProvider = "args")
104     public void testUpcall(MethodHandle downcall, MethodType upcallType,
105                            FunctionDescriptor upcallDescriptor) throws Throwable {
106         AtomicReference<Object[]> capturedArgs = new AtomicReference<>();
107         MethodHandle target = MethodHandles.insertArguments(MH_passAndSave, 1, capturedArgs)
108                                          .asCollector(Object[].class, upcallType.parameterCount())
109                                          .asType(upcallType);
110         try (ResourceScope scope = ResourceScope.newConfinedScope()) {
111             MemoryAddress upcallStub = LINKER.upcallStub(target, upcallDescriptor, scope);
112             Object[] args = new Object[upcallType.parameterCount() + 1];
113             args[0] = upcallStub.address();
114             List<MemoryLayout> argLayouts = upcallDescriptor.argumentLayouts();
115             for (int i = 1; i < args.length; i++) {
116                 args[i] = makeArg(argLayouts.get(i - 1), null, false);
117             }
118 
119             downcall.invokeWithArguments(args);
120 
121             Object[] capturedArgsArr = capturedArgs.get();
122             for (int i = 0; i < capturedArgsArr.length; i++) {
123                 if (upcallType.parameterType(i) == MemorySegment.class) {
124                     assertStructEquals((MemorySegment) capturedArgsArr[i], (MemorySegment) args[i + 1], argLayouts.get(i));
125                 } else {
126                     assertEquals(capturedArgsArr[i], args[i + 1]);
127                 }
128             }
129         }
130     }
131 
132     @DataProvider
133     public static Object[][] args() {
134         return new Object[][]{
135             { MH_do_upcall,
136                 MethodType.methodType(void.class,
137                     MemorySegment.class, int.class, double.class, MemoryAddress.class,
138                     MemorySegment.class, int.class, double.class, MemoryAddress.class,
139                     MemorySegment.class, int.class, double.class, MemoryAddress.class,
140                     MemorySegment.class, int.class, double.class, MemoryAddress.class),
141                 FunctionDescriptor.ofVoid(
142                     S_PDI_LAYOUT, C_INT, C_DOUBLE, C_POINTER,
143                     S_PDI_LAYOUT, C_INT, C_DOUBLE, C_POINTER,
144                     S_PDI_LAYOUT, C_INT, C_DOUBLE, C_POINTER,
145                     S_PDI_LAYOUT, C_INT, C_DOUBLE, C_POINTER)
146             }

 16  *  2 along with this work; if not, write to the Free Software Foundation,
 17  *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  *  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  *  or visit www.oracle.com if you need additional information or have any
 21  *  questions.
 22  *
 23  */
 24 
 25 /*
 26  * @test
 27  * @requires ((os.arch == "amd64" | os.arch == "x86_64") & sun.arch.data.model == "64") | os.arch == "aarch64"
 28  * @modules jdk.incubator.foreign/jdk.internal.foreign
 29  * @build NativeTestHelper CallGeneratorHelper TestUpcallHighArity
 30  *
 31  * @run testng/othervm/native
 32  *   --enable-native-access=ALL-UNNAMED
 33  *   TestUpcallHighArity
 34  */
 35 
 36 import jdk.incubator.foreign.Addressable;
 37 import jdk.incubator.foreign.CLinker;
 38 import jdk.incubator.foreign.FunctionDescriptor;
 39 import jdk.incubator.foreign.NativeSymbol;
 40 import jdk.incubator.foreign.SymbolLookup;
 41 import jdk.incubator.foreign.MemoryAddress;
 42 import jdk.incubator.foreign.MemoryLayout;
 43 import jdk.incubator.foreign.MemorySegment;
 44 import jdk.incubator.foreign.ResourceScope;
 45 import org.testng.annotations.DataProvider;
 46 import org.testng.annotations.Test;
 47 
 48 import java.lang.invoke.MethodHandle;
 49 import java.lang.invoke.MethodHandles;
 50 import java.lang.invoke.MethodType;
 51 import java.util.List;
 52 import java.util.concurrent.atomic.AtomicReference;
 53 

 54 import static org.testng.Assert.assertEquals;
 55 
 56 public class TestUpcallHighArity extends CallGeneratorHelper {
 57     static final MethodHandle MH_do_upcall;
 58     static final MethodHandle MH_passAndSave;
 59     static final CLinker LINKER = CLinker.systemCLinker();
 60 
 61     // struct S_PDI { void* p0; double p1; int p2; };
 62     static final MemoryLayout S_PDI_LAYOUT = MemoryLayout.structLayout(
 63         C_POINTER.withName("p0"),
 64         C_DOUBLE.withName("p1"),
 65         C_INT.withName("p2")
 66     );
 67 
 68     static {
 69         try {
 70             System.loadLibrary("TestUpcallHighArity");
 71             SymbolLookup lookup = SymbolLookup.loaderLookup();
 72             MH_do_upcall = LINKER.downcallHandle(
 73                 lookup.lookup("do_upcall").get(),
 74                     FunctionDescriptor.ofVoid(C_POINTER,





 75                     S_PDI_LAYOUT, C_INT, C_DOUBLE, C_POINTER,
 76                     S_PDI_LAYOUT, C_INT, C_DOUBLE, C_POINTER,
 77                     S_PDI_LAYOUT, C_INT, C_DOUBLE, C_POINTER,
 78                     S_PDI_LAYOUT, C_INT, C_DOUBLE, C_POINTER)
 79             );
 80             MH_passAndSave = MethodHandles.lookup().findStatic(TestUpcallHighArity.class, "passAndSave",
 81                     MethodType.methodType(void.class, Object[].class, AtomicReference.class));
 82         } catch (ReflectiveOperationException e) {
 83             throw new InternalError(e);
 84         }
 85     }
 86 
 87     static void passAndSave(Object[] o, AtomicReference<Object[]> ref) {
 88         for (int i = 0; i < o.length; i++) {
 89             if (o[i] instanceof MemorySegment) {
 90                 MemorySegment ms = (MemorySegment) o[i];
 91                 MemorySegment copy = MemorySegment.allocateNative(ms.byteSize(), ResourceScope.newImplicitScope());
 92                 copy.copyFrom(ms);
 93                 o[i] = copy;
 94             }
 95         }
 96         ref.set(o);
 97     }
 98 
 99     @Test(dataProvider = "args")
100     public void testUpcall(MethodHandle downcall, MethodType upcallType,
101                            FunctionDescriptor upcallDescriptor) throws Throwable {
102         AtomicReference<Object[]> capturedArgs = new AtomicReference<>();
103         MethodHandle target = MethodHandles.insertArguments(MH_passAndSave, 1, capturedArgs)
104                                          .asCollector(Object[].class, upcallType.parameterCount())
105                                          .asType(upcallType);
106         try (ResourceScope scope = ResourceScope.newConfinedScope()) {
107             NativeSymbol upcallStub = LINKER.upcallStub(target, upcallDescriptor, scope);
108             Object[] args = new Object[upcallType.parameterCount() + 1];
109             args[0] = upcallStub;
110             List<MemoryLayout> argLayouts = upcallDescriptor.argumentLayouts();
111             for (int i = 1; i < args.length; i++) {
112                 args[i] = makeArg(argLayouts.get(i - 1), null, false);
113             }
114 
115             downcall.invokeWithArguments(args);
116 
117             Object[] capturedArgsArr = capturedArgs.get();
118             for (int i = 0; i < capturedArgsArr.length; i++) {
119                 if (upcallType.parameterType(i) == MemorySegment.class) {
120                     assertStructEquals((MemorySegment) capturedArgsArr[i], (MemorySegment) args[i + 1], argLayouts.get(i));
121                 } else {
122                     assertEquals(capturedArgsArr[i], args[i + 1], "For index " + i);
123                 }
124             }
125         }
126     }
127 
128     @DataProvider
129     public static Object[][] args() {
130         return new Object[][]{
131             { MH_do_upcall,
132                 MethodType.methodType(void.class,
133                     MemorySegment.class, int.class, double.class, MemoryAddress.class,
134                     MemorySegment.class, int.class, double.class, MemoryAddress.class,
135                     MemorySegment.class, int.class, double.class, MemoryAddress.class,
136                     MemorySegment.class, int.class, double.class, MemoryAddress.class),
137                 FunctionDescriptor.ofVoid(
138                     S_PDI_LAYOUT, C_INT, C_DOUBLE, C_POINTER,
139                     S_PDI_LAYOUT, C_INT, C_DOUBLE, C_POINTER,
140                     S_PDI_LAYOUT, C_INT, C_DOUBLE, C_POINTER,
141                     S_PDI_LAYOUT, C_INT, C_DOUBLE, C_POINTER)
142             }
< prev index next >