# HG changeset patch # User Matthias Grimmer # Date 1407247091 -7200 # Node ID dd8449afc086b96cf1e2a1754ddf5c74c0905469 # Parent 7e8ecfe7d2e57080db3dee0359f1b50ae70c7b99 GNFI: move GNFI interfaces to oracle.nfi - interface does not depend on graal diff -r 7e8ecfe7d2e5 -r dd8449afc086 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionHandle.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionHandle.java Tue Aug 05 12:34:55 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.api.code; - -/** - * A handle that can be used to {@linkplain #call(Object[]) call} a native function. - */ -public interface NativeFunctionHandle { - - /** - * Calls the native function. - *

- * The caller is responsible for ensuring {@code args} comply with the platform ABI (e.g. Unix AMD64 ABI). If the library - * function has struct parameters, the fields of the struct must be passed as individual - * arguments. - * - * @param args the arguments that will be passed to the native function - * @return boxed return value of the function call - */ - Object call(Object... args); - - /** - * Returns the installed code of the call stub for the native function call. - * - * @return the installed code of the native call stub - */ - InstalledCode getCallStub(); -} diff -r 7e8ecfe7d2e5 -r dd8449afc086 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionInterface.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionInterface.java Tue Aug 05 12:34:55 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.api.code; - -/** - * Interface to get a {@linkplain NativeFunctionHandle handle} or {@linkplain NativeFunctionPointer - * pointer} to a native function or a {@linkplain NativeLibraryHandle handle} to an open native - * library. - */ -public interface NativeFunctionInterface { - - /** - * Resolves and returns a handle to an open native library. This method will open the library - * only if it is not already open. - * - * @param libPath the absolute path to the library - * @return the resolved library handle - * @throws UnsatisfiedLinkError if the library could not be found or opened - */ - NativeLibraryHandle getLibraryHandle(String libPath); - - /** - * Determines if the underlying platform/runtime supports the notion of a default library search - * path. For example, on *nix systems, this is typically defined by the {@code LD_LIBRARY_PATH} - * environment variable. - */ - boolean isDefaultLibrarySearchSupported(); - - /** - * Resolves the function pointer {@code NativeFunctionPointer} of a native function. - * - * @param libraries the ordered list of libraries to search for the function - * @param name the name of the function to be resolved - * @return a pointer to the native function - * @throws UnsatisfiedLinkError if the function could not be resolved - */ - NativeFunctionPointer getFunctionPointer(NativeLibraryHandle[] libraries, String name); - - /** - * Resolves a function name to a {@linkplain NativeFunctionHandle handle} that can be called - * with a given signature. The signature contains the types of the arguments that will be passed - * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}. - * - * @param library the handle to a resolved library - * @param name the name of the function to be resolved - * @param returnType the type of the return value - * @param argumentTypes the types of the arguments - * @return the function handle of the native function - * @throws UnsatisfiedLinkError if the function handle could not be resolved - */ - NativeFunctionHandle getFunctionHandle(NativeLibraryHandle library, String name, Class returnType, Class... argumentTypes); - - /** - * Resolves a function pointer to a {@linkplain NativeFunctionHandle handle} that can be called - * with a given signature. The signature contains the types of the arguments that will be passed - * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}. - * - * @param functionPointer a function pointer - * @param returnType the type of the return value - * @param argumentTypes the types of the arguments - * @return the function handle of the native function - * @throws UnsatisfiedLinkError the function handle could not be created - */ - NativeFunctionHandle getFunctionHandle(NativeFunctionPointer functionPointer, Class returnType, Class... argumentTypes); - - /** - * Resolves a function name to a {@linkplain NativeFunctionHandle handle} that can be called - * with a given signature. The signature contains the types of the arguments that will be passed - * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}. - * - * @param libraries the ordered list of libraries to search for the function - * @param name the name of the function to be resolved - * @param returnType the type of the return value - * @param argumentTypes the types of the arguments - * @return the function handle of the native function - * @throws UnsatisfiedLinkError if the function handle could not be created - */ - NativeFunctionHandle getFunctionHandle(NativeLibraryHandle[] libraries, String name, Class returnType, Class... argumentTypes); - - /** - * Resolves a function name to a {@linkplain NativeFunctionHandle handle} that can be called - * with a given signature. The signature contains the types of the arguments that will be passed - * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}. - * - * @param name the name of the function to be resolved - * @param returnType the type of the return value - * @param argumentTypes the types of the arguments - * @return the function handle of the native function - * @throws UnsatisfiedLinkError if default library searching is not - * {@linkplain #isDefaultLibrarySearchSupported() supported} or if the function - * could not be resolved - */ - NativeFunctionHandle getFunctionHandle(String name, Class returnType, Class... argumentTypes); - - /** - * Creates a {@link NativeFunctionPointer} from a raw value. - * - * @param rawValue raw function pointer - * @return {@code NativeFunctionPointer} for {@code rawValue} - */ - NativeFunctionPointer getNativeFunctionPointerFromRawValue(long rawValue); -} diff -r 7e8ecfe7d2e5 -r dd8449afc086 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionPointer.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionPointer.java Tue Aug 05 12:34:55 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.api.code; - -/** - * An opaque representation of a native function pointer. - *

- * Use {@code NativeFunctionInterface#getFunctionHandle(NativeFunctionPointer, Class, Class...)} to - * get a handle enabling the native function to be {@linkplain NativeFunctionHandle#call(Object...) - * called}. - */ -public interface NativeFunctionPointer { - - /** - * Returns the name of the function. - * - * @return name of the function - */ - String getName(); - -} diff -r 7e8ecfe7d2e5 -r dd8449afc086 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeLibraryHandle.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeLibraryHandle.java Tue Aug 05 12:34:55 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.api.code; - -/** - * An opaque representation of a native library handle. A handle is obtained via - * {@link NativeFunctionInterface#getLibraryHandle(String)}. A handle is used to resolve a string to - * a {@linkplain NativeFunctionInterface#getFunctionHandle(String, Class, Class...) handle} or - * {@linkplain NativeFunctionInterface#getFunctionPointer(NativeLibraryHandle[], String) pointer}. - */ -public interface NativeLibraryHandle { - /** - * Gets a name for this library. This may be the path for the file from which the library was - * loaded. - */ - String getName(); -} diff -r 7e8ecfe7d2e5 -r dd8449afc086 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/nfi/NativeFunctionInterfaceTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/nfi/NativeFunctionInterfaceTest.java Tue Aug 05 12:34:55 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,401 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.compiler.test.nfi; - -import static com.oracle.graal.compiler.common.UnsafeAccess.*; -import static java.io.File.*; -import static java.lang.System.*; -import static org.junit.Assert.*; -import static org.junit.Assume.*; - -import java.io.*; -import java.util.*; - -import org.junit.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.runtime.*; -import com.oracle.graal.compiler.target.*; -import com.oracle.graal.runtime.*; - -@Ignore -public class NativeFunctionInterfaceTest { - - public final NativeFunctionInterface nfi; - - public NativeFunctionInterfaceTest() { - RuntimeProvider runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class); - Assume.assumeTrue(runtimeProvider.getHostBackend() instanceof HostBackend); - nfi = ((HostBackend) runtimeProvider.getHostBackend()).getNativeFunctionInterface(); - } - - private List allocations = new ArrayList<>(); - - protected long malloc(int length) { - long buf = unsafe.allocateMemory(length); - allocations.add(buf); - return buf; - } - - @After - public void cleanup() { - for (long buf : allocations) { - unsafe.freeMemory(buf); - } - } - - private static void assertCStringEquals(long cString, String s) { - for (int i = 0; i < s.length(); i++) { - assertEquals(unsafe.getByte(cString + i) & 0xFF, (byte) s.charAt(i)); - } - assertEquals(unsafe.getByte(cString + s.length()) & 0xFF, (byte) '\0'); - } - - @Test - public void test1() { - assumeTrue(nfi.isDefaultLibrarySearchSupported()); - NativeFunctionHandle malloc = nfi.getFunctionHandle("malloc", long.class, int.class); - NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class); - NativeFunctionHandle free = nfi.getFunctionHandle("free", void.class, long.class); - - String string = "GRAAL"; - int bufferLength = string.length() + 1; - long cString = (long) malloc.call(bufferLength); - writeCString(string, cString); - - long cStringCopy = malloc(bufferLength); - int result = (int) snprintf.call(cStringCopy, bufferLength, cString); - Assert.assertEquals(string.length(), result); - assertCStringEquals(cString, string); - assertCStringEquals(cStringCopy, string); - - free.call(cString); - } - - @Test - public void test2() { - assumeTrue(nfi.isDefaultLibrarySearchSupported()); - String formatString = "AB %f%f"; - long formatCString = writeCString("AB %f%f", malloc(formatString.length() + 1)); - - String referenceString = "AB 1.0000001.000000"; - int bufferLength = referenceString.length() + 1; - long buffer = malloc(bufferLength); - - NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, double.class, double.class); - int result = (int) snprintf.call(buffer, bufferLength, formatCString, 1.0D, 1.0D); - - assertCStringEquals(buffer, referenceString); - Assert.assertEquals(referenceString.length(), result); - } - - @Test - public void test3() { - assumeTrue(nfi.isDefaultLibrarySearchSupported()); - String format = "%i%i%i%i%i%i%i%i%i%i%i%i"; - long formatCString = writeCString(format, malloc(format.length() + 1)); - String referenceString = "01234567891011"; - - int bufferLength = referenceString.length() + 1; - long buffer = malloc(bufferLength); - - NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class, - int.class, int.class, int.class, int.class, int.class); - - int result = (int) snprintf.call(buffer, bufferLength, formatCString, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); - assertCStringEquals(buffer, referenceString); - Assert.assertEquals(referenceString.length(), result); - } - - @Test - public void test4() { - assumeTrue(nfi.isDefaultLibrarySearchSupported()); - long str = malloc(49); - int[] val = new int[12]; - for (int i = 0; i < 12; i++) { - unsafe.putByte(str + 2 * i, (byte) '%'); - unsafe.putByte(str + 2 * i + 1, (byte) 'i'); - val[i] = i; - } - double[] dval = new double[12]; - for (int i = 12; i < 24; i++) { - unsafe.putByte(str + 2 * i, (byte) '%'); - unsafe.putByte(str + 2 * i + 1, (byte) 'f'); - dval[i - 12] = i + 0.5; - } - unsafe.putByte(str + 48, (byte) '\0'); - - String referenceString = "0123456789101112.50000013.50000014.50000015.50000016.50000017.50000018.50000019.50000020.500000" + "21.50000022.50000023.500000"; - int bufferLength = referenceString.length() + 1; - - long buffer = malloc(bufferLength); - - NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class, - int.class, int.class, int.class, int.class, int.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class, - double.class, double.class, double.class, double.class); - - int result = (int) snprintf.call(buffer, bufferLength, str, val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8], val[9], val[10], val[11], dval[0], dval[1], dval[2], - dval[3], dval[4], dval[5], dval[6], dval[7], dval[8], dval[9], dval[10], dval[11]); - assertCStringEquals(buffer, referenceString); - Assert.assertEquals(referenceString.length(), result); - } - - @Test - public void test5() { - assumeTrue(nfi.isDefaultLibrarySearchSupported()); - long str = malloc(73); - int[] val = new int[12]; - for (int i = 0; i < 12; i++) { - unsafe.putByte(str + 2 * i, (byte) '%'); - unsafe.putByte(str + 2 * i + 1, (byte) 'i'); - val[i] = i; - } - double[] dval = new double[12]; - for (int i = 12; i < 24; i++) { - unsafe.putByte(str + 2 * i, (byte) '%'); - unsafe.putByte(str + 2 * i + 1, (byte) 'f'); - dval[i - 12] = i + 0.5; - } - char[] cval = new char[12]; - for (int i = 24; i < 36; i++) { - unsafe.putByte(str + 2 * i, (byte) '%'); - unsafe.putByte(str + 2 * i + 1, (byte) 'c'); - cval[i - 24] = (char) ('a' + (i - 24)); - } - unsafe.putByte(str + 72, (byte) '\0'); - - String referenceString = "0123456789101112.50000013.50000014.50000015.50000016.50000017.50000018.50000019.50000020.50000021.50000022.50000023.500000abcdefghijkl"; - int bufferLength = referenceString.length() + 1; - - long buffer = malloc(bufferLength); - - NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class, - int.class, int.class, int.class, int.class, int.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class, - double.class, double.class, double.class, double.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, - char.class, char.class); - - int result = (int) snprintf.call(buffer, bufferLength, str, val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8], val[9], val[10], val[11], dval[0], dval[1], dval[2], - dval[3], dval[4], dval[5], dval[6], dval[7], dval[8], dval[9], dval[10], dval[11], cval[0], cval[1], cval[2], cval[3], cval[4], cval[5], cval[6], cval[7], cval[8], cval[9], - cval[10], cval[11]); - assertCStringEquals(buffer, referenceString); - Assert.assertEquals(referenceString.length(), result); - } - - @Test - public void test6() { - assumeTrue(nfi.isDefaultLibrarySearchSupported()); - NativeFunctionHandle handle = nfi.getFunctionHandle("pow", double.class, double.class, double.class); - double result = (double) handle.call(3D, 5.5D); - assertEquals(Math.pow(3D, 5.5D), result, 0); - } - - @Test - public void test7() { - assumeTrue(nfi.isDefaultLibrarySearchSupported()); - double result = 0; - NativeFunctionHandle handle = nfi.getFunctionHandle("pow", double.class, double.class, double.class); - for (int i = 0; i < 10; i++) { - result = (double) handle.call(3D, 5.5D); - } - assertEquals(Math.pow(3D, 5.5D), result, 0); - } - - @Test - public void test8() { - assumeTrue(nfi.isDefaultLibrarySearchSupported()); - String formatString = "AB %f%f"; - long formatCString = writeCString("AB %f%f", malloc(formatString.length() + 1)); - - String expected = "AB 1.0000001.000000"; - int bufferLength = expected.length() + 1; - byte[] buffer = new byte[bufferLength]; - - NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, byte[].class, int.class, long.class, double.class, double.class); - int result = (int) snprintf.call(buffer, bufferLength, formatCString, 1.0D, 1.0D); - - // trim trailing '\0' - String actual = new String(buffer, 0, expected.length()); - - assertEquals(expected, actual); - Assert.assertEquals(expected.length(), result); - } - - private static double[] someDoubles = {2454.346D, 98789.22D, Double.MAX_VALUE, Double.MIN_NORMAL, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY}; - - @Test - public void test9() { - assumeTrue(nfi.isDefaultLibrarySearchSupported()); - double[] src = someDoubles.clone(); - double[] dst = new double[src.length]; - - NativeFunctionHandle memcpy = nfi.getFunctionHandle("memcpy", void.class, double[].class, double[].class, int.class); - memcpy.call(dst, src, src.length * (Double.SIZE / Byte.SIZE)); - - assertArrayEquals(src, dst, 0.0D); - } - - private static String getVMName() { - String vmName = System.getProperty("java.vm.name").toLowerCase(); - String vm = null; - if (vmName.contains("server")) { - vm = "server"; - } else if (vmName.contains("graal")) { - vm = "graal"; - } else if (vmName.contains("client")) { - vm = "client"; - } - - Assume.assumeTrue(vm != null); - return vm; - } - - private static String getVMLibPath() { - String vm = getVMName(); - - String path = String.format("%s%c%s%c%s", getProperty("sun.boot.library.path"), separatorChar, vm, separatorChar, mapLibraryName("jvm")); - // Only continue if the library file exists - Assume.assumeTrue(new File(path).exists()); - return path; - } - - @Test - public void test10() { - NativeLibraryHandle vmLib = nfi.getLibraryHandle(getVMLibPath()); - NativeFunctionHandle currentTimeMillis = nfi.getFunctionHandle(vmLib, "JVM_CurrentTimeMillis", long.class); - long time1 = (long) currentTimeMillis.call(); - long time2 = System.currentTimeMillis(); - long delta = time2 - time1; - - // The 2 calls to get the current time should not differ by more than - // 100 milliseconds at the very most - assertTrue(String.valueOf(delta), delta >= 0); - assertTrue(String.valueOf(delta), delta < 100); - } - - private static String getJavaLibPath() { - String path = String.format("%s%c%s", getProperty("sun.boot.library.path"), separatorChar, mapLibraryName("java")); - Assume.assumeTrue(new File(path).exists()); - return path; - } - - private static void testD2L(NativeFunctionHandle d2l) { - for (double d : someDoubles) { - long expected = Double.doubleToRawLongBits(d); - long actual = (long) d2l.call(0L, 0L, d); - assertEquals(Double.toString(d), expected, actual); - } - } - - @Test - public void test11() { - NativeLibraryHandle javaLib = nfi.getLibraryHandle(getJavaLibPath()); - NativeFunctionHandle d2l = nfi.getFunctionHandle(javaLib, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class); - testD2L(d2l); - } - - @Test - public void test12() { - NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())}; - NativeFunctionHandle d2l = nfi.getFunctionHandle(libs, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class); - testD2L(d2l); - - NativeLibraryHandle[] libsReveresed = {libs[1], libs[0]}; - d2l = nfi.getFunctionHandle(libsReveresed, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class); - testD2L(d2l); - } - - @Test - public void test13() { - NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())}; - NativeFunctionPointer functionPointer = nfi.getFunctionPointer(libs, "Java_java_lang_Double_doubleToRawLongBits"); - NativeFunctionHandle d2l = nfi.getFunctionHandle(functionPointer, long.class, long.class, long.class, double.class); - testD2L(d2l); - - NativeLibraryHandle[] libsReveresed = {libs[1], libs[0]}; - functionPointer = nfi.getFunctionPointer(libsReveresed, "Java_java_lang_Double_doubleToRawLongBits"); - d2l = nfi.getFunctionHandle(functionPointer, long.class, long.class, long.class, double.class); - testD2L(d2l); - } - - @Test - public void test14() { - if (!nfi.isDefaultLibrarySearchSupported()) { - try { - nfi.getFunctionHandle("snprintf", int.class); - fail(); - } catch (UnsatisfiedLinkError e) { - } - } - } - - @Test - public void test15() { - assumeTrue(nfi.isDefaultLibrarySearchSupported()); - try { - nfi.getFunctionHandle("an invalid function name", int.class); - fail(); - } catch (UnsatisfiedLinkError e) { - } - } - - @Test - public void test16() { - NativeLibraryHandle javaLib = nfi.getLibraryHandle(getJavaLibPath()); - try { - - nfi.getFunctionHandle(javaLib, "an invalid function name", int.class); - fail(); - } catch (UnsatisfiedLinkError e) { - } - } - - @Test - public void test17() { - NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())}; - try { - nfi.getFunctionPointer(libs, "an invalid function name"); - fail(); - } catch (UnsatisfiedLinkError e) { - } - } - - @Test - public void test18() { - NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())}; - try { - nfi.getFunctionHandle(libs, "an invalid function name", int.class); - fail(); - } catch (UnsatisfiedLinkError e) { - } - } - - @Test - public void test19() { - try { - nfi.getLibraryHandle("an invalid library name"); - fail(); - } catch (UnsatisfiedLinkError e) { - } - } - -} diff -r 7e8ecfe7d2e5 -r dd8449afc086 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/HostBackend.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/HostBackend.java Tue Aug 05 12:34:55 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.compiler.target; - -import com.oracle.graal.api.code.*; - -/** - * Common functionality of host backends. - */ -public interface HostBackend { - NativeFunctionInterface getNativeFunctionInterface(); -} diff -r 7e8ecfe7d2e5 -r dd8449afc086 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Tue Aug 05 12:34:55 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Tue Aug 05 15:58:11 2014 +0200 @@ -49,6 +49,7 @@ import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.nfi.api.*; /** * HotSpot AMD64 specific backend. @@ -321,15 +322,16 @@ } } - @Override - public NativeFunctionInterface getNativeFunctionInterface() { - HotSpotVMConfig config = getRuntime().getConfig(); + // used by native code, don't remove! + public static NativeFunctionInterface createNativeFunctionInterface() { + HotSpotVMConfig config = HotSpotGraalRuntime.runtime().getConfig(); RawNativeCallNodeFactory factory = new RawNativeCallNodeFactory() { public FixedWithNextNode createRawCallNode(Kind returnType, Constant functionPointer, ValueNode... args) { return new AMD64RawNativeCallNode(returnType, functionPointer, args); } }; - return new HotSpotNativeFunctionInterface(getProviders(), factory, this, config.dllLoad, config.dllLookup, config.rtldDefault); + Backend backend = HotSpotGraalRuntime.runtime().getBackend(AMD64.class); + return new HotSpotNativeFunctionInterface(HotSpotGraalRuntime.runtime().getHostProviders(), factory, backend, config.dllLoad, config.dllLookup, config.rtldDefault); } } diff -r 7e8ecfe7d2e5 -r dd8449afc086 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Tue Aug 05 12:34:55 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Tue Aug 05 15:58:11 2014 +0200 @@ -44,7 +44,6 @@ import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.RestoreWindow; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx; -import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId; import com.oracle.graal.hotspot.meta.*; @@ -247,9 +246,4 @@ } } - @Override - public NativeFunctionInterface getNativeFunctionInterface() { - throw GraalInternalError.unimplemented("No NativeFunctionInterface of SPARC"); - } - } diff -r 7e8ecfe7d2e5 -r dd8449afc086 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java Tue Aug 05 12:34:55 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java Tue Aug 05 15:58:11 2014 +0200 @@ -27,7 +27,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; -import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.hotspot.meta.*; @@ -37,7 +36,7 @@ /** * Common functionality of HotSpot host backends. */ -public abstract class HotSpotHostBackend extends HotSpotBackend implements HostBackend { +public abstract class HotSpotHostBackend extends HotSpotBackend { /** * Descriptor for {@link DeoptimizationStub#deoptimizationHandler}. diff -r 7e8ecfe7d2e5 -r dd8449afc086 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionHandle.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionHandle.java Tue Aug 05 12:34:55 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionHandle.java Tue Aug 05 15:58:11 2014 +0200 @@ -29,6 +29,7 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; +import com.oracle.nfi.api.*; public class HotSpotNativeFunctionHandle implements NativeFunctionHandle { @@ -87,10 +88,6 @@ return true; } - public InstalledCode getCallStub() { - return code; - } - @Override public String toString() { return name + Arrays.toString(argumentTypes); diff -r 7e8ecfe7d2e5 -r dd8449afc086 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java Tue Aug 05 12:34:55 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java Tue Aug 05 15:58:11 2014 +0200 @@ -40,6 +40,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.tiers.*; +import com.oracle.nfi.api.*; public class HotSpotNativeFunctionInterface implements NativeFunctionInterface { diff -r 7e8ecfe7d2e5 -r dd8449afc086 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionPointer.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionPointer.java Tue Aug 05 12:34:55 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionPointer.java Tue Aug 05 15:58:11 2014 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot.nfi; -import com.oracle.graal.api.code.*; +import com.oracle.nfi.api.*; public class HotSpotNativeFunctionPointer implements NativeFunctionPointer { @@ -41,7 +41,7 @@ return name; } - public long getValue() { + public long getRawValue() { return value; } diff -r 7e8ecfe7d2e5 -r dd8449afc086 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeLibraryHandle.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeLibraryHandle.java Tue Aug 05 12:34:55 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeLibraryHandle.java Tue Aug 05 15:58:11 2014 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot.nfi; -import com.oracle.graal.api.code.*; +import com.oracle.nfi.api.*; public class HotSpotNativeLibraryHandle implements NativeLibraryHandle { diff -r 7e8ecfe7d2e5 -r dd8449afc086 graal/com.oracle.nfi.test/test/com/oracle/nfi/test/NativeFunctionInterfaceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.nfi.test/test/com/oracle/nfi/test/NativeFunctionInterfaceTest.java Tue Aug 05 15:58:11 2014 +0200 @@ -0,0 +1,397 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.nfi.test; + +import static com.oracle.graal.compiler.common.UnsafeAccess.*; +import static java.io.File.*; +import static java.lang.System.*; +import static org.junit.Assert.*; +import static org.junit.Assume.*; + +import java.io.*; +import java.util.*; + +import org.junit.*; + +import com.oracle.nfi.*; +import com.oracle.nfi.api.*; + +@Ignore +public class NativeFunctionInterfaceTest { + + public final NativeFunctionInterface nfi; + + public NativeFunctionInterfaceTest() { + nfi = NativeFunctionInterfaceRuntime.getNativeFunctionInterface(); + } + + private List allocations = new ArrayList<>(); + + protected long malloc(int length) { + long buf = unsafe.allocateMemory(length); + allocations.add(buf); + return buf; + } + + @After + public void cleanup() { + for (long buf : allocations) { + unsafe.freeMemory(buf); + } + } + + private static void assertCStringEquals(long cString, String s) { + for (int i = 0; i < s.length(); i++) { + assertEquals(unsafe.getByte(cString + i) & 0xFF, (byte) s.charAt(i)); + } + assertEquals(unsafe.getByte(cString + s.length()) & 0xFF, (byte) '\0'); + } + + @Test + public void test1() { + assumeTrue(nfi.isDefaultLibrarySearchSupported()); + NativeFunctionHandle malloc = nfi.getFunctionHandle("malloc", long.class, int.class); + NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class); + NativeFunctionHandle free = nfi.getFunctionHandle("free", void.class, long.class); + + String string = "GRAAL"; + int bufferLength = string.length() + 1; + long cString = (long) malloc.call(bufferLength); + writeCString(string, cString); + + long cStringCopy = malloc(bufferLength); + int result = (int) snprintf.call(cStringCopy, bufferLength, cString); + Assert.assertEquals(string.length(), result); + assertCStringEquals(cString, string); + assertCStringEquals(cStringCopy, string); + + free.call(cString); + } + + @Test + public void test2() { + assumeTrue(nfi.isDefaultLibrarySearchSupported()); + String formatString = "AB %f%f"; + long formatCString = writeCString("AB %f%f", malloc(formatString.length() + 1)); + + String referenceString = "AB 1.0000001.000000"; + int bufferLength = referenceString.length() + 1; + long buffer = malloc(bufferLength); + + NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, double.class, double.class); + int result = (int) snprintf.call(buffer, bufferLength, formatCString, 1.0D, 1.0D); + + assertCStringEquals(buffer, referenceString); + Assert.assertEquals(referenceString.length(), result); + } + + @Test + public void test3() { + assumeTrue(nfi.isDefaultLibrarySearchSupported()); + String format = "%i%i%i%i%i%i%i%i%i%i%i%i"; + long formatCString = writeCString(format, malloc(format.length() + 1)); + String referenceString = "01234567891011"; + + int bufferLength = referenceString.length() + 1; + long buffer = malloc(bufferLength); + + NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class, + int.class, int.class, int.class, int.class, int.class); + + int result = (int) snprintf.call(buffer, bufferLength, formatCString, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); + assertCStringEquals(buffer, referenceString); + Assert.assertEquals(referenceString.length(), result); + } + + @Test + public void test4() { + assumeTrue(nfi.isDefaultLibrarySearchSupported()); + long str = malloc(49); + int[] val = new int[12]; + for (int i = 0; i < 12; i++) { + unsafe.putByte(str + 2 * i, (byte) '%'); + unsafe.putByte(str + 2 * i + 1, (byte) 'i'); + val[i] = i; + } + double[] dval = new double[12]; + for (int i = 12; i < 24; i++) { + unsafe.putByte(str + 2 * i, (byte) '%'); + unsafe.putByte(str + 2 * i + 1, (byte) 'f'); + dval[i - 12] = i + 0.5; + } + unsafe.putByte(str + 48, (byte) '\0'); + + String referenceString = "0123456789101112.50000013.50000014.50000015.50000016.50000017.50000018.50000019.50000020.500000" + "21.50000022.50000023.500000"; + int bufferLength = referenceString.length() + 1; + + long buffer = malloc(bufferLength); + + NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class, + int.class, int.class, int.class, int.class, int.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class, + double.class, double.class, double.class, double.class); + + int result = (int) snprintf.call(buffer, bufferLength, str, val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8], val[9], val[10], val[11], dval[0], dval[1], dval[2], + dval[3], dval[4], dval[5], dval[6], dval[7], dval[8], dval[9], dval[10], dval[11]); + assertCStringEquals(buffer, referenceString); + Assert.assertEquals(referenceString.length(), result); + } + + @Test + public void test5() { + assumeTrue(nfi.isDefaultLibrarySearchSupported()); + long str = malloc(73); + int[] val = new int[12]; + for (int i = 0; i < 12; i++) { + unsafe.putByte(str + 2 * i, (byte) '%'); + unsafe.putByte(str + 2 * i + 1, (byte) 'i'); + val[i] = i; + } + double[] dval = new double[12]; + for (int i = 12; i < 24; i++) { + unsafe.putByte(str + 2 * i, (byte) '%'); + unsafe.putByte(str + 2 * i + 1, (byte) 'f'); + dval[i - 12] = i + 0.5; + } + char[] cval = new char[12]; + for (int i = 24; i < 36; i++) { + unsafe.putByte(str + 2 * i, (byte) '%'); + unsafe.putByte(str + 2 * i + 1, (byte) 'c'); + cval[i - 24] = (char) ('a' + (i - 24)); + } + unsafe.putByte(str + 72, (byte) '\0'); + + String referenceString = "0123456789101112.50000013.50000014.50000015.50000016.50000017.50000018.50000019.50000020.50000021.50000022.50000023.500000abcdefghijkl"; + int bufferLength = referenceString.length() + 1; + + long buffer = malloc(bufferLength); + + NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class, + int.class, int.class, int.class, int.class, int.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class, + double.class, double.class, double.class, double.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, + char.class, char.class); + + int result = (int) snprintf.call(buffer, bufferLength, str, val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8], val[9], val[10], val[11], dval[0], dval[1], dval[2], + dval[3], dval[4], dval[5], dval[6], dval[7], dval[8], dval[9], dval[10], dval[11], cval[0], cval[1], cval[2], cval[3], cval[4], cval[5], cval[6], cval[7], cval[8], cval[9], + cval[10], cval[11]); + assertCStringEquals(buffer, referenceString); + Assert.assertEquals(referenceString.length(), result); + } + + @Test + public void test6() { + assumeTrue(nfi.isDefaultLibrarySearchSupported()); + NativeFunctionHandle handle = nfi.getFunctionHandle("pow", double.class, double.class, double.class); + double result = (double) handle.call(3D, 5.5D); + assertEquals(Math.pow(3D, 5.5D), result, 0); + } + + @Test + public void test7() { + assumeTrue(nfi.isDefaultLibrarySearchSupported()); + double result = 0; + NativeFunctionHandle handle = nfi.getFunctionHandle("pow", double.class, double.class, double.class); + for (int i = 0; i < 10; i++) { + result = (double) handle.call(3D, 5.5D); + } + assertEquals(Math.pow(3D, 5.5D), result, 0); + } + + @Test + public void test8() { + assumeTrue(nfi.isDefaultLibrarySearchSupported()); + String formatString = "AB %f%f"; + long formatCString = writeCString("AB %f%f", malloc(formatString.length() + 1)); + + String expected = "AB 1.0000001.000000"; + int bufferLength = expected.length() + 1; + byte[] buffer = new byte[bufferLength]; + + NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, byte[].class, int.class, long.class, double.class, double.class); + int result = (int) snprintf.call(buffer, bufferLength, formatCString, 1.0D, 1.0D); + + // trim trailing '\0' + String actual = new String(buffer, 0, expected.length()); + + assertEquals(expected, actual); + Assert.assertEquals(expected.length(), result); + } + + private static double[] someDoubles = {2454.346D, 98789.22D, Double.MAX_VALUE, Double.MIN_NORMAL, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY}; + + @Test + public void test9() { + assumeTrue(nfi.isDefaultLibrarySearchSupported()); + double[] src = someDoubles.clone(); + double[] dst = new double[src.length]; + + NativeFunctionHandle memcpy = nfi.getFunctionHandle("memcpy", void.class, double[].class, double[].class, int.class); + memcpy.call(dst, src, src.length * (Double.SIZE / Byte.SIZE)); + + assertArrayEquals(src, dst, 0.0D); + } + + private static String getVMName() { + String vmName = System.getProperty("java.vm.name").toLowerCase(); + String vm = null; + if (vmName.contains("server")) { + vm = "server"; + } else if (vmName.contains("graal")) { + vm = "graal"; + } else if (vmName.contains("client")) { + vm = "client"; + } + + Assume.assumeTrue(vm != null); + return vm; + } + + private static String getVMLibPath() { + String vm = getVMName(); + + String path = String.format("%s%c%s%c%s", getProperty("sun.boot.library.path"), separatorChar, vm, separatorChar, mapLibraryName("jvm")); + // Only continue if the library file exists + Assume.assumeTrue(new File(path).exists()); + return path; + } + + @Test + public void test10() { + NativeLibraryHandle vmLib = nfi.getLibraryHandle(getVMLibPath()); + NativeFunctionHandle currentTimeMillis = nfi.getFunctionHandle(vmLib, "JVM_CurrentTimeMillis", long.class); + long time1 = (long) currentTimeMillis.call(); + long time2 = System.currentTimeMillis(); + long delta = time2 - time1; + + // The 2 calls to get the current time should not differ by more than + // 100 milliseconds at the very most + assertTrue(String.valueOf(delta), delta >= 0); + assertTrue(String.valueOf(delta), delta < 100); + } + + private static String getJavaLibPath() { + String path = String.format("%s%c%s", getProperty("sun.boot.library.path"), separatorChar, mapLibraryName("java")); + Assume.assumeTrue(new File(path).exists()); + return path; + } + + private static void testD2L(NativeFunctionHandle d2l) { + for (double d : someDoubles) { + long expected = Double.doubleToRawLongBits(d); + long actual = (long) d2l.call(0L, 0L, d); + assertEquals(Double.toString(d), expected, actual); + } + } + + @Test + public void test11() { + NativeLibraryHandle javaLib = nfi.getLibraryHandle(getJavaLibPath()); + NativeFunctionHandle d2l = nfi.getFunctionHandle(javaLib, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class); + testD2L(d2l); + } + + @Test + public void test12() { + NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())}; + NativeFunctionHandle d2l = nfi.getFunctionHandle(libs, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class); + testD2L(d2l); + + NativeLibraryHandle[] libsReveresed = {libs[1], libs[0]}; + d2l = nfi.getFunctionHandle(libsReveresed, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class); + testD2L(d2l); + } + + @Test + public void test13() { + NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())}; + NativeFunctionPointer functionPointer = nfi.getFunctionPointer(libs, "Java_java_lang_Double_doubleToRawLongBits"); + NativeFunctionHandle d2l = nfi.getFunctionHandle(functionPointer, long.class, long.class, long.class, double.class); + testD2L(d2l); + + NativeLibraryHandle[] libsReveresed = {libs[1], libs[0]}; + functionPointer = nfi.getFunctionPointer(libsReveresed, "Java_java_lang_Double_doubleToRawLongBits"); + d2l = nfi.getFunctionHandle(functionPointer, long.class, long.class, long.class, double.class); + testD2L(d2l); + } + + @Test + public void test14() { + if (!nfi.isDefaultLibrarySearchSupported()) { + try { + nfi.getFunctionHandle("snprintf", int.class); + fail(); + } catch (UnsatisfiedLinkError e) { + } + } + } + + @Test + public void test15() { + assumeTrue(nfi.isDefaultLibrarySearchSupported()); + try { + nfi.getFunctionHandle("an invalid function name", int.class); + fail(); + } catch (UnsatisfiedLinkError e) { + } + } + + @Test + public void test16() { + NativeLibraryHandle javaLib = nfi.getLibraryHandle(getJavaLibPath()); + try { + + nfi.getFunctionHandle(javaLib, "an invalid function name", int.class); + fail(); + } catch (UnsatisfiedLinkError e) { + } + } + + @Test + public void test17() { + NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())}; + try { + nfi.getFunctionPointer(libs, "an invalid function name"); + fail(); + } catch (UnsatisfiedLinkError e) { + } + } + + @Test + public void test18() { + NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())}; + try { + nfi.getFunctionHandle(libs, "an invalid function name", int.class); + fail(); + } catch (UnsatisfiedLinkError e) { + } + } + + @Test + public void test19() { + try { + nfi.getLibraryHandle("an invalid library name"); + fail(); + } catch (UnsatisfiedLinkError e) { + } + } + +} diff -r 7e8ecfe7d2e5 -r dd8449afc086 graal/com.oracle.nfi/src/com/oracle/nfi/NativeFunctionInterfaceRuntime.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.nfi/src/com/oracle/nfi/NativeFunctionInterfaceRuntime.java Tue Aug 05 15:58:11 2014 +0200 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.nfi; + +import com.oracle.nfi.api.*; + +public final class NativeFunctionInterfaceRuntime { + private static final NativeFunctionInterface INTERFACE; + + private static native NativeFunctionInterface createInterface(); + + public static NativeFunctionInterface getNativeFunctionInterface() { + return INTERFACE; + } + + static { + NativeFunctionInterface instance; + try { + instance = createInterface(); + } catch (UnsatisfiedLinkError e) { + System.err.println("Graal Native Function Interface not supported!"); + e.printStackTrace(); + instance = null; + } + INTERFACE = instance; + } +} diff -r 7e8ecfe7d2e5 -r dd8449afc086 graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionHandle.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionHandle.java Tue Aug 05 15:58:11 2014 +0200 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.nfi.api; + +/** + * A handle that can be used to {@linkplain #call(Object[]) call} a native function. + */ +public interface NativeFunctionHandle { + + /** + * Calls the native function. + *

+ * The caller is responsible for ensuring {@code args} comply with the platform ABI (e.g. Unix AMD64 ABI). If the library + * function has struct parameters, the fields of the struct must be passed as individual + * arguments. + * + * @param args the arguments that will be passed to the native function + * @return boxed return value of the function call + */ + Object call(Object... args); + +} diff -r 7e8ecfe7d2e5 -r dd8449afc086 graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionInterface.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionInterface.java Tue Aug 05 15:58:11 2014 +0200 @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.nfi.api; + +/** + * Interface to get a {@linkplain NativeFunctionHandle handle} or {@linkplain NativeFunctionPointer + * pointer} to a native function or a {@linkplain NativeLibraryHandle handle} to an open native + * library. + */ +public interface NativeFunctionInterface { + + /** + * Resolves and returns a handle to an open native library. This method will open the library + * only if it is not already open. + * + * @param libPath the absolute path to the library + * @return the resolved library handle + * @throws UnsatisfiedLinkError if the library could not be found or opened + */ + NativeLibraryHandle getLibraryHandle(String libPath); + + /** + * Determines if the underlying platform/runtime supports the notion of a default library search + * path. For example, on *nix systems, this is typically defined by the {@code LD_LIBRARY_PATH} + * environment variable. + */ + boolean isDefaultLibrarySearchSupported(); + + /** + * Resolves the function pointer {@code NativeFunctionPointer} of a native function. + * + * @param libraries the ordered list of libraries to search for the function + * @param name the name of the function to be resolved + * @return a pointer to the native function + * @throws UnsatisfiedLinkError if the function could not be resolved + */ + NativeFunctionPointer getFunctionPointer(NativeLibraryHandle[] libraries, String name); + + /** + * Resolves a function name to a {@linkplain NativeFunctionHandle handle} that can be called + * with a given signature. The signature contains the types of the arguments that will be passed + * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}. + * + * @param library the handle to a resolved library + * @param name the name of the function to be resolved + * @param returnType the type of the return value + * @param argumentTypes the types of the arguments + * @return the function handle of the native function + * @throws UnsatisfiedLinkError if the function handle could not be resolved + */ + NativeFunctionHandle getFunctionHandle(NativeLibraryHandle library, String name, Class returnType, Class... argumentTypes); + + /** + * Resolves a function pointer to a {@linkplain NativeFunctionHandle handle} that can be called + * with a given signature. The signature contains the types of the arguments that will be passed + * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}. + * + * @param functionPointer a function pointer + * @param returnType the type of the return value + * @param argumentTypes the types of the arguments + * @return the function handle of the native function + * @throws UnsatisfiedLinkError the function handle could not be created + */ + NativeFunctionHandle getFunctionHandle(NativeFunctionPointer functionPointer, Class returnType, Class... argumentTypes); + + /** + * Resolves a function name to a {@linkplain NativeFunctionHandle handle} that can be called + * with a given signature. The signature contains the types of the arguments that will be passed + * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}. + * + * @param libraries the ordered list of libraries to search for the function + * @param name the name of the function to be resolved + * @param returnType the type of the return value + * @param argumentTypes the types of the arguments + * @return the function handle of the native function + * @throws UnsatisfiedLinkError if the function handle could not be created + */ + NativeFunctionHandle getFunctionHandle(NativeLibraryHandle[] libraries, String name, Class returnType, Class... argumentTypes); + + /** + * Resolves a function name to a {@linkplain NativeFunctionHandle handle} that can be called + * with a given signature. The signature contains the types of the arguments that will be passed + * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}. + * + * @param name the name of the function to be resolved + * @param returnType the type of the return value + * @param argumentTypes the types of the arguments + * @return the function handle of the native function + * @throws UnsatisfiedLinkError if default library searching is not + * {@linkplain #isDefaultLibrarySearchSupported() supported} or if the function + * could not be resolved + */ + NativeFunctionHandle getFunctionHandle(String name, Class returnType, Class... argumentTypes); + + /** + * Creates a {@link NativeFunctionPointer} from a raw value. + * + * @param rawValue raw function pointer + * @return {@code NativeFunctionPointer} for {@code rawValue} + */ + NativeFunctionPointer getNativeFunctionPointerFromRawValue(long rawValue); +} diff -r 7e8ecfe7d2e5 -r dd8449afc086 graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionPointer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionPointer.java Tue Aug 05 15:58:11 2014 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.nfi.api; + +/** + * An opaque representation of a native function pointer. + *

+ * Use {@code NativeFunctionInterface#getFunctionHandle(NativeFunctionPointer, Class, Class...)} to + * get a handle enabling the native function to be {@linkplain NativeFunctionHandle#call(Object...) + * called}. + */ +public interface NativeFunctionPointer { + + /** + * Returns the name of the function. + * + * @return name of the function + */ + String getName(); + + /** + * Returns the raw function pointer value. + * + * @return raw function pointer value + */ + long getRawValue(); + +} diff -r 7e8ecfe7d2e5 -r dd8449afc086 graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeLibraryHandle.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeLibraryHandle.java Tue Aug 05 15:58:11 2014 +0200 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.nfi.api; + +/** + * An opaque representation of a native library handle. A handle is obtained via + * {@link NativeFunctionInterface#getLibraryHandle(String)}. A handle is used to resolve a string to + * a {@linkplain NativeFunctionInterface#getFunctionHandle(String, Class, Class...) handle} or + * {@linkplain NativeFunctionInterface#getFunctionPointer(NativeLibraryHandle[], String) pointer}. + */ +public interface NativeLibraryHandle { + /** + * Gets a name for this library. This may be the path for the file from which the library was + * loaded. + */ + String getName(); +} diff -r 7e8ecfe7d2e5 -r dd8449afc086 mx/projects --- a/mx/projects Tue Aug 05 12:34:55 2014 +0200 +++ b/mx/projects Tue Aug 05 15:58:11 2014 +0200 @@ -103,7 +103,8 @@ distribution@TRUFFLE@subDir=graal distribution@TRUFFLE@sourcesPath=build/truffle.src.zip distribution@TRUFFLE@dependencies=\ -com.oracle.truffle.api.dsl +com.oracle.truffle.api.dsl,\ +com.oracle.nfi distribution@GRAAL_TRUFFLE@path=build/graal-truffle.jar distribution@GRAAL_TRUFFLE@subDir=graal @@ -121,6 +122,20 @@ com.oracle.truffle.dsl.processor distribution@TRUFFLE-DSL-PROCESSOR@distDependencies=TRUFFLE +# nfi +project@com.oracle.nfi@subDir=graal +project@com.oracle.nfi@sourceDirs=src +project@com.oracle.nfi@dependencies= +project@com.oracle.nfi@checkstyle=com.oracle.graal.graph +project@com.oracle.nfi@javaCompliance=1.8 + +# nfi.test +project@com.oracle.nfi.test@subDir=graal +project@com.oracle.nfi.test@sourceDirs=test +project@com.oracle.nfi.test@dependencies=com.oracle.nfi,com.oracle.graal.compiler.common,JUNIT +project@com.oracle.nfi.test@checkstyle=com.oracle.graal.graph +project@com.oracle.nfi.test@javaCompliance=1.8 + # graal.api.collections project@com.oracle.graal.api.collections@subDir=graal project@com.oracle.graal.api.collections@sourceDirs=src @@ -161,7 +176,7 @@ # graal.api.code project@com.oracle.graal.api.code@subDir=graal project@com.oracle.graal.api.code@sourceDirs=src -project@com.oracle.graal.api.code@dependencies=com.oracle.graal.api.meta +project@com.oracle.graal.api.code@dependencies=com.oracle.graal.api.meta,com.oracle.nfi project@com.oracle.graal.api.code@checkstyle=com.oracle.graal.graph project@com.oracle.graal.api.code@javaCompliance=1.8 project@com.oracle.graal.api.code@workingSets=API,Graal @@ -515,7 +530,7 @@ # graal.compiler project@com.oracle.graal.compiler@subDir=graal project@com.oracle.graal.compiler@sourceDirs=src -project@com.oracle.graal.compiler@dependencies=com.oracle.graal.virtual,com.oracle.graal.loop,com.oracle.graal.alloc +project@com.oracle.graal.compiler@dependencies=com.oracle.graal.virtual,com.oracle.graal.loop,com.oracle.graal.alloc,com.oracle.nfi project@com.oracle.graal.compiler@checkstyle=com.oracle.graal.graph project@com.oracle.graal.compiler@javaCompliance=1.8 project@com.oracle.graal.compiler@annotationProcessors=com.oracle.graal.service.processor diff -r 7e8ecfe7d2e5 -r dd8449afc086 src/share/vm/graal/graalRuntime.cpp --- a/src/share/vm/graal/graalRuntime.cpp Tue Aug 05 12:34:55 2014 +0200 +++ b/src/share/vm/graal/graalRuntime.cpp Tue Aug 05 15:58:11 2014 +0200 @@ -664,6 +664,18 @@ return JNIHandles::make_local((oop) result.get_jobject()); JVM_END +// private static NativeFunctionInterfaceRuntime.createInterface() +JVM_ENTRY(jobject, JVM_CreateNativeFunctionInterface(JNIEnv *env, jclass c)) + TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend", CHECK_NULL); + KlassHandle klass = GraalRuntime::resolve_or_fail(name, CHECK_NULL); + + TempNewSymbol makeInstance = SymbolTable::new_symbol("createNativeFunctionInterface", CHECK_NULL); + TempNewSymbol sig = SymbolTable::new_symbol("()Lcom/oracle/nfi/api/NativeFunctionInterface;", CHECK_NULL); + JavaValue result(T_OBJECT); + JavaCalls::call_static(&result, klass, makeInstance, sig, CHECK_NULL); + return JNIHandles::make_local((oop) result.get_jobject()); +JVM_END + void GraalRuntime::check_generated_sources_sha1(TRAPS) { TempNewSymbol name = SymbolTable::new_symbol("GeneratedSourcesSha1", CHECK_ABORT); KlassHandle klass = load_required_class(name); diff -r 7e8ecfe7d2e5 -r dd8449afc086 src/share/vm/prims/nativeLookup.cpp --- a/src/share/vm/prims/nativeLookup.cpp Tue Aug 05 12:34:55 2014 +0200 +++ b/src/share/vm/prims/nativeLookup.cpp Tue Aug 05 15:58:11 2014 +0200 @@ -128,6 +128,7 @@ jobject JNICALL JVM_GetGraalRuntime(JNIEnv *env, jclass c); jobject JNICALL JVM_GetGraalServiceImpls(JNIEnv *env, jclass c); jobject JNICALL JVM_CreateTruffleRuntime(JNIEnv *env, jclass c); + jobject JNICALL JVM_CreateNativeFunctionInterface(JNIEnv *env, jclass c); jboolean JNICALL JVM_ParseGraalOptions(JNIEnv *env, jclass hotspotOptionsClass); #ifdef COMPILERGRAAL void JNICALL JVM_PrintAndResetGraalCompRate(JNIEnv *env, jclass c); @@ -144,11 +145,12 @@ { CC"Java_sun_misc_Perf_registerNatives", NULL, FN_PTR(JVM_RegisterPerfMethods) }, { CC"Java_sun_hotspot_WhiteBox_registerNatives", NULL, FN_PTR(JVM_RegisterWhiteBoxMethods) }, #ifdef GRAAL - { CC"Java_com_oracle_graal_api_runtime_Graal_initializeRuntime", NULL, FN_PTR(JVM_GetGraalRuntime) }, - { CC"Java_com_oracle_graal_api_runtime_Services_getServiceImpls", NULL, FN_PTR(JVM_GetGraalServiceImpls) }, - { CC"Java_com_oracle_truffle_api_Truffle_createRuntime", NULL, FN_PTR(JVM_CreateTruffleRuntime) }, - { CC"Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_init", NULL, FN_PTR(JVM_InitializeGraalNatives) }, - { CC"Java_com_oracle_graal_hotspot_HotSpotOptions_parseVMOptions", NULL, FN_PTR(JVM_ParseGraalOptions) }, + { CC"Java_com_oracle_graal_api_runtime_Graal_initializeRuntime", NULL, FN_PTR(JVM_GetGraalRuntime) }, + { CC"Java_com_oracle_graal_api_runtime_Services_getServiceImpls", NULL, FN_PTR(JVM_GetGraalServiceImpls) }, + { CC"Java_com_oracle_truffle_api_Truffle_createRuntime", NULL, FN_PTR(JVM_CreateTruffleRuntime) }, + { CC"Java_com_oracle_nfi_NativeFunctionInterfaceRuntime_createInterface", NULL, FN_PTR(JVM_CreateNativeFunctionInterface) }, + { CC"Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_init", NULL, FN_PTR(JVM_InitializeGraalNatives) }, + { CC"Java_com_oracle_graal_hotspot_HotSpotOptions_parseVMOptions", NULL, FN_PTR(JVM_ParseGraalOptions) }, #endif };