# HG changeset patch # User Matthias Grimmer # Date 1391069985 -3600 # Node ID ed3a1471e13339bfad6d5ce588df52ddd4dd4592 # Parent 64c77f0577bb6fc7b49e74ea342a1fad4b851754 Add the Graal Native Function Interface diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionHandle.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionHandle.java Thu Jan 30 09:19:45 2014 +0100 @@ -0,0 +1,44 @@ +/* + * 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; + +/** + * The function handle of a native foreign function. + * + */ +public interface NativeFunctionHandle { + + /** + * Calls the native foreign function. + * + * @param args the arguments that will be passed to the native foreign function + */ + Object call(Object[] args); + + /** + * Returns the installed code of the call stub for the native foreign function call. + * + * @return the installed code of the native call stub + */ + InstalledCode getCallStub(); +} diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionInterface.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionInterface.java Thu Jan 30 09:19:45 2014 +0100 @@ -0,0 +1,99 @@ +/* + * 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 resolve pointers to native foreign functions. + * + */ +public interface NativeFunctionInterface { + + /** + * Resolves and returns a library handle. + * + * @param libPath the absolute path to the library + * @return the resolved library handle + */ + NativeLibraryHandle getLibraryHandle(String libPath); + + /** + * Resolves the NativeFunctionHandle of a native function that can be called. + * + * @param libraryHandle the handle to a resolved library + * @param functionName 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 foreign function + */ + NativeFunctionHandle getFunctionHandle(NativeLibraryHandle libraryHandle, String functionName, Class returnType, Class[] argumentTypes); + + /** + * Resolves the NativeFunctionHandle of a native function that can be called. + * + * @param functionPointer the function pointer + * @param returnType the type of the return value + * @param argumentTypes the types of the arguments + * @return the function handle of the native foreign function + */ + NativeFunctionHandle getFunctionHandle(NativeFunctionPointer functionPointer, Class returnType, Class[] argumentTypes); + + /** + * Resolves the function pointer NativeFunctionPointer of a native function. + * + * @param libraryHandles the handles to a various resolved library, the first library containing + * the method wins + * @param functionName the name of the function to be resolved + * @return the function handle of the native foreign function + */ + NativeFunctionPointer getFunctionPointer(NativeLibraryHandle[] libraryHandles, String functionName); + + /** + * Resolves the NativeFunctionHandle of a native function that can be called. + * + * @param libraryHandles the handles to a various resolved library, the first library containing + * the method wins + * @param functionName 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 foreign function + */ + NativeFunctionHandle getFunctionHandle(NativeLibraryHandle[] libraryHandles, String functionName, Class returnType, Class[] argumentTypes); + + /** + * Resolves the NativeFunctionHandle of a native function that can be called. + * + * @param functionName 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 foreign function + */ + NativeFunctionHandle getFunctionHandle(String functionName, Class returnType, Class[] argumentTypes); + + /** + * Creates NativeFunctionPointer from raw value. + * + * @param rawValue Raw pointer value + * @return NativeFunctionPointer of the raw pointer + */ + NativeFunctionPointer getNativeFunctionPointerFromRawValue(long rawValue); +} diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionPointer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionPointer.java Thu Jan 30 09:19:45 2014 +0100 @@ -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.graal.api.code; + +public interface NativeFunctionPointer { + + /** + * Returns whether the pointer is valid. + * + * @return true if the pointer is valid + */ + boolean isValid(); + + /** + * Returns function pointer as raw value. + * + * @return raw value of function pointer + */ + long asRawValue(); + + /** + * Returns the name of the function. + * + * @return name of the function + */ + String getFunctionName(); + +} diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeLibraryHandle.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeLibraryHandle.java Thu Jan 30 09:19:45 2014 +0100 @@ -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.graal.api.code; + +/** + * The library handle of the native library. + */ +public interface NativeLibraryHandle { + + /** + * Returns whether the handle is valid. + * + * @return true if the handle is valid + */ + boolean isValid(); + + /** + * Returns function pointer as raw value. + * + * @return raw value of function pointer + */ + long asRawValue(); +} diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Thu Jan 30 17:53:27 2014 -0800 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Thu Jan 30 09:19:45 2014 +0100 @@ -899,6 +899,8 @@ } } + public abstract void emitCCall(long address, CallingConvention nativeCallingConvention, Value[] args, int numberOfFloatingPointArguments); + @Override protected void emitForeignCall(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info) { long maxOffset = linkage.getMaxCallTargetOffset(); diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java Thu Jan 30 17:53:27 2014 -0800 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java Thu Jan 30 09:19:45 2014 +0100 @@ -63,6 +63,8 @@ return providers.getCodeCache().getTarget(); } + public abstract NativeFunctionInterface getNativeFunctionInterface(); + public abstract FrameMap newFrameMap(); public abstract LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir); diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.ffi.amd64.test/test/com/oracle/graal/ffi/amd64/test/ArrayPointerTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.ffi.amd64.test/test/com/oracle/graal/ffi/amd64/test/ArrayPointerTest.java Thu Jan 30 09:19:45 2014 +0100 @@ -0,0 +1,39 @@ +/* + * 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.ffi.amd64.test; + +import org.junit.*; + +import com.oracle.graal.api.code.*; + +public class ArrayPointerTest extends LibCallTest { + + @Test + public void arrayPointerTest01() { + byte[] str = new byte[]{'A', 'B', 'C', '\0'}; + NativeFunctionHandle handle = ffi.getFunctionHandle("puts", int.class, new Class[]{byte[].class}); + Object[] args = new Object[]{str}; + int result = (int) handle.call(args); + Assert.assertTrue(0 < result); + } +} diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.ffi.amd64.test/test/com/oracle/graal/ffi/amd64/test/LibCallTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.ffi.amd64.test/test/com/oracle/graal/ffi/amd64/test/LibCallTest.java Thu Jan 30 09:19:45 2014 +0100 @@ -0,0 +1,90 @@ +/* + * 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.ffi.amd64.test; + +import java.lang.reflect.*; + +import org.junit.*; + +import sun.misc.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.runtime.*; +import com.oracle.graal.runtime.*; + +public class LibCallTest { + + protected static final Unsafe unsafe = getUnsafe(); + public static final RuntimeProvider runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class); + public static final NativeFunctionInterface ffi = runtimeProvider.getHostBackend().getNativeFunctionInterface(); + + @Test + public void test() { + Long str = unsafe.allocateMemory(4); + unsafe.putByte(str, (byte) 'A'); + unsafe.putByte(str + 1, (byte) 'B'); + unsafe.putByte(str + 2, (byte) 'C'); + unsafe.putByte(str + 3, (byte) '\0'); + NativeFunctionHandle handle = ffi.getFunctionHandle("puts", int.class, new Class[]{long.class}); + Object[] args = new Object[]{str}; + int result = (int) handle.call(args); + Assert.assertTrue(0 < result); + } + + protected long getDouble(double val) { + Long d = unsafe.allocateMemory(8); + unsafe.putDouble(d, val); + return d; + } + + protected long getLong(long val) { + Long d = unsafe.allocateMemory(8); + unsafe.putLong(d, val); + return d; + } + + protected long getInt(int val) { + Long d = unsafe.allocateMemory(4); + unsafe.putInt(d, val); + return d; + } + + protected void free(long p) { + unsafe.freeMemory(p); + } + + private static Unsafe getUnsafe() { + try { + return Unsafe.getUnsafe(); + } catch (SecurityException e) { + } + try { + Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe"); + theUnsafeInstance.setAccessible(true); + return (Unsafe) theUnsafeInstance.get(Unsafe.class); + } catch (Exception e) { + throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e); + } + } + +} diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.ffi.amd64.test/test/com/oracle/graal/ffi/amd64/test/MathLibCallTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.ffi.amd64.test/test/com/oracle/graal/ffi/amd64/test/MathLibCallTest.java Thu Jan 30 09:19:45 2014 +0100 @@ -0,0 +1,53 @@ +/* + * 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.ffi.amd64.test; + +import org.junit.*; + +import com.oracle.graal.api.code.*; + +public class MathLibCallTest extends LibCallTest { + + static final Object[] args = new Object[]{Double.doubleToLongBits(3), Double.doubleToLongBits(5.5)}; + static final NativeFunctionHandle handle = ffi.getFunctionHandle("pow", double.class, new Class[]{double.class, double.class}); + + @Test + public void powTest() { + double result = (double) handle.call(args); + Assert.assertEquals(Math.pow(3, 5.5), result, 0); + } + + @Test + public void compilePowTest() { + double result = 0; + for (int i = 0; i < 100000; i++) { + result = callPow(); + } + Assert.assertEquals(Math.pow(3, 5.5), result, 0); + + } + + private static double callPow() { + return (double) handle.call(args); + } +} diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.ffi.amd64.test/test/com/oracle/graal/ffi/amd64/test/StdLibCallTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.ffi.amd64.test/test/com/oracle/graal/ffi/amd64/test/StdLibCallTest.java Thu Jan 30 09:19:45 2014 +0100 @@ -0,0 +1,175 @@ +/* + * 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.ffi.amd64.test; + +import org.junit.*; + +import com.oracle.graal.api.code.*; + +public class StdLibCallTest extends LibCallTest { + + @Test + public void mallocTest() { + Object[] args = new Object[]{6}; + NativeFunctionHandle mallocHandle = ffi.getFunctionHandle("malloc", long.class, new Class[]{int.class}); + + long p = (long) mallocHandle.call(args); + unsafe.putByte(p, (byte) 'G'); + unsafe.putByte(p + 1, (byte) 'R'); + unsafe.putByte(p + 2, (byte) 'A'); + unsafe.putByte(p + 3, (byte) 'A'); + unsafe.putByte(p + 4, (byte) 'L'); + unsafe.putByte(p + 5, (byte) '\0'); + + NativeFunctionHandle putsHandle = ffi.getFunctionHandle("puts", int.class, new Class[]{long.class}); + Object[] args2 = new Object[]{p}; + int result = (int) putsHandle.call(args2); + Assert.assertTrue(0 < result); + Assert.assertEquals(unsafe.getByte(p) & 0xFF, 'G'); + Assert.assertEquals(unsafe.getByte(p + 1) & 0xFF, 'R'); + Assert.assertEquals(unsafe.getByte(p + 2) & 0xFF, 'A'); + Assert.assertEquals(unsafe.getByte(p + 3) & 0xFF, 'A'); + Assert.assertEquals(unsafe.getByte(p + 4) & 0xFF, 'L'); + Assert.assertEquals(unsafe.getByte(p + 5) & 0xFF, '\0'); + + NativeFunctionHandle freeHandle = ffi.getFunctionHandle("free", void.class, new Class[]{long.class}); + freeHandle.call(args2); + } + + @Test + public void printfSimpleTest() { + long str = unsafe.allocateMemory(8); + unsafe.putByte(str, (byte) 'A'); + unsafe.putByte(str + 1, (byte) 'B'); + unsafe.putByte(str + 2, (byte) ' '); + unsafe.putByte(str + 3, (byte) '%'); + unsafe.putByte(str + 4, (byte) 'f'); + unsafe.putByte(str + 5, (byte) '%'); + unsafe.putByte(str + 6, (byte) 'f'); + unsafe.putByte(str + 7, (byte) '\0'); + + Object[] args = new Object[]{str, Double.doubleToRawLongBits(1.0), Double.doubleToRawLongBits(1.0)}; + NativeFunctionHandle printfHandle = ffi.getFunctionHandle("printf", int.class, new Class[]{long.class, double.class, double.class}); + + int result = (int) printfHandle.call(args); + Assert.assertTrue(0 < result); + } + + @Test + public void putsSimpleTest() { + long str = unsafe.allocateMemory(6); + unsafe.putByte(str, (byte) 'A'); + unsafe.putByte(str + 1, (byte) 'B'); + unsafe.putByte(str + 2, (byte) 'B'); + unsafe.putByte(str + 3, (byte) 'B'); + unsafe.putByte(str + 4, (byte) '\0'); + + Object[] args = new Object[]{str}; + NativeFunctionHandle printfHandle = ffi.getFunctionHandle("puts", int.class, new Class[]{long.class}); + + int result = (int) printfHandle.call(args); + Assert.assertTrue(0 < result); + } + + @Test + public void printfTest() { + long str = unsafe.allocateMemory(25); + 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; + } + unsafe.putByte(str + 24, (byte) '\0'); + + Object[] args = new Object[]{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]}; + NativeFunctionHandle printfHandle = ffi.getFunctionHandle("printf", int.class, new 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) printfHandle.call(args); + Assert.assertTrue(0 < result); + } + + @Test + public void printfTest2() { + long str = unsafe.allocateMemory(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'); + + Object[] args = new Object[]{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]}; + + NativeFunctionHandle printfHandle = ffi.getFunctionHandle("printf", int.class, new 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) printfHandle.call(args); + Assert.assertTrue(0 < result); + } + + @Test + public void printfTest3() { + long str = unsafe.allocateMemory(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'); + + Object[] args = new Object[]{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]}; + + NativeFunctionHandle printfHandle = ffi.getFunctionHandle("printf", int.class, new 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) printfHandle.call(args); + Assert.assertTrue(0 < result); + } +} diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/AMD64NativeFunctionHandle.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/AMD64NativeFunctionHandle.java Thu Jan 30 09:19:45 2014 +0100 @@ -0,0 +1,61 @@ +/* + * 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.ffi.amd64; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.compiler.target.*; +import com.oracle.graal.ffi.amd64.util.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.nodes.*; + +public class AMD64NativeFunctionHandle implements NativeFunctionHandle { + + private final InstalledCode code; + private final String functionName; + + protected final HotSpotProviders providers; + protected final Backend backend; + + public AMD64NativeFunctionHandle(HotSpotProviders providers, Backend backend, AMD64NativeFunctionPointer functionPointer, Class returnType, Class[] argumentTypes) { + this.providers = providers; + this.backend = backend; + this.functionName = functionPointer.getFunctionName(); + StructuredGraph graph = NativeCallStubGraphBuilder.getGraph(providers, functionPointer, returnType, argumentTypes); + InstallUtil installer = new InstallUtil(providers, backend); + this.code = installer.install(graph); + } + + @Override + public Object call(Object[] args) { + try { + return code.execute(args, null, null); + } catch (InvalidInstalledCodeException e) { + throw GraalInternalError.shouldNotReachHere("Execution of GNFI Callstub failed: " + functionName); + } + } + + public InstalledCode getCallStub() { + return code; + } +} diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/AMD64NativeFunctionInterface.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/AMD64NativeFunctionInterface.java Thu Jan 30 09:19:45 2014 +0100 @@ -0,0 +1,169 @@ +/* + * 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.ffi.amd64; + +import java.lang.reflect.*; + +import sun.misc.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.compiler.target.*; +import com.oracle.graal.hotspot.meta.*; + +public class AMD64NativeFunctionInterface implements NativeFunctionInterface { + + private static final Class LOOKUP_FUNCTION_RETURNTYPE = long.class; + private static final Class[] LOOKUP_FUNCTION_SIGNATURE = new Class[]{long.class, long.class}; + + private static final Unsafe unsafe = getUnsafe(); + + private static final int STD_BUFFER_SIZE = 1024; + + protected final HotSpotProviders providers; + protected final Backend backend; + protected final AMD64NativeLibraryHandle rtldDefault; + protected final AMD64NativeFunctionPointer libraryLoadFunctionPointer; + protected final AMD64NativeFunctionPointer functionLookupFunctionPointer; + + public AMD64NativeFunctionInterface(HotSpotProviders providers, Backend backend, AMD64NativeFunctionPointer libraryLoadFunctionPointer, AMD64NativeFunctionPointer functionLookUpFunctionPointer, + AMD64NativeLibraryHandle rtldDefault) { + this.rtldDefault = rtldDefault; + this.providers = providers; + this.backend = backend; + this.libraryLoadFunctionPointer = libraryLoadFunctionPointer; + this.functionLookupFunctionPointer = functionLookUpFunctionPointer; + } + + @Override + public AMD64NativeLibraryHandle getLibraryHandle(String libPath) { + AMD64NativeFunctionHandle libraryLookupFunctionHandle = new AMD64NativeFunctionHandle(providers, backend, libraryLoadFunctionPointer, long.class, + new Class[]{long.class, long.class, int.class}); + + long allocatedMemory = -1; + try { + allocatedMemory = unsafe.allocateMemory(STD_BUFFER_SIZE); + } catch (OutOfMemoryError e) { + throw new AssertionError(); + } + + Object[] args = new Object[]{copyStringToMemory(libPath), allocatedMemory, STD_BUFFER_SIZE}; + long libraryHandle = (long) libraryLookupFunctionHandle.call(args); + unsafe.freeMemory(allocatedMemory); + return new AMD64NativeLibraryHandle(libraryHandle); + } + + @Override + public AMD64NativeFunctionHandle getFunctionHandle(NativeLibraryHandle libraryHandle, String functionName, Class returnType, Class[] argumentTypes) { + AMD64NativeFunctionPointer functionPointer = lookupFunctionPointer(functionName, libraryHandle); + if (!functionPointer.isValid()) { + throw new IllegalStateException(functionName + " not found!"); + } + return getFunctionHandle(functionPointer, returnType, argumentTypes); + } + + @Override + public AMD64NativeFunctionHandle getFunctionHandle(NativeLibraryHandle[] libraryHandles, String functionName, Class returnType, Class[] argumentTypes) { + AMD64NativeFunctionPointer functionPointer = null; + for (NativeLibraryHandle libraryHandle : libraryHandles) { + functionPointer = lookupFunctionPointer(functionName, libraryHandle); + if (functionPointer.isValid()) { + return new AMD64NativeFunctionHandle(providers, backend, functionPointer, returnType, argumentTypes); + } + } + return getFunctionHandle(functionName, returnType, argumentTypes); + } + + @Override + public AMD64NativeFunctionHandle getFunctionHandle(String functionName, Class returnType, Class[] argumentTypes) { + if (rtldDefault.asRawValue() == AMD64NativeLibraryHandle.INVALID_HANDLE) { + throw new AssertionError("No library provided or RTLD_DEFAULT not supported!"); + } + return getFunctionHandle(rtldDefault, functionName, returnType, argumentTypes); + } + + private AMD64NativeFunctionPointer lookupFunctionPointer(String functionName, NativeLibraryHandle handle) { + + if (!functionLookupFunctionPointer.isValid()) { + throw new IllegalStateException("no dlsym function pointer"); + } + AMD64NativeFunctionHandle dllLookupFunctionHandle = new AMD64NativeFunctionHandle(providers, backend, functionLookupFunctionPointer, LOOKUP_FUNCTION_RETURNTYPE, LOOKUP_FUNCTION_SIGNATURE); + long allocatedMemory = copyStringToMemory(functionName); + Object[] args = new Object[]{handle, allocatedMemory}; + long functionPointer = (long) dllLookupFunctionHandle.call(args); + unsafe.freeMemory(allocatedMemory); + return new AMD64NativeFunctionPointer(functionPointer, functionName); + } + + private static long copyStringToMemory(String str) { + int size = str.length(); + long ptr = unsafe.allocateMemory(size + 1); + for (int i = 0; i < size; i++) { + unsafe.putByte(ptr + i, (byte) str.charAt(i)); + } + unsafe.putByte(ptr + size, (byte) '\0'); + return ptr; + } + + private static Unsafe getUnsafe() { + try { + return Unsafe.getUnsafe(); + } catch (SecurityException e) { + } + try { + Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe"); + theUnsafeInstance.setAccessible(true); + return (Unsafe) theUnsafeInstance.get(Unsafe.class); + } catch (IllegalArgumentException | SecurityException | NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e); + } + } + + @Override + public AMD64NativeFunctionHandle getFunctionHandle(NativeFunctionPointer functionPointer, Class returnType, Class[] argumentTypes) { + if (functionPointer instanceof AMD64NativeFunctionPointer) { + if (!((AMD64NativeFunctionPointer) functionPointer).isValid()) { + throw new IllegalStateException("Function Symbol not found"); + } + } else { + throw new IllegalStateException("AMD64 function pointer required!"); + } + return new AMD64NativeFunctionHandle(providers, backend, (AMD64NativeFunctionPointer) functionPointer, returnType, argumentTypes); + } + + @Override + public AMD64NativeFunctionPointer getFunctionPointer(NativeLibraryHandle[] libraryHandles, String functionName) { + for (NativeLibraryHandle libraryHandle : libraryHandles) { + AMD64NativeFunctionPointer functionPointer = lookupFunctionPointer(functionName, libraryHandle); + if (functionPointer.isValid()) { + return functionPointer; + } + } + throw new LinkageError("Function not found: " + functionName); + } + + @Override + public NativeFunctionPointer getNativeFunctionPointerFromRawValue(long rawValue) { + return new AMD64NativeFunctionPointer(rawValue, null); + } + +} diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/AMD64NativeFunctionPointer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/AMD64NativeFunctionPointer.java Thu Jan 30 09:19:45 2014 +0100 @@ -0,0 +1,50 @@ +/* + * 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.ffi.amd64; + +import com.oracle.graal.api.code.*; + +public class AMD64NativeFunctionPointer implements NativeFunctionPointer { + + private final long functionPointer; + private final String functionName; + + public AMD64NativeFunctionPointer(long functionPointer, String functionName) { + this.functionPointer = functionPointer; + this.functionName = functionName; + } + + public boolean isValid() { + return functionPointer != 0; + } + + @Override + public long asRawValue() { + return functionPointer; + } + + public String getFunctionName() { + return functionName; + } + +} diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/AMD64NativeLibraryHandle.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/AMD64NativeLibraryHandle.java Thu Jan 30 09:19:45 2014 +0100 @@ -0,0 +1,43 @@ +/* + * 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.ffi.amd64; + +import com.oracle.graal.api.code.*; + +public class AMD64NativeLibraryHandle implements NativeLibraryHandle { + + private final long handle; + public static final long INVALID_HANDLE = 0xDEADFACE; + + public AMD64NativeLibraryHandle(long handle) { + this.handle = handle; + } + + public long asRawValue() { + return handle; + } + + public boolean isValid() { + return handle != 0 && handle != INVALID_HANDLE; + } +} diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/node/AMD64RawNativeCallNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/node/AMD64RawNativeCallNode.java Thu Jan 30 09:19:45 2014 +0100 @@ -0,0 +1,80 @@ +/* + * 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.ffi.amd64.node; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CallingConvention.Type; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.amd64.*; +import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.target.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.type.*; + +public class AMD64RawNativeCallNode extends FixedWithNextNode implements LIRGenLowerable { + + private final Constant functionPointer; + @Input private final NodeInputList args; + + public AMD64RawNativeCallNode(Kind returnType, Constant functionPointer, ValueNode[] args) { + super(StampFactory.forKind(returnType)); + this.functionPointer = functionPointer; + this.args = new NodeInputList<>(this, args); + } + + @Override + public void generate(LIRGenerator generator) { + if (generator instanceof AMD64LIRGenerator) { + AMD64LIRGenerator amd64gen = (AMD64LIRGenerator) generator; + Value[] parameter = new Value[args.count()]; + JavaType[] parameterTypes = new JavaType[args.count()]; + for (int i = 0; i < args.count(); i++) { + parameter[i] = generator.operand(args.get(i)); + parameterTypes[i] = args.get(i).stamp().javaType(amd64gen.getMetaAccess()); + } + ResolvedJavaType returnType = stamp().javaType(amd64gen.getMetaAccess()); + CallingConvention cc = generator.getCodeCache().getRegisterConfig().getCallingConvention(Type.NativeCall, returnType, parameterTypes, generator.target(), false); + amd64gen.emitCCall(functionPointer.asLong(), cc, parameter, countFloatingTypeArguments(args)); + if (this.kind() != Kind.Void) { + generator.setResult(this, amd64gen.emitMove(cc.getReturn())); + } + } else { + throw GraalInternalError.shouldNotReachHere("GNFI Native call only supported with AMD64LIR Generator"); + } + } + + private static int countFloatingTypeArguments(NodeInputList args) { + int count = 0; + for (ValueNode n : args) { + if (n.kind() == Kind.Double || n.kind() == Kind.Float) { + count++; + } + } + if (count > 8) { + return 8; + } + return count; + } + +} diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/util/InstallUtil.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/util/InstallUtil.java Thu Jan 30 09:19:45 2014 +0100 @@ -0,0 +1,81 @@ +/* + * 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.ffi.amd64.util; + +import static com.oracle.graal.api.code.CodeUtil.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CallingConvention.Type; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.meta.ProfilingInfo.TriState; +import com.oracle.graal.compiler.*; +import com.oracle.graal.compiler.target.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.tiers.*; +import com.oracle.graal.printer.*; + +/** + * Utility to install the code of the native call stub. + * + */ +public class InstallUtil { + + protected final HotSpotProviders providers; + protected final Backend backend; + + public InstallUtil(HotSpotProviders providers, Backend backend) { + DebugEnvironment.initialize(System.out); + this.providers = providers; + this.backend = backend; + } + + /** + * Attaches a graph to a method libCall. Compiles the graph and installs it. + * + * @param g the graph to be attached to a method and compiled + * @return returns the installed code that also holds a copy of graph g + */ + public InstalledCode install(final StructuredGraph g) { + try { + Suites suites = providers.getSuites().createSuites(); + PhaseSuite phaseSuite = backend.getSuites().getDefaultGraphBuilderSuite().copy(); + CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, g.method(), false); + CompilationResult compResult = GraalCompiler.compileGraph(g, cc, g.method(), providers, backend, backend.getTarget(), null, phaseSuite, OptimisticOptimizations.ALL, + DefaultProfilingInfo.get(TriState.UNKNOWN), new SpeculationLog(), suites, true, new CompilationResult(), CompilationResultBuilderFactory.Default); + InstalledCode installedCode; + try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache(), g.method())) { + installedCode = providers.getCodeCache().addMethod(g.method(), compResult, null); + } + + return installedCode; + } catch (SecurityException e) { + throw GraalInternalError.shouldNotReachHere("Installation of GNFI Callstub failed."); + } + } +} diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/util/NativeCallStubGraphBuilder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.ffi.amd64/src/com/oracle/graal/ffi/amd64/util/NativeCallStubGraphBuilder.java Thu Jan 30 09:19:45 2014 +0100 @@ -0,0 +1,271 @@ +/* + * 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.ffi.amd64.util; + +import java.util.*; + +import sun.misc.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.ffi.amd64.*; +import com.oracle.graal.ffi.amd64.node.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.virtual.*; +import com.oracle.graal.word.phases.*; + +/** + * Utility that creates a Graal graph. The graph represents the native call stub for a foreign + * target function. + * + */ +public class NativeCallStubGraphBuilder { + + private static final ResolvedJavaType integerJavaType = HotSpotResolvedObjectType.fromClass(Integer.class); + private static final ResolvedJavaField[] integerInstanceFields = integerJavaType.getInstanceFields(false); + private static final ResolvedJavaField integerValueField = getValueField(integerInstanceFields); + + private static final ResolvedJavaType longJavaType = HotSpotResolvedObjectType.fromClass(Long.class); + private static final ResolvedJavaField[] longInstanceFields = longJavaType.getInstanceFields(false); + private static final ResolvedJavaField longValueField = getValueField(longInstanceFields); + + private static final ResolvedJavaType charJavaType = HotSpotResolvedObjectType.fromClass(Character.class); + private static final ResolvedJavaField[] charInstanceFields = charJavaType.getInstanceFields(false); + private static final ResolvedJavaField charValueField = getValueField(charInstanceFields); + + private static final ResolvedJavaType byteJavaType = HotSpotResolvedObjectType.fromClass(Byte.class); + private static final ResolvedJavaField[] byteInstanceFields = byteJavaType.getInstanceFields(false); + private static final ResolvedJavaField byteValueField = getValueField(byteInstanceFields); + + private static final ResolvedJavaType floatJavaType = HotSpotResolvedObjectType.fromClass(Float.class); + private static final ResolvedJavaField[] floatInstanceFields = floatJavaType.getInstanceFields(false); + private static final ResolvedJavaField floatValueField = getValueField(floatInstanceFields); + + private static final ResolvedJavaType doubleJavaType = HotSpotResolvedObjectType.fromClass(Double.class); + private static final ResolvedJavaField[] doubleInstanceFields = doubleJavaType.getInstanceFields(false); + private static final ResolvedJavaField doubleValueField = getValueField(doubleInstanceFields); + + private static ResolvedJavaField getValueField(ResolvedJavaField[] fields) { + for (ResolvedJavaField field : fields) { + if (field.getName().equals("value")) { + return field; + } + } + throw new AssertionError("value field not found!"); + } + + /** + * Creates a Graal graph that represents the call stub for a foreign target function. + * + * @param providers the HotSpot providers + * @param functionPointer a function pointer that points to the foreign target function + * @param returnType the type of the return value + * @param argumentTypes the types of the arguments + * @return the graph that represents the call stub + */ + public static StructuredGraph getGraph(HotSpotProviders providers, AMD64NativeFunctionPointer functionPointer, Class returnType, Class[] argumentTypes) { + ResolvedJavaMethod method; + try { + method = providers.getMetaAccess().lookupJavaMethod(NativeCallStubGraphBuilder.class.getMethod("libCall", Object.class, Object.class, Object.class)); + StructuredGraph g = new StructuredGraph(method); + ParameterNode arg0 = g.unique(new ParameterNode(0, StampFactory.forKind(Kind.Object))); + ParameterNode arg1 = g.unique(new ParameterNode(1, StampFactory.forKind(Kind.Object))); + ParameterNode arg2 = g.unique(new ParameterNode(2, StampFactory.forKind(Kind.Object))); + FrameState frameState = g.add(new FrameState(method, 0, Arrays.asList(new ValueNode[]{arg0, arg1, arg2}), 3, 0, false, false, new ArrayList(), + new ArrayList())); + g.start().setStateAfter(frameState); + List parameters = new ArrayList<>(); + FixedWithNextNode fixedWithNext = getParameters(g, arg0, argumentTypes.length, argumentTypes, parameters, providers); + Constant functionPointerNode = Constant.forLong(functionPointer.asRawValue()); + + ValueNode[] arguments = new ValueNode[parameters.size()]; + + for (int i = 0; i < arguments.length; i++) { + arguments[i] = parameters.get(i); + } + + AMD64RawNativeCallNode callNode = g.add(new AMD64RawNativeCallNode(getKind(returnType), functionPointerNode, arguments)); + + if (fixedWithNext == null) { + g.start().setNext(callNode); + } else { + fixedWithNext.setNext(callNode); + } + + // box result + BoxNode boxedResult; + if (callNode.kind() != Kind.Void) { + ResolvedJavaType type = getResolvedJavaType(callNode.kind()); + boxedResult = new BoxNode(callNode, type, callNode.kind()); + } else { + boxedResult = new BoxNode(ConstantNode.forLong(0, g), longJavaType, Kind.Long); + } + + // box result: + BoxNode boxNode = g.unique(boxedResult); + + ReturnNode returnNode = g.add(new ReturnNode(boxNode)); + callNode.setNext(returnNode); + (new WordTypeRewriterPhase(providers.getMetaAccess(), Kind.Long)).apply(g); + return g; + } catch (NoSuchMethodException | SecurityException e) { + throw GraalInternalError.shouldNotReachHere("Call Stub method not found"); + } + } + + private static FixedWithNextNode getParameters(StructuredGraph g, ParameterNode argumentsArray, int numArgs, Class[] argumentClass, List args, HotSpotProviders providers) { + assert numArgs == argumentClass.length; + FixedWithNextNode fixedWithNext = null; + for (int i = 0; i < numArgs; i++) { + // load boxed array element: + LoadIndexedNode boxedElement = g.add(new LoadIndexedNode(argumentsArray, ConstantNode.forInt(i, g), Kind.Object)); + if (i == 0) { + g.start().setNext(boxedElement); + fixedWithNext = boxedElement; + } else { + fixedWithNext.setNext(boxedElement); + fixedWithNext = boxedElement; + } + if (getKind(argumentClass[i]) == Kind.Object) { + // array value + Kind arrayElementKind = getArrayValuesKind(argumentClass[i]); + LocationIdentity locationIdentity = NamedLocationIdentity.getArrayLocation(arrayElementKind); + IndexedLocationNode locationNode = IndexedLocationNode.create(locationIdentity, arrayElementKind, HotSpotGraalRuntime.getArrayBaseOffset(arrayElementKind), ConstantNode.forInt(0, g), + g, HotSpotGraalRuntime.getArrayIndexScale(arrayElementKind)); + ComputeAddressNode arrayAddress = g.unique(new ComputeAddressNode(boxedElement, locationNode, StampFactory.forKind(providers.getCodeCache().getTarget().wordKind))); + args.add(arrayAddress); + } else { + // boxed primitive value + LoadFieldNode loadFieldNode = g.add(new LoadFieldNode(boxedElement, getResolvedJavaField(argumentClass[i]))); + fixedWithNext.setNext(loadFieldNode); + fixedWithNext = loadFieldNode; + args.add(loadFieldNode); + } + } + return fixedWithNext; + } + + public static int getArrayValuesObjectOffset(Class clazz) { + if (clazz == int[].class) { + return Unsafe.ARRAY_INT_BASE_OFFSET; + } else if (clazz == long[].class) { + return Unsafe.ARRAY_LONG_BASE_OFFSET; + } else if (clazz == char[].class) { + return Unsafe.ARRAY_CHAR_BASE_OFFSET; + } else if (clazz == byte[].class) { + return Unsafe.ARRAY_BYTE_BASE_OFFSET; + } else if (clazz == float[].class) { + return Unsafe.ARRAY_FLOAT_BASE_OFFSET; + } else if (clazz == double[].class) { + return Unsafe.ARRAY_DOUBLE_BASE_OFFSET; + } else { + throw new IllegalArgumentException("Array Type not supported: " + clazz); + } + } + + public static Kind getArrayValuesKind(Class clazz) { + if (clazz == int[].class) { + return Kind.Int; + } else if (clazz == long[].class) { + return Kind.Long; + } else if (clazz == char[].class) { + return Kind.Char; + } else if (clazz == byte[].class) { + return Kind.Byte; + } else if (clazz == float[].class) { + return Kind.Float; + } else if (clazz == double[].class) { + return Kind.Double; + } else { + throw new IllegalArgumentException("Array Type not supported: " + clazz); + } + } + + private static Kind getKind(Class clazz) { + if (clazz == int.class || clazz == Integer.class) { + return Kind.Int; + } else if (clazz == long.class || clazz == Long.class) { + return Kind.Long; + } else if (clazz == char.class || clazz == Character.class) { + return Kind.Char; + } else if (clazz == byte.class || clazz == Byte.class) { + return Kind.Byte; + } else if (clazz == float.class || clazz == Float.class) { + return Kind.Float; + } else if (clazz == double.class || clazz == Double.class) { + return Kind.Double; + } else if (clazz == int[].class || clazz == long[].class || clazz == char[].class || clazz == byte[].class || clazz == float[].class || clazz == double[].class) { + return Kind.Object; + } else if (clazz == void.class) { + return Kind.Void; + } else { + throw new IllegalArgumentException("Type not supported: " + clazz); + } + } + + private static ResolvedJavaField getResolvedJavaField(Class containerClass) { + if (containerClass == int.class || containerClass == Integer.class) { + return integerValueField; + } else if (containerClass == long.class || containerClass == Long.class) { + return longValueField; + } else if (containerClass == char.class || containerClass == Character.class) { + return charValueField; + } else if (containerClass == byte.class || containerClass == Byte.class) { + return byteValueField; + } else if (containerClass == float.class || containerClass == Float.class) { + return floatValueField; + } else if (containerClass == double.class || containerClass == Double.class) { + return doubleValueField; + } else { + throw new IllegalArgumentException("Type not supported: " + containerClass); + } + } + + private static ResolvedJavaType getResolvedJavaType(Kind kind) { + if (kind == Kind.Int) { + return integerJavaType; + } else if (kind == Kind.Long) { + return longJavaType; + } else if (kind == Kind.Char) { + return charJavaType; + } else if (kind == Kind.Byte) { + return byteJavaType; + } else if (kind == Kind.Float) { + return floatJavaType; + } else if (kind == Kind.Double) { + return doubleJavaType; + } else { + throw GraalInternalError.shouldNotReachHere(); + } + } + + @SuppressWarnings("unused") + public static Object libCall(Object argLoc, Object unused1, Object unused2) { + throw GraalInternalError.shouldNotReachHere("GNFI Callstub method must not be called!"); + } +} diff -r 64c77f0577bb -r ed3a1471e133 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 Thu Jan 30 17:53:27 2014 -0800 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Thu Jan 30 09:19:45 2014 +0100 @@ -40,6 +40,7 @@ import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; +import com.oracle.graal.ffi.amd64.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.meta.*; @@ -306,4 +307,15 @@ } } } + + @Override + public NativeFunctionInterface getNativeFunctionInterface() { + AMD64NativeFunctionPointer libraryLoadPointer = new AMD64NativeFunctionPointer(getRuntime().getConfig().libraryLoadAddress, "GNFI_UTIL_LOADLIBRARY"); + AMD64NativeFunctionPointer functionLookupPointer = new AMD64NativeFunctionPointer(getRuntime().getConfig().functionLookupAddress, "GNFI_UTIL_FUNCTIONLOOKUP"); + AMD64NativeLibraryHandle rtldDefault = new AMD64NativeLibraryHandle(getRuntime().getConfig().rtldDefault); + if (!libraryLoadPointer.isValid() || !functionLookupPointer.isValid()) { + throw new AssertionError("Lookup Pointers null"); + } + return new AMD64NativeFunctionInterface(this.getProviders(), this, libraryLoadPointer, functionLookupPointer, rtldDefault); + } } diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Thu Jan 30 17:53:27 2014 -0800 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Thu Jan 30 09:19:45 2014 +0100 @@ -350,6 +350,22 @@ } @Override + public void emitCCall(long address, CallingConvention nativeCallingConvention, Value[] args, int numberOfFloatingPointArguments) { + Value[] argLocations = new Value[args.length]; + frameMap.callsMethod(nativeCallingConvention); + AllocatableValue numberOfFloatingPointArgumentsRegister = AMD64.rax.asValue(); + emitMove(numberOfFloatingPointArgumentsRegister, Constant.forInt(numberOfFloatingPointArguments)); + for (int i = 0; i < args.length; i++) { + Value arg = args[i]; + AllocatableValue loc = nativeCallingConvention.getArgument(i); + emitMove(loc, arg); + argLocations[i] = loc; + } + Value ptr = emitMove(Constant.forLong(address)); + append(new AMD64CCall(nativeCallingConvention.getReturn(), ptr, numberOfFloatingPointArgumentsRegister, argLocations)); + } + + @Override protected void emitDirectCall(DirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { InvokeKind invokeKind = ((HotSpotDirectCallTargetNode) callTarget).invokeKind(); if (invokeKind == InvokeKind.Interface || invokeKind == InvokeKind.Virtual) { diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Thu Jan 30 17:53:27 2014 -0800 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Thu Jan 30 09:19:45 2014 +0100 @@ -414,4 +414,9 @@ codeBuffer.emitString0("};"); codeBuffer.emitString(""); } + + @Override + public NativeFunctionInterface getNativeFunctionInterface() { + throw GraalInternalError.unimplemented("No NativeFunctionInterface of HSAIL"); + } } diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java Thu Jan 30 17:53:27 2014 -0800 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackend.java Thu Jan 30 09:19:45 2014 +0100 @@ -484,4 +484,10 @@ private static native int getAvailableProcessors0(); + + @Override + public NativeFunctionInterface getNativeFunctionInterface() { + throw GraalInternalError.unimplemented("No NativeFunctionInterface of PTX"); + } + } diff -r 64c77f0577bb -r ed3a1471e133 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 Thu Jan 30 17:53:27 2014 -0800 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Thu Jan 30 09:19:45 2014 +0100 @@ -227,4 +227,9 @@ SPARCCall.indirectJmp(crb, masm, scratch, foreignCalls.lookupForeignCall(IC_MISS_HANDLER)); } } + + @Override + public NativeFunctionInterface getNativeFunctionInterface() { + throw GraalInternalError.unimplemented("No NativeFunctionInterface of SPARC"); + } } diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Thu Jan 30 17:53:27 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Thu Jan 30 09:19:45 2014 +0100 @@ -840,6 +840,10 @@ @HotSpotVMField(name = "JavaThread::_vm_result", type = "oop", get = HotSpotVMField.Type.OFFSET) @Stable public int threadObjectResultOffset; @HotSpotVMField(name = "JavaThread::_graal_counters[0]", type = "jlong", get = HotSpotVMField.Type.OFFSET, optional = true) @Stable public int graalCountersThreadOffset; + @HotSpotVMConstant(name = "libraryLoadAddress") @Stable public long libraryLoadAddress; + @HotSpotVMConstant(name = "functionLookupAddress") @Stable public long functionLookupAddress; + @HotSpotVMConstant(name = "rtldDefault") @Stable public long rtldDefault; + /** * This field is used to pass exception objects into and out of the runtime system during * exception handling for compiled code. diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Thu Jan 30 17:53:27 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Thu Jan 30 09:19:45 2014 +0100 @@ -718,4 +718,14 @@ throw new GraalInternalError(e); } } + + @Fold + public static long dllLoad() { + return config().libraryLoadAddress; + } + + @Fold + public static long dllLookup() { + return config().functionLookupAddress; + } } diff -r 64c77f0577bb -r ed3a1471e133 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64CCall.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64CCall.java Thu Jan 30 09:19:45 2014 +0100 @@ -0,0 +1,62 @@ +/* + * 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.lir.amd64; + +import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.lir.asm.*; + +public class AMD64CCall extends AMD64LIRInstruction { + + @Def({REG, ILLEGAL}) protected Value result; + @Use({REG, STACK}) protected Value[] parameters; + @Use({REG}) protected Value functionPtr; + @Use({REG}) protected Value numberOfFloatingPointArguments; + + public AMD64CCall(Value result, Value functionPtr, Value numberOfFloatingPointArguments, Value[] parameters) { + this.result = result; + this.functionPtr = functionPtr; + this.parameters = parameters; + this.numberOfFloatingPointArguments = numberOfFloatingPointArguments; + } + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + directCall(masm); + } + + private void directCall(AMD64MacroAssembler masm) { + Register reg = ValueUtil.asRegister(functionPtr); + masm.call(reg); + masm.ensureUniquePC(); + } + + @Override + public boolean destroysCallerSavedRegisters() { + return true; + } + +} diff -r 64c77f0577bb -r ed3a1471e133 mx/projects --- a/mx/projects Thu Jan 30 17:53:27 2014 -0800 +++ b/mx/projects Thu Jan 30 09:19:45 2014 +0100 @@ -184,7 +184,7 @@ # graal.hotspot.amd64 project@com.oracle.graal.hotspot.amd64@subDir=graal project@com.oracle.graal.hotspot.amd64@sourceDirs=src -project@com.oracle.graal.hotspot.amd64@dependencies=com.oracle.graal.hotspot,com.oracle.graal.compiler.amd64,com.oracle.graal.replacements.amd64 +project@com.oracle.graal.hotspot.amd64@dependencies=com.oracle.graal.ffi.amd64,com.oracle.graal.replacements.amd64 project@com.oracle.graal.hotspot.amd64@checkstyle=com.oracle.graal.graph project@com.oracle.graal.hotspot.amd64@annotationProcessors=com.oracle.graal.service.processor project@com.oracle.graal.hotspot.amd64@javaCompliance=1.7 @@ -651,6 +651,22 @@ project@com.oracle.graal.asm.sparc@javaCompliance=1.7 project@com.oracle.graal.asm.sparc@workingSets=Graal,Assembler,SPARC +# graal.ffi.amd64 +project@com.oracle.graal.ffi.amd64@subDir=graal +project@com.oracle.graal.ffi.amd64@sourceDirs=src +project@com.oracle.graal.ffi.amd64@dependencies=com.oracle.graal.compiler.amd64,com.oracle.graal.hotspot +project@com.oracle.graal.ffi.amd64@checkstyle=com.oracle.graal.graph +project@com.oracle.graal.ffi.amd64@javaCompliance=1.7 +project@com.oracle.graal.ffi.amd64.test@workingSets=Graal,AMD64 + +# graal.ffi.amd64.test +project@com.oracle.graal.ffi.amd64.test@subDir=graal +project@com.oracle.graal.ffi.amd64.test@sourceDirs=test +project@com.oracle.graal.ffi.amd64.test@dependencies=JUNIT,com.oracle.graal.runtime +project@com.oracle.graal.ffi.amd64.test@checkstyle=com.oracle.graal.graph +project@com.oracle.graal.ffi.amd64.test@javaCompliance=1.7 +project@com.oracle.graal.ffi.amd64.test@workingSets=Graal,AMD64,Test + # truffle.api project@com.oracle.truffle.api@subDir=graal project@com.oracle.truffle.api@sourceDirs=src diff -r 64c77f0577bb -r ed3a1471e133 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Thu Jan 30 17:53:27 2014 -0800 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Thu Jan 30 09:19:45 2014 +0100 @@ -554,7 +554,17 @@ //------------------------------------------------------------------------------------------------ set_int("graalCountersThreadOffset", in_bytes(JavaThread::graal_counters_offset())); - set_int("graalCountersSize", (jint) GraalCounterSize); + set_int("graalCountersSize", (jint) GraalCounterSize);\ + + //------------------------------------------------------------------------------------------------ + + set_long("libraryLoadAddress", (jlong) os::dll_load); + set_long("functionLookupAddress", (jlong) os::dll_lookup); + #if defined(TARGET_OS_FAMILY_bsd) || defined(TARGET_OS_FAMILY_linux) + set_long("rtldDefault", (jlong) RTLD_DEFAULT); + #else + set_long("rtldDefault", (jlong) 0xDEADFACE); //TODO(mg): will crash on java side, not supported! + #endif #undef set_boolean #undef set_int