1 /*
  2  * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 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 package org.openjdk.bench.jdk.incubator.foreign;
 24 
 25 import jdk.incubator.foreign.Addressable;
 26 import jdk.incubator.foreign.CLinker;
 27 import jdk.incubator.foreign.FunctionDescriptor;
 28 import jdk.incubator.foreign.MemoryAddress;
 29 import jdk.incubator.foreign.MemoryLayout;
 30 import jdk.incubator.foreign.MemorySegment;
 31 import jdk.incubator.foreign.ResourceScope;
 32 import jdk.incubator.foreign.SegmentAllocator;
 33 import jdk.incubator.foreign.SymbolLookup;
 34 
 35 import java.lang.invoke.MethodHandle;
 36 import java.lang.invoke.MethodType;
 37 
 38 import static java.lang.invoke.MethodHandles.insertArguments;
 39 import static jdk.incubator.foreign.CLinker.C_DOUBLE;
 40 import static jdk.incubator.foreign.CLinker.C_INT;
 41 import static jdk.incubator.foreign.CLinker.C_LONG_LONG;
 42 import static jdk.incubator.foreign.CLinker.C_POINTER;
 43 
 44 public class CallOverheadHelper {
 45 
 46     static final CLinker abi = CLinker.getInstance();
 47 
 48     static final MethodHandle func;
 49     static final MethodHandle func_v;
 50     static Addressable func_addr;
 51     static final MethodHandle identity;
 52     static final MethodHandle identity_v;
 53     static Addressable identity_addr;
 54     static final MethodHandle identity_struct;
 55     static final MethodHandle identity_struct_v;
 56     static Addressable identity_struct_addr;
 57     static final MethodHandle identity_memory_address;
 58     static final MethodHandle identity_memory_address_v;
 59     static Addressable identity_memory_address_addr;
 60     static final MethodHandle args1;
 61     static final MethodHandle args1_v;
 62     static Addressable args1_addr;
 63     static final MethodHandle args2;
 64     static final MethodHandle args2_v;
 65     static Addressable args2_addr;
 66     static final MethodHandle args3;
 67     static final MethodHandle args3_v;
 68     static Addressable args3_addr;
 69     static final MethodHandle args4;
 70     static final MethodHandle args4_v;
 71     static Addressable args4_addr;
 72     static final MethodHandle args5;
 73     static final MethodHandle args5_v;
 74     static Addressable args5_addr;
 75     static final MethodHandle args10;
 76     static final MethodHandle args10_v;
 77     static Addressable args10_addr;
 78     static final MethodHandle func_trivial;
 79     static final MethodHandle func_trivial_v;
 80     static final MethodHandle identity_trivial;
 81     static final MethodHandle identity_trivial_v;
 82 
 83     static final MemoryLayout POINT_LAYOUT = MemoryLayout.structLayout(
 84             C_LONG_LONG, C_LONG_LONG
 85     );
 86 
 87     static final MemorySegment point = MemorySegment.allocateNative(POINT_LAYOUT, ResourceScope.newImplicitScope());
 88 
 89     static final SegmentAllocator recycling_allocator = SegmentAllocator.ofSegment(MemorySegment.allocateNative(POINT_LAYOUT, ResourceScope.newImplicitScope()));
 90 
 91     static {
 92         System.loadLibrary("CallOverheadJNI");
 93 
 94         System.loadLibrary("CallOverhead");
 95         SymbolLookup lookup = SymbolLookup.loaderLookup();
 96         {
 97             func_addr = lookup.lookup("func").orElseThrow();
 98             MethodType mt = MethodType.methodType(void.class);
 99             FunctionDescriptor fd = FunctionDescriptor.ofVoid();
100             func_v = abi.downcallHandle(mt, fd);
101             func = insertArguments(func_v, 0, func_addr);
102             func_trivial_v = abi.downcallHandle(mt, fd.withAttribute(FunctionDescriptor.TRIVIAL_ATTRIBUTE_NAME, true));
103             func_trivial = insertArguments(func_trivial_v, 0, func_addr);
104         }
105         {
106             identity_addr = lookup.lookup("identity").orElseThrow();
107             MethodType mt = MethodType.methodType(int.class, int.class);
108             FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_INT);
109             identity_v = abi.downcallHandle(mt, fd);
110             identity = insertArguments(identity_v, 0, identity_addr);
111             identity_trivial_v = abi.downcallHandle(mt, fd.withAttribute(FunctionDescriptor.TRIVIAL_ATTRIBUTE_NAME, true));
112             identity_trivial = insertArguments(identity_trivial_v, 0, identity_addr);
113         }
114         identity_struct_addr = lookup.lookup("identity_struct").orElseThrow();
115         identity_struct_v = abi.downcallHandle(
116                 MethodType.methodType(MemorySegment.class, MemorySegment.class),
117                 FunctionDescriptor.of(POINT_LAYOUT, POINT_LAYOUT));
118         identity_struct = insertArguments(identity_struct_v, 0, identity_struct_addr);
119 
120         identity_memory_address_addr = lookup.lookup("identity_memory_address").orElseThrow();
121         identity_memory_address_v = abi.downcallHandle(
122                 MethodType.methodType(MemoryAddress.class, MemoryAddress.class),
123                 FunctionDescriptor.of(C_POINTER, C_POINTER));
124         identity_memory_address = insertArguments(identity_memory_address_v, 0, identity_memory_address_addr);
125 
126         args1_addr = lookup.lookup("args1").orElseThrow();
127         args1_v = abi.downcallHandle(
128                 MethodType.methodType(void.class, long.class),
129                 FunctionDescriptor.ofVoid(C_LONG_LONG));
130         args1 = insertArguments(args1_v, 0, args1_addr);
131 
132         args2_addr = lookup.lookup("args2").orElseThrow();
133         args2_v = abi.downcallHandle(
134                 MethodType.methodType(void.class, long.class, double.class),
135                 FunctionDescriptor.ofVoid(C_LONG_LONG, C_DOUBLE));
136         args2 = insertArguments(args2_v, 0, args2_addr);
137 
138         args3_addr = lookup.lookup("args3").orElseThrow();
139         args3_v = abi.downcallHandle(
140                 MethodType.methodType(void.class, long.class, double.class, long.class),
141                 FunctionDescriptor.ofVoid(C_LONG_LONG, C_DOUBLE, C_LONG_LONG));
142         args3 = insertArguments(args3_v, 0, args3_addr);
143 
144         args4_addr = lookup.lookup("args4").orElseThrow();
145         args4_v = abi.downcallHandle(
146                 MethodType.methodType(void.class, long.class, double.class, long.class, double.class),
147                 FunctionDescriptor.ofVoid(C_LONG_LONG, C_DOUBLE, C_LONG_LONG, C_DOUBLE));
148         args4 = insertArguments(args4_v, 0, args4_addr);
149 
150         args5_addr = lookup.lookup("args5").orElseThrow();
151         args5_v = abi.downcallHandle(
152                 MethodType.methodType(void.class, long.class, double.class, long.class, double.class, long.class),
153                 FunctionDescriptor.ofVoid(C_LONG_LONG, C_DOUBLE, C_LONG_LONG, C_DOUBLE, C_LONG_LONG));
154         args5 = insertArguments(args5_v, 0, args5_addr);
155 
156         args10_addr = lookup.lookup("args10").orElseThrow();
157         args10_v = abi.downcallHandle(
158                 MethodType.methodType(void.class, long.class, double.class, long.class, double.class, long.class,
159                                                   double.class, long.class, double.class, long.class, double.class),
160                 FunctionDescriptor.ofVoid(C_LONG_LONG, C_DOUBLE, C_LONG_LONG, C_DOUBLE, C_LONG_LONG,
161                                           C_DOUBLE, C_LONG_LONG, C_DOUBLE, C_LONG_LONG, C_DOUBLE));
162         args10 = insertArguments(args10_v, 0, args10_addr);
163     }
164 
165     static native void blank();
166     static native int identity(int x);
167 }