changeset 13895:4731c1a0b1f3

consolidated GNFI code into graal.hotspot project and cleaned up the documentation and code
author Doug Simon <doug.simon@oracle.com>
date Thu, 06 Feb 2014 18:44:14 +0100
parents 4fa77c58ad8f
children cf1f97283122
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionHandle.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionInterface.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionPointer.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeLibraryHandle.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/nfi/NativeFunctionInterfaceTest.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64RawNativeCallNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionHandle.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionPointer.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeLibraryHandle.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/RawNativeCallNodeFactory.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java graal/com.oracle.graal.nfi.hotspot.amd64/src/com/oracle/graal/nfi/hotspot/amd64/AMD64HotSpotNativeFunctionHandle.java graal/com.oracle.graal.nfi.hotspot.amd64/src/com/oracle/graal/nfi/hotspot/amd64/AMD64HotSpotNativeFunctionInterface.java graal/com.oracle.graal.nfi.hotspot.amd64/src/com/oracle/graal/nfi/hotspot/amd64/AMD64HotSpotNativeFunctionPointer.java graal/com.oracle.graal.nfi.hotspot.amd64/src/com/oracle/graal/nfi/hotspot/amd64/AMD64HotSpotNativeLibraryHandle.java graal/com.oracle.graal.nfi.hotspot.amd64/src/com/oracle/graal/nfi/hotspot/amd64/node/AMD64RawNativeCallNode.java graal/com.oracle.graal.nfi.hotspot.amd64/src/com/oracle/graal/nfi/hotspot/amd64/util/InstallUtil.java graal/com.oracle.graal.nfi.hotspot.amd64/src/com/oracle/graal/nfi/hotspot/amd64/util/NativeCallStubGraphBuilder.java graal/com.oracle.graal.nfi.test/test/com/oracle/graal/nfi/test/LibCallTest.java graal/com.oracle.graal.nfi.test/test/com/oracle/graal/nfi/test/MathLibCallTest.java graal/com.oracle.graal.nfi.test/test/com/oracle/graal/nfi/test/StdLibCallTest.java mx/projects src/share/vm/graal/graalCompilerToVM.cpp
diffstat 27 files changed, 988 insertions(+), 1237 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionHandle.java	Thu Feb 06 18:42:45 2014 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionHandle.java	Thu Feb 06 18:44:14 2014 +0100
@@ -23,28 +23,25 @@
 package com.oracle.graal.api.code;
 
 /**
- * The handle of a native foreign function. Use a {@code NativeFunctionHandle} to invoke native
- * target functions.
- * <p>
- * The user of a {@code NativeFunctionHandle} has to pack the boxed arguments into an
- * {@code Object[]} according to the ABI of the target platform (e.g. Unix AMD64 system:
- * {@link "http://www.uclibc.org/docs/psABI-x86_64.pdf"}). The {@code NativeFunctionHandle} unboxes
- * the arguments and places them into the right location (register / stack) according to the ABI.
- * <p>
- * A {@code NativeFunctionHandle} returns the boxed return value of the native target function. The
- * boxed value is the return value as specified by the ABI.
+ * A handle that can be used to {@linkplain #call(Object[]) call} a native function.
  */
 public interface NativeFunctionHandle {
 
     /**
-     * Calls the native foreign function.
+     * Calls the native function.
+     * <p>
+     * The caller is responsible for ensuring {@code args} comply with the platform ABI (e.g. <a
+     * href="http://www.uclibc.org/docs/psABI-x86_64.pdf"> Unix AMD64 ABI</a>). 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 foreign function
+     * @param args the arguments that will be passed to the native function
+     * @return boxed return value of the function call
      */
-    Object call(Object[] args);
+    Object call(Object... args);
 
     /**
-     * Returns the installed code of the call stub for the native foreign function call.
+     * Returns the installed code of the call stub for the native function call.
      * 
      * @return the installed code of the native call stub
      */
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionInterface.java	Thu Feb 06 18:42:45 2014 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionInterface.java	Thu Feb 06 18:44:14 2014 +0100
@@ -23,91 +23,91 @@
 package com.oracle.graal.api.code;
 
 /**
- * Interface to resolve a {@code NativeFunctionHandle} or a {@code NativeFunctionPointer} to a
- * native foreign function and a {@code NativeLibraryHandle} of a library. A
- * {@code NativeFunctionPointer} wraps the raw function pointer. A {@code NativeFunctionHandle} is a
- * callable representation of a native target function in Java.
- * <p>
- * To resolve a {@code NativeFunctionHandle}, one has to provide the signature of the native target
- * function according to the calling convention of the target platform (e.g. Unix AMD64:
- * {@link "http://www.uclibc.org/docs/psABI-x86_64.pdf"}). The signature contains the type (e.g.
- * {@code int.class} for a C integer, ( {@code long.class} for a 64bit pointer) of each value, which
- * is passed to the native target function.
+ * 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 library handle.
+     * 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);
 
     /**
-     * Resolves the {@code NativeFunctionHandle} of a native function that can be called. Use a
-     * {@code NativeFunctionHandle} to invoke the native target function.
+     * Resolves the function pointer {@code NativeFunctionPointer} of a native function.
      * 
-     * @param libraryHandle the handle to a resolved library
-     * @param functionName the name of the function to be resolved
+     * @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 foreign function
+     * @return the function handle of the native function
+     * @throws UnsatisfiedLinkError if the function handle could not be resolved
      */
-    NativeFunctionHandle getFunctionHandle(NativeLibraryHandle libraryHandle, String functionName, Class returnType, Class[] argumentTypes);
-
-    /**
-     * Resolves the {@code NativeFunctionHandle} of a native function that can be called. Use a
-     * {@code NativeFunctionHandle} to invoke the native target function.
-     * 
-     * @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);
+    NativeFunctionHandle getFunctionHandle(NativeLibraryHandle library, String name, Class returnType, Class... argumentTypes);
 
     /**
-     * Resolves the function pointer {@code NativeFunctionPointer} of a native function. A
-     * {@code NativeFunctionPointer} wraps the raw pointer value.
+     * 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 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
+     * @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 if the function handle could not be created
      */
-    NativeFunctionPointer getFunctionPointer(NativeLibraryHandle[] libraryHandles, String functionName);
+    NativeFunctionHandle getFunctionHandle(NativeFunctionPointer functionPointer, Class returnType, Class... argumentTypes);
 
     /**
-     * Resolves the {@code NativeFunctionHandle} of a native function that can be called. Use a
-     * {@code NativeFunctionHandle} to invoke the native target function.
+     * 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 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 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 foreign function
+     * @return the function handle of the native function
+     * @throws UnsatisfiedLinkError if the function handle could not be created
      */
-    NativeFunctionHandle getFunctionHandle(NativeLibraryHandle[] libraryHandles, String functionName, Class returnType, Class[] argumentTypes);
+    NativeFunctionHandle getFunctionHandle(NativeLibraryHandle[] libraries, String name, Class returnType, Class... argumentTypes);
 
     /**
-     * Resolves the {@code NativeFunctionHandle} of a native function that can be called. Use a
-     * {@code NativeFunctionHandle} to invoke the native target function.
+     * 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 functionName the name of the function to be resolved
+     * @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 foreign function
+     * @return the function handle of the native function
+     * @throws UnsatisfiedLinkError if the function could not be resolved
      */
-    NativeFunctionHandle getFunctionHandle(String functionName, Class returnType, Class[] argumentTypes);
+    NativeFunctionHandle getFunctionHandle(String name, Class returnType, Class... argumentTypes);
 
     /**
-     * Creates {@code NativeFunctionPointer} from raw value. A {@code NativeFunctionPointer} wraps
-     * the raw pointer value.
+     * Creates a {@link NativeFunctionPointer} from a raw value.
      * 
-     * @param rawValue Raw pointer value
-     * @return {@code NativeFunctionPointer} of the raw pointer
+     * @param rawValue raw function pointer
+     * @return {@code NativeFunctionPointer} for {@code rawValue}
      */
     NativeFunctionPointer getNativeFunctionPointerFromRawValue(long rawValue);
 }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionPointer.java	Thu Feb 06 18:42:45 2014 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionPointer.java	Thu Feb 06 18:44:14 2014 +0100
@@ -23,32 +23,19 @@
 package com.oracle.graal.api.code;
 
 /**
- * Wraps the raw function pointer value.
+ * An opaque representation of a native function pointer.
  * <p>
- * Use the {@code NativeFunctionInterface} to resolve a {@code NativeFunctionHandle} of this pointer
- * to invoke the native target function.
+ * 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 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();
+    String getName();
 
 }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeLibraryHandle.java	Thu Feb 06 18:42:45 2014 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeLibraryHandle.java	Thu Feb 06 18:44:14 2014 +0100
@@ -23,24 +23,10 @@
 package com.oracle.graal.api.code;
 
 /**
- * The library handle of the native library.
- * <p>
- * The {@code NativeFunctionInterface} can use a {@code NativeLibraryHandle} to look up a
- * {@code NativeFunctionPointer} or a {@code NativeFunctionHandle} in this library.
+ * 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 {
-
-    /**
-     * 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();
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/nfi/NativeFunctionInterfaceTest.java	Thu Feb 06 18:44:14 2014 +0100
@@ -0,0 +1,212 @@
+/*
+ * 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.graph.UnsafeAccess.*;
+import static org.junit.Assert.*;
+
+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.*;
+
+public class NativeFunctionInterfaceTest {
+
+    public final RuntimeProvider runtimeProvider;
+    public final NativeFunctionInterface ffi;
+
+    public NativeFunctionInterfaceTest() {
+        this.runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class);
+        Assume.assumeTrue(runtimeProvider.getHostBackend() instanceof HostBackend);
+        ffi = ((HostBackend) runtimeProvider.getHostBackend()).getNativeFunctionInterface();
+    }
+
+    private List<Long> 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() {
+
+        NativeFunctionHandle malloc = ffi.getFunctionHandle("malloc", long.class, int.class);
+        NativeFunctionHandle snprintf = ffi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class);
+        NativeFunctionHandle free = ffi.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() {
+        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 = ffi.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() {
+        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 = ffi.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() {
+        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 = ffi.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() {
+        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 = ffi.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() {
+        NativeFunctionHandle handle = ffi.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() {
+        double result = 0;
+        NativeFunctionHandle handle = ffi.getFunctionHandle("pow", double.class, double.class, double.class);
+        for (int i = 0; i < 100000; i++) {
+            result = (double) handle.call(3D, 5.5D);
+        }
+        assertEquals(Math.pow(3D, 5.5D), result, 0);
+    }
+}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Thu Feb 06 18:42:45 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Thu Feb 06 18:44:14 2014 +0100
@@ -40,15 +40,14 @@
 import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.nfi.*;
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
-import com.oracle.graal.nfi.hotspot.amd64.*;
 import com.oracle.graal.nodes.*;
 
 /**
@@ -311,12 +310,12 @@
 
     @Override
     public NativeFunctionInterface getNativeFunctionInterface() {
-        AMD64HotSpotNativeFunctionPointer libraryLoadPointer = new AMD64HotSpotNativeFunctionPointer(getRuntime().getConfig().libraryLoadAddress, "GNFI_UTIL_LOADLIBRARY");
-        AMD64HotSpotNativeFunctionPointer functionLookupPointer = new AMD64HotSpotNativeFunctionPointer(getRuntime().getConfig().functionLookupAddress, "GNFI_UTIL_FUNCTIONLOOKUP");
-        AMD64HotSpotNativeLibraryHandle rtldDefault = new AMD64HotSpotNativeLibraryHandle(getRuntime().getConfig().rtldDefault);
-        if (!libraryLoadPointer.isValid() || !functionLookupPointer.isValid()) {
-            throw GraalInternalError.shouldNotReachHere("Lookup Pointers null");
-        }
-        return new AMD64HotSpotNativeFunctionInterface(this.getProviders(), this, libraryLoadPointer, functionLookupPointer, rtldDefault);
+        HotSpotVMConfig config = getRuntime().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);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64RawNativeCallNode.java	Thu Feb 06 18:44:14 2014 +0100
@@ -0,0 +1,76 @@
+/*
+ * 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.hotspot.amd64;
+
+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<ValueNode> 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) {
+        AMD64LIRGenerator gen = (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(gen.getMetaAccess());
+        }
+        ResolvedJavaType returnType = stamp().javaType(gen.getMetaAccess());
+        CallingConvention cc = generator.getCodeCache().getRegisterConfig().getCallingConvention(Type.NativeCall, returnType, parameterTypes, generator.target(), false);
+        gen.emitCCall(functionPointer.asLong(), cc, parameter, countFloatingTypeArguments(args));
+        if (this.kind() != Kind.Void) {
+            generator.setResult(this, gen.emitMove(cc.getReturn()));
+        }
+    }
+
+    private static int countFloatingTypeArguments(NodeInputList<ValueNode> 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;
+    }
+
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Thu Feb 06 18:42:45 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Thu Feb 06 18:44:14 2014 +0100
@@ -840,14 +840,35 @@
     @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;
 
-    // The native side (graalCompilerToVM.cpp) sets the rtldDefault if the
-    // platform is NOT Windows (Windows is currently not supported).
-    // AMD64NativeFunctionInterface checks if rtld_default handle is valid.
-    // Using 0 is not possible as it is a valid value for rtldDefault on some platforms.
+    /**
+     * An invalid value for {@link #rtldDefault}.
+     */
     public static final long INVALID_RTLD_DEFAULT_HANDLE = 0xDEADFACE;
 
-    @Stable public long libraryLoadAddress;
-    @Stable public long functionLookupAddress;
+    /**
+     * Address of the library lookup routine. The C signature of this routine is:
+     * 
+     * <pre>
+     *     void* (const char *filename, char *ebuf, int ebuflen)
+     * </pre>
+     */
+    @Stable public long dllLoad;
+
+    /**
+     * Address of the library lookup routine. The C signature of this routine is:
+     * 
+     * <pre>
+     *     void* (void* handle, const char* name)
+     * </pre>
+     */
+    @Stable public long dllLookup;
+
+    /**
+     * A pseudo-handle which when used as the first argument to {@link #dllLookup} means
+     * lookup will return the first occurrence of the desired symbol using the default library
+     * search order. If this field is {@value #INVALID_RTLD_DEFAULT_HANDLE}, then this capability is
+     * not supported on the current platform.
+     */
     @Stable public long rtldDefault = INVALID_RTLD_DEFAULT_HANDLE;
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionHandle.java	Thu Feb 06 18:44:14 2014 +0100
@@ -0,0 +1,98 @@
+/*
+ * 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.hotspot.nfi;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
+import com.oracle.graal.graph.*;
+
+public class HotSpotNativeFunctionHandle implements NativeFunctionHandle {
+
+    private final InstalledCode code;
+    private final String name;
+    private final Class[] argumentTypes;
+
+    public HotSpotNativeFunctionHandle(InstalledCode code, String name, Class... argumentTypes) {
+        this.argumentTypes = argumentTypes;
+        this.name = name;
+        this.code = code;
+    }
+
+    private void traceCall(Object... args) {
+        try (Scope s = Debug.scope("GNFI")) {
+            if (Debug.isLogEnabled()) {
+                Debug.log("[GNFI] %s%s", name, Arrays.toString(args));
+            }
+        }
+    }
+
+    private void traceResult(Object result) {
+        try (Scope s = Debug.scope("GNFI")) {
+            if (Debug.isLogEnabled()) {
+                Debug.log("[GNFI] %s --> %s", name, result);
+            }
+        }
+    }
+
+    @Override
+    public Object call(Object... args) {
+        assert checkArgs(args);
+        try {
+            traceCall(args);
+            Object res = code.execute(args, null, null);
+            traceResult(res);
+            return res;
+        } catch (InvalidInstalledCodeException e) {
+            throw GraalInternalError.shouldNotReachHere("Execution of GNFI Callstub failed: " + name);
+        }
+    }
+
+    private boolean checkArgs(Object... args) {
+        assert args.length == argumentTypes.length : this + " expected " + argumentTypes.length + " args, got " + args.length;
+        for (int i = 0; i < argumentTypes.length; i++) {
+            Object arg = args[i];
+            assert arg != null;
+            Class expectedType = argumentTypes[i];
+            if (expectedType.isPrimitive()) {
+                Kind kind = Kind.fromJavaClass(expectedType);
+                expectedType = kind.toBoxedJavaClass();
+            }
+            assert expectedType == arg.getClass() : this + " expected arg " + i + " to be " + expectedType.getName() + ", not " + arg.getClass().getName();
+
+        }
+        return true;
+    }
+
+    public InstalledCode getCallStub() {
+        return code;
+    }
+
+    @Override
+    public String toString() {
+        return name + Arrays.toString(argumentTypes);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java	Thu Feb 06 18:44:14 2014 +0100
@@ -0,0 +1,187 @@
+/*
+ * 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.hotspot.nfi;
+
+import static com.oracle.graal.api.code.CodeUtil.*;
+import static com.oracle.graal.graph.UnsafeAccess.*;
+import static com.oracle.graal.hotspot.nfi.NativeCallStubGraphBuilder.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CallingConvention.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.ProfilingInfo.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.*;
+import com.oracle.graal.hotspot.*;
+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.*;
+
+public class HotSpotNativeFunctionInterface implements NativeFunctionInterface {
+
+    private final HotSpotProviders providers;
+    private final Backend backend;
+    private final HotSpotNativeLibraryHandle rtldDefault;
+    private final HotSpotNativeFunctionPointer libraryLoadFunctionPointer;
+    private final HotSpotNativeFunctionPointer functionLookupFunctionPointer;
+    private final RawNativeCallNodeFactory factory;
+
+    private HotSpotNativeFunctionHandle libraryLookupFunctionHandle;
+    private HotSpotNativeFunctionHandle dllLookupFunctionHandle;
+
+    public HotSpotNativeFunctionInterface(HotSpotProviders providers, RawNativeCallNodeFactory factory, Backend backend, long dlopen, long dlsym, long rtldDefault) {
+        this.rtldDefault = rtldDefault == HotSpotVMConfig.INVALID_RTLD_DEFAULT_HANDLE ? null : new HotSpotNativeLibraryHandle("RTLD_DEFAULT", rtldDefault);
+        this.providers = providers;
+        this.backend = backend;
+        this.factory = factory;
+        this.libraryLoadFunctionPointer = new HotSpotNativeFunctionPointer(dlopen, "os::dll_load");
+        this.functionLookupFunctionPointer = new HotSpotNativeFunctionPointer(dlsym, "os::dll_lookup");
+    }
+
+    @Override
+    public HotSpotNativeLibraryHandle getLibraryHandle(String libPath) {
+        if (libraryLookupFunctionHandle == null) {
+            libraryLookupFunctionHandle = createHandle(libraryLoadFunctionPointer, long.class, long.class, long.class, int.class);
+        }
+
+        int ebufLen = 1024;
+        // Allocating a single chunk for both the error message buffer and the
+        // file name simplifies deallocation below.
+        long buffer = unsafe.allocateMemory(ebufLen + libPath.length() + 1);
+        long ebuf = buffer;
+        long libPathCString = writeCString(libPath, buffer + ebufLen);
+        try {
+            long handle = (long) libraryLookupFunctionHandle.call(libPathCString, ebuf, ebufLen);
+            if (handle == 0) {
+                throw new UnsatisfiedLinkError(libPath);
+            }
+            return new HotSpotNativeLibraryHandle(libPath, handle);
+        } finally {
+            unsafe.freeMemory(buffer);
+        }
+    }
+
+    @Override
+    public HotSpotNativeFunctionHandle getFunctionHandle(NativeLibraryHandle library, String name, Class returnType, Class... argumentTypes) {
+        HotSpotNativeFunctionPointer functionPointer = lookupFunctionPointer(name, library, true);
+        return getFunctionHandle(functionPointer, returnType, argumentTypes);
+    }
+
+    @Override
+    public HotSpotNativeFunctionHandle getFunctionHandle(NativeLibraryHandle[] libraries, String name, Class returnType, Class... argumentTypes) {
+        HotSpotNativeFunctionPointer functionPointer = null;
+        for (NativeLibraryHandle libraryHandle : libraries) {
+            functionPointer = lookupFunctionPointer(name, libraryHandle, false);
+            if (functionPointer != null) {
+                return createHandle(functionPointer, returnType, argumentTypes);
+            }
+        }
+        // Fall back to default library path
+        return getFunctionHandle(name, returnType, argumentTypes);
+    }
+
+    @Override
+    public HotSpotNativeFunctionHandle getFunctionHandle(String name, Class returnType, Class... argumentTypes) {
+        if (rtldDefault == null) {
+            throw new UnsatisfiedLinkError(name);
+        }
+        return getFunctionHandle(rtldDefault, name, returnType, argumentTypes);
+    }
+
+    private HotSpotNativeFunctionPointer lookupFunctionPointer(String name, NativeLibraryHandle library, boolean linkageErrorIfMissing) {
+        if (name == null || library == null) {
+            throw new NullPointerException();
+        }
+        if (dllLookupFunctionHandle == null) {
+            dllLookupFunctionHandle = createHandle(functionLookupFunctionPointer, long.class, long.class, long.class);
+        }
+        long nameCString = createCString(name);
+        try {
+            long functionPointer = (long) dllLookupFunctionHandle.call(((HotSpotNativeLibraryHandle) library).value, nameCString);
+            if (functionPointer == 0L) {
+                if (!linkageErrorIfMissing) {
+                    return null;
+                }
+                throw new UnsatisfiedLinkError(name);
+            }
+            return new HotSpotNativeFunctionPointer(functionPointer, name);
+        } finally {
+            unsafe.freeMemory(nameCString);
+        }
+    }
+
+    @Override
+    public HotSpotNativeFunctionHandle getFunctionHandle(NativeFunctionPointer functionPointer, Class returnType, Class... argumentTypes) {
+        if (!(functionPointer instanceof HotSpotNativeFunctionPointer)) {
+            throw new UnsatisfiedLinkError(functionPointer.getName());
+        }
+        return createHandle(functionPointer, returnType, argumentTypes);
+    }
+
+    private HotSpotNativeFunctionHandle createHandle(NativeFunctionPointer functionPointer, Class returnType, Class... argumentTypes) {
+        HotSpotNativeFunctionPointer hs = (HotSpotNativeFunctionPointer) functionPointer;
+        InstalledCode code = installNativeFunctionStub(hs.value, returnType, argumentTypes);
+        return new HotSpotNativeFunctionHandle(code, hs.name, argumentTypes);
+    }
+
+    /**
+     * Creates and installs a stub for calling a native function.
+     */
+    private InstalledCode installNativeFunctionStub(long functionPointer, Class returnType, Class... argumentTypes) {
+        StructuredGraph g = getGraph(providers, factory, functionPointer, returnType, argumentTypes);
+        Suites suites = providers.getSuites().createSuites();
+        PhaseSuite<HighTierContext> 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), null, 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;
+    }
+
+    @Override
+    public HotSpotNativeFunctionPointer getFunctionPointer(NativeLibraryHandle[] libraries, String name) {
+        for (NativeLibraryHandle libraryHandle : libraries) {
+            HotSpotNativeFunctionPointer functionPointer = lookupFunctionPointer(name, libraryHandle, false);
+            if (functionPointer != null) {
+                return functionPointer;
+            }
+        }
+        // Fall back to default library path
+        if (rtldDefault == null) {
+            throw new UnsatisfiedLinkError(name);
+        }
+        return lookupFunctionPointer(name, rtldDefault, true);
+    }
+
+    @Override
+    public NativeFunctionPointer getNativeFunctionPointerFromRawValue(long rawValue) {
+        return new HotSpotNativeFunctionPointer(rawValue, null);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionPointer.java	Thu Feb 06 18:44:14 2014 +0100
@@ -0,0 +1,52 @@
+/*
+ * 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.hotspot.nfi;
+
+import com.oracle.graal.api.code.*;
+
+public class HotSpotNativeFunctionPointer implements NativeFunctionPointer {
+
+    final long value;
+    final String name;
+
+    public HotSpotNativeFunctionPointer(long value, String name) {
+        if (value == 0) {
+            throw new UnsatisfiedLinkError(name);
+        }
+        this.value = value;
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public long getValue() {
+        return value;
+    }
+
+    @Override
+    public String toString() {
+        return name + "@0x" + Long.toHexString(value);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeLibraryHandle.java	Thu Feb 06 18:44:14 2014 +0100
@@ -0,0 +1,41 @@
+/*
+ * 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.hotspot.nfi;
+
+import com.oracle.graal.api.code.*;
+
+public class HotSpotNativeLibraryHandle implements NativeLibraryHandle {
+
+    final long value;
+    final String name;
+
+    public HotSpotNativeLibraryHandle(String name, long handle) {
+        this.name = name;
+        this.value = handle;
+    }
+
+    @Override
+    public String toString() {
+        return name + "@" + value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java	Thu Feb 06 18:44:14 2014 +0100
@@ -0,0 +1,180 @@
+/*
+ * 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.hotspot.nfi;
+
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+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 creating a graph for a stub used to call a native function.
+ */
+public class NativeCallStubGraphBuilder {
+
+    /**
+     * Creates a graph for a stub used to call a native function.
+     * 
+     * @param functionPointer a native function pointer
+     * @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, RawNativeCallNodeFactory factory, long functionPointer, Class returnType, Class... argumentTypes) {
+        try {
+            ResolvedJavaMethod 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<MonitorIdNode>(),
+                            new ArrayList<EscapeObjectState>()));
+            g.start().setStateAfter(frameState);
+            List<ValueNode> parameters = new ArrayList<>();
+            FixedWithNextNode fixedWithNext = getParameters(g, arg0, argumentTypes.length, argumentTypes, parameters, providers);
+            Constant functionPointerNode = Constant.forLong(functionPointer);
+
+            ValueNode[] arguments = new ValueNode[parameters.size()];
+
+            for (int i = 0; i < arguments.length; i++) {
+                arguments[i] = parameters.get(i);
+            }
+
+            FixedWithNextNode callNode = g.add(factory.createRawCallNode(getKind(returnType), functionPointerNode, arguments));
+
+            if (fixedWithNext == null) {
+                g.start().setNext(callNode);
+            } else {
+                fixedWithNext.setNext(callNode);
+            }
+
+            // box result
+            BoxNode boxedResult;
+            if (callNode.kind() != Kind.Void) {
+                if (callNode.kind() == Kind.Object) {
+                    throw new IllegalArgumentException("Return type not supported: " + returnType.getName());
+                }
+                ResolvedJavaType type = providers.getMetaAccess().lookupJavaType(callNode.kind().toBoxedJavaClass());
+                boxedResult = g.unique(new BoxNode(callNode, type, callNode.kind()));
+            } else {
+                boxedResult = g.unique(new BoxNode(ConstantNode.forLong(0, g), providers.getMetaAccess().lookupJavaType(Long.class), Kind.Long));
+            }
+
+            ReturnNode returnNode = g.add(new ReturnNode(boxedResult));
+            callNode.setNext(returnNode);
+            (new WordTypeRewriterPhase(providers.getMetaAccess(), Kind.Long)).apply(g);
+            return g;
+        } catch (NoSuchMethodException e) {
+            throw GraalInternalError.shouldNotReachHere("Call Stub method not found");
+        }
+    }
+
+    private static FixedWithNextNode getParameters(StructuredGraph g, ParameterNode argumentsArray, int numArgs, Class[] argumentTypes, List<ValueNode> args, HotSpotProviders providers) {
+        assert numArgs == argumentTypes.length;
+        FixedWithNextNode last = 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);
+                last = boxedElement;
+            } else {
+                last.setNext(boxedElement);
+                last = boxedElement;
+            }
+            Class type = argumentTypes[i];
+            Kind kind = getKind(type);
+            if (kind == Kind.Object) {
+                // array value
+                Kind arrayElementKind = getElementKind(type);
+                LocationIdentity locationIdentity = NamedLocationIdentity.getArrayLocation(arrayElementKind);
+                int displacement = getArrayBaseOffset(arrayElementKind);
+                ConstantNode index = ConstantNode.forInt(0, g);
+                int indexScaling = getArrayIndexScale(arrayElementKind);
+                IndexedLocationNode locationNode = IndexedLocationNode.create(locationIdentity, arrayElementKind, displacement, index, g, indexScaling);
+                Stamp wordStamp = StampFactory.forKind(providers.getCodeCache().getTarget().wordKind);
+                ComputeAddressNode arrayAddress = g.unique(new ComputeAddressNode(boxedElement, locationNode, wordStamp));
+                args.add(arrayAddress);
+            } else {
+                // boxed primitive value
+                try {
+                    ResolvedJavaField field = providers.getMetaAccess().lookupJavaField(kind.toBoxedJavaClass().getDeclaredField("value"));
+                    LoadFieldNode loadFieldNode = g.add(new LoadFieldNode(boxedElement, field));
+                    last.setNext(loadFieldNode);
+                    last = loadFieldNode;
+                    args.add(loadFieldNode);
+                } catch (NoSuchFieldException e) {
+                    throw new GraalInternalError(e);
+                }
+            }
+        }
+        return last;
+    }
+
+    public static Kind getElementKind(Class clazz) {
+        Class componentType = clazz.getComponentType();
+        if (componentType == null) {
+            throw new IllegalArgumentException("Parameter type not supported: " + clazz);
+        }
+        if (componentType.isPrimitive()) {
+            Kind.fromJavaClass(componentType);
+        }
+        throw new IllegalArgumentException("Parameter 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);
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static Object libCall(Object argLoc, Object unused1, Object unused2) {
+        throw GraalInternalError.shouldNotReachHere("GNFI libCall method must not be called");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/RawNativeCallNodeFactory.java	Thu Feb 06 18:44:14 2014 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.hotspot.nfi;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+
+/**
+ * Factory for creating a node that makes a direct call to a native function pointer.
+ */
+public interface RawNativeCallNodeFactory {
+    FixedWithNextNode createRawCallNode(Kind returnType, Constant functionPointer, ValueNode... args);
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Thu Feb 06 18:42:45 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Thu Feb 06 18:44:14 2014 +0100
@@ -718,14 +718,4 @@
             throw new GraalInternalError(e);
         }
     }
-
-    @Fold
-    public static long dllLoad() {
-        return config().libraryLoadAddress;
-    }
-
-    @Fold
-    public static long dllLookup() {
-        return config().functionLookupAddress;
-    }
 }
--- a/graal/com.oracle.graal.nfi.hotspot.amd64/src/com/oracle/graal/nfi/hotspot/amd64/AMD64HotSpotNativeFunctionHandle.java	Thu Feb 06 18:42:45 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +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.nfi.hotspot.amd64;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.nfi.hotspot.amd64.util.*;
-import com.oracle.graal.nodes.*;
-
-public class AMD64HotSpotNativeFunctionHandle implements NativeFunctionHandle {
-
-    private final InstalledCode code;
-    private final String functionName;
-
-    protected final HotSpotProviders providers;
-    protected final Backend backend;
-
-    public AMD64HotSpotNativeFunctionHandle(HotSpotProviders providers, Backend backend, AMD64HotSpotNativeFunctionPointer 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;
-    }
-}
--- a/graal/com.oracle.graal.nfi.hotspot.amd64/src/com/oracle/graal/nfi/hotspot/amd64/AMD64HotSpotNativeFunctionInterface.java	Thu Feb 06 18:42:45 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,176 +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.nfi.hotspot.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.*;
-import com.oracle.graal.hotspot.meta.*;
-
-public class AMD64HotSpotNativeFunctionInterface 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 AMD64HotSpotNativeLibraryHandle rtldDefault;
-    protected final AMD64HotSpotNativeFunctionPointer libraryLoadFunctionPointer;
-    protected final AMD64HotSpotNativeFunctionPointer functionLookupFunctionPointer;
-
-    private AMD64HotSpotNativeFunctionHandle libraryLookupFunctionHandle;
-    private AMD64HotSpotNativeFunctionHandle dllLookupFunctionHandle;
-
-    public AMD64HotSpotNativeFunctionInterface(HotSpotProviders providers, Backend backend, AMD64HotSpotNativeFunctionPointer libraryLoadFunctionPointer,
-                    AMD64HotSpotNativeFunctionPointer functionLookUpFunctionPointer, AMD64HotSpotNativeLibraryHandle rtldDefault) {
-        this.rtldDefault = rtldDefault;
-        this.providers = providers;
-        this.backend = backend;
-        this.libraryLoadFunctionPointer = libraryLoadFunctionPointer;
-        this.functionLookupFunctionPointer = functionLookUpFunctionPointer;
-    }
-
-    @Override
-    public AMD64HotSpotNativeLibraryHandle getLibraryHandle(String libPath) {
-        if (libraryLookupFunctionHandle == null) {
-            libraryLookupFunctionHandle = new AMD64HotSpotNativeFunctionHandle(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 AMD64HotSpotNativeLibraryHandle(libraryHandle);
-    }
-
-    @Override
-    public AMD64HotSpotNativeFunctionHandle getFunctionHandle(NativeLibraryHandle libraryHandle, String functionName, Class returnType, Class[] argumentTypes) {
-        AMD64HotSpotNativeFunctionPointer functionPointer = lookupFunctionPointer(functionName, libraryHandle);
-        if (!functionPointer.isValid()) {
-            throw new IllegalStateException(functionName + " not found!");
-        }
-        return getFunctionHandle(functionPointer, returnType, argumentTypes);
-    }
-
-    @Override
-    public AMD64HotSpotNativeFunctionHandle getFunctionHandle(NativeLibraryHandle[] libraryHandles, String functionName, Class returnType, Class[] argumentTypes) {
-        AMD64HotSpotNativeFunctionPointer functionPointer = null;
-        for (NativeLibraryHandle libraryHandle : libraryHandles) {
-            functionPointer = lookupFunctionPointer(functionName, libraryHandle);
-            if (functionPointer.isValid()) {
-                return new AMD64HotSpotNativeFunctionHandle(providers, backend, functionPointer, returnType, argumentTypes);
-            }
-        }
-        return getFunctionHandle(functionName, returnType, argumentTypes);
-    }
-
-    @Override
-    public AMD64HotSpotNativeFunctionHandle getFunctionHandle(String functionName, Class returnType, Class[] argumentTypes) {
-        if (rtldDefault.asRawValue() == HotSpotVMConfig.INVALID_RTLD_DEFAULT_HANDLE) {
-            throw new AssertionError("No library provided or RTLD_DEFAULT not supported!");
-        }
-        return getFunctionHandle(rtldDefault, functionName, returnType, argumentTypes);
-    }
-
-    private AMD64HotSpotNativeFunctionPointer lookupFunctionPointer(String functionName, NativeLibraryHandle handle) {
-
-        if (!functionLookupFunctionPointer.isValid()) {
-            throw new IllegalStateException("no dlsym function pointer");
-        }
-        if (dllLookupFunctionHandle == null) {
-            dllLookupFunctionHandle = new AMD64HotSpotNativeFunctionHandle(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 AMD64HotSpotNativeFunctionPointer(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 AMD64HotSpotNativeFunctionHandle getFunctionHandle(NativeFunctionPointer functionPointer, Class returnType, Class[] argumentTypes) {
-        if (functionPointer instanceof AMD64HotSpotNativeFunctionPointer) {
-            if (!((AMD64HotSpotNativeFunctionPointer) functionPointer).isValid()) {
-                throw new IllegalStateException("Function Symbol not found");
-            }
-        } else {
-            throw new IllegalStateException("AMD64 function pointer required!");
-        }
-        return new AMD64HotSpotNativeFunctionHandle(providers, backend, (AMD64HotSpotNativeFunctionPointer) functionPointer, returnType, argumentTypes);
-    }
-
-    @Override
-    public AMD64HotSpotNativeFunctionPointer getFunctionPointer(NativeLibraryHandle[] libraryHandles, String functionName) {
-        for (NativeLibraryHandle libraryHandle : libraryHandles) {
-            AMD64HotSpotNativeFunctionPointer functionPointer = lookupFunctionPointer(functionName, libraryHandle);
-            if (functionPointer.isValid()) {
-                return functionPointer;
-            }
-        }
-        throw new LinkageError("Function not found: " + functionName);
-    }
-
-    @Override
-    public NativeFunctionPointer getNativeFunctionPointerFromRawValue(long rawValue) {
-        return new AMD64HotSpotNativeFunctionPointer(rawValue, null);
-    }
-
-}
--- a/graal/com.oracle.graal.nfi.hotspot.amd64/src/com/oracle/graal/nfi/hotspot/amd64/AMD64HotSpotNativeFunctionPointer.java	Thu Feb 06 18:42:45 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +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.nfi.hotspot.amd64;
-
-import com.oracle.graal.api.code.*;
-
-public class AMD64HotSpotNativeFunctionPointer implements NativeFunctionPointer {
-
-    private final long functionPointer;
-    private final String functionName;
-
-    public AMD64HotSpotNativeFunctionPointer(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;
-    }
-
-}
--- a/graal/com.oracle.graal.nfi.hotspot.amd64/src/com/oracle/graal/nfi/hotspot/amd64/AMD64HotSpotNativeLibraryHandle.java	Thu Feb 06 18:42:45 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +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.nfi.hotspot.amd64;
-
-import com.oracle.graal.api.code.*;
-
-public class AMD64HotSpotNativeLibraryHandle implements NativeLibraryHandle {
-
-    private final long handle;
-
-    public AMD64HotSpotNativeLibraryHandle(long handle) {
-        this.handle = handle;
-    }
-
-    public long asRawValue() {
-        return handle;
-    }
-
-    public boolean isValid() {
-        return handle != 0;
-    }
-}
--- a/graal/com.oracle.graal.nfi.hotspot.amd64/src/com/oracle/graal/nfi/hotspot/amd64/node/AMD64RawNativeCallNode.java	Thu Feb 06 18:42:45 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +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.nfi.hotspot.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<ValueNode> 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<ValueNode> 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;
-    }
-
-}
--- a/graal/com.oracle.graal.nfi.hotspot.amd64/src/com/oracle/graal/nfi/hotspot/amd64/util/InstallUtil.java	Thu Feb 06 18:42:45 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +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.nfi.hotspot.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<HighTierContext> 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), null, 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.");
-        }
-    }
-}
--- a/graal/com.oracle.graal.nfi.hotspot.amd64/src/com/oracle/graal/nfi/hotspot/amd64/util/NativeCallStubGraphBuilder.java	Thu Feb 06 18:42:45 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,271 +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.nfi.hotspot.amd64.util;
-
-import java.util.*;
-
-import sun.misc.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.nfi.hotspot.amd64.*;
-import com.oracle.graal.nfi.hotspot.amd64.node.*;
-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, AMD64HotSpotNativeFunctionPointer 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<MonitorIdNode>(),
-                            new ArrayList<EscapeObjectState>()));
-            g.start().setStateAfter(frameState);
-            List<ValueNode> 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<ValueNode> 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!");
-    }
-}
--- a/graal/com.oracle.graal.nfi.test/test/com/oracle/graal/nfi/test/LibCallTest.java	Thu Feb 06 18:42:45 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +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.nfi.test;
-
-import java.lang.reflect.*;
-
-import sun.misc.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.runtime.*;
-
-public class LibCallTest {
-
-    protected static final Unsafe unsafe = getUnsafe();
-    public final RuntimeProvider runtimeProvider;
-    public final NativeFunctionInterface ffi;
-
-    public LibCallTest() {
-        this.runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class);
-        if (runtimeProvider.getHostBackend() instanceof HostBackend) {
-            ffi = ((HostBackend) runtimeProvider.getHostBackend()).getNativeFunctionInterface();
-        } else {
-            throw GraalInternalError.shouldNotReachHere("Cannot initialize GNFI - backend is not a HostBackend");
-        }
-    }
-
-    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);
-        }
-    }
-
-}
--- a/graal/com.oracle.graal.nfi.test/test/com/oracle/graal/nfi/test/MathLibCallTest.java	Thu Feb 06 18:42:45 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +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.nfi.test;
-
-import org.junit.*;
-
-import com.oracle.graal.api.code.*;
-
-public class MathLibCallTest extends LibCallTest {
-
-    private final Object[] args = new Object[]{Double.doubleToLongBits(3), Double.doubleToLongBits(5.5)};
-    private 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 double callPow() {
-        return (double) handle.call(args);
-    }
-}
--- a/graal/com.oracle.graal.nfi.test/test/com/oracle/graal/nfi/test/StdLibCallTest.java	Thu Feb 06 18:42:45 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,192 +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.nfi.test;
-
-import org.junit.*;
-
-import com.oracle.graal.api.code.*;
-
-public class StdLibCallTest extends LibCallTest {
-
-    private static void copyString(long pointer, String s) {
-        for (int i = 0; i < s.length(); i++) {
-            unsafe.putByte(pointer + i, (byte) s.charAt(i));
-        }
-        unsafe.putByte(pointer + s.length(), (byte) '\0');
-    }
-
-    private static void checkString(long pointer, String s) {
-        for (int i = 0; i < s.length(); i++) {
-            Assert.assertEquals(unsafe.getByte(pointer + i) & 0xFF, (byte) s.charAt(i));
-        }
-        Assert.assertEquals(unsafe.getByte(pointer + s.length()) & 0xFF, (byte) '\0');
-    }
-
-    private static long getBuffer(int length) {
-        return unsafe.allocateMemory(length);
-    }
-
-    @Test
-    public void mallocTest() {
-        String string = "GRAAL";
-        int stringLength = string.length() + 1;
-
-        Object[] args = new Object[]{1};
-        args[0] = stringLength;
-        NativeFunctionHandle mallocHandle = ffi.getFunctionHandle("malloc", long.class, new Class[]{int.class});
-
-        long p = (long) mallocHandle.call(args);
-        copyString(p, string);
-
-        long buffer = getBuffer(stringLength);
-        NativeFunctionHandle putsHandle = ffi.getFunctionHandle("snprintf", int.class, new Class[]{long.class, int.class, long.class});
-        Object[] args2 = new Object[]{buffer, stringLength, p};
-        int result = (int) putsHandle.call(args2);
-        Assert.assertTrue(0 < result);
-        checkString(p, string);
-        checkString(buffer, string);
-
-        NativeFunctionHandle freeHandle = ffi.getFunctionHandle("free", void.class, new Class[]{long.class});
-        freeHandle.call(args2);
-    }
-
-    @Test
-    public void printfSimpleTest() {
-        long str = unsafe.allocateMemory(8);
-        copyString(str, "AB %f%f");
-
-        String referenceString = "AB 1.0000001.000000";
-        int referenceStringLenght = referenceString.length() + 1;
-
-        long buffer = getBuffer(referenceStringLenght);
-
-        Object[] args = new Object[]{buffer, referenceStringLenght, str, Double.doubleToRawLongBits(1.0), Double.doubleToRawLongBits(1.0)};
-        NativeFunctionHandle printfHandle = ffi.getFunctionHandle("snprintf", int.class, new Class[]{long.class, int.class, long.class, double.class, double.class});
-
-        int result = (int) printfHandle.call(args);
-
-        checkString(buffer, referenceString);
-        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');
-
-        String referenceString = "01234567891011";
-        int referenceStringLenght = referenceString.length() + 1;
-
-        long buffer = getBuffer(referenceStringLenght);
-
-        Object[] args = new Object[]{buffer, referenceStringLenght, 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("snprintf", int.class, new 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) printfHandle.call(args);
-        checkString(buffer, referenceString);
-        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');
-
-        String referenceString = "0123456789101112.50000013.50000014.50000015.50000016.50000017.50000018.50000019.50000020.500000" + "21.50000022.50000023.500000";
-        int referenceStringLenght = referenceString.length() + 1;
-
-        long buffer = getBuffer(referenceStringLenght);
-
-        Object[] args = new Object[]{buffer, referenceStringLenght, 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("snprintf", int.class, new 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) printfHandle.call(args);
-        checkString(buffer, referenceString);
-        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');
-
-        String referenceString = "0123456789101112.50000013.50000014.50000015.50000016.50000017.50000018.50000019.50000020.50000021.50000022.50000023.500000abcdefghijkl";
-        int referenceStringLenght = referenceString.length() + 1;
-
-        long buffer = getBuffer(referenceStringLenght);
-
-        Object[] args = new Object[]{buffer, referenceStringLenght, 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("snprintf", int.class, new 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) printfHandle.call(args);
-        checkString(buffer, referenceString);
-        Assert.assertTrue(0 < result);
-    }
-}
--- a/mx/projects	Thu Feb 06 18:42:45 2014 +0100
+++ b/mx/projects	Thu Feb 06 18:44:14 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.nfi.hotspot.amd64,com.oracle.graal.replacements.amd64
+project@com.oracle.graal.hotspot.amd64@dependencies=com.oracle.graal.compiler.amd64,com.oracle.graal.hotspot,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,22 +651,6 @@
 project@com.oracle.graal.asm.sparc@javaCompliance=1.7
 project@com.oracle.graal.asm.sparc@workingSets=Graal,Assembler,SPARC
 
-# graal.nfi.hotspot.amd64
-project@com.oracle.graal.nfi.hotspot.amd64@subDir=graal
-project@com.oracle.graal.nfi.hotspot.amd64@sourceDirs=src
-project@com.oracle.graal.nfi.hotspot.amd64@dependencies=com.oracle.graal.compiler.amd64,com.oracle.graal.hotspot
-project@com.oracle.graal.nfi.hotspot.amd64@checkstyle=com.oracle.graal.graph
-project@com.oracle.graal.nfi.hotspot.amd64@javaCompliance=1.7
-project@com.oracle.graal.nfi.hotspot.amd64@workingSets=Graal,AMD64
-
-# graal.nfi.test
-project@com.oracle.graal.nfi.test@subDir=graal
-project@com.oracle.graal.nfi.test@sourceDirs=test
-project@com.oracle.graal.nfi.test@dependencies=JUNIT,com.oracle.graal.runtime
-project@com.oracle.graal.nfi.test@checkstyle=com.oracle.graal.graph
-project@com.oracle.graal.nfi.test@javaCompliance=1.7
-project@com.oracle.graal.nfi.test@workingSets=Graal,Test
-
 # truffle.api
 project@com.oracle.truffle.api@subDir=graal
 project@com.oracle.truffle.api@sourceDirs=src
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Thu Feb 06 18:42:45 2014 +0100
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Thu Feb 06 18:44:14 2014 +0100
@@ -558,8 +558,8 @@
 
   //------------------------------------------------------------------------------------------------
 
-  set_long("libraryLoadAddress", (jlong) os::dll_load);
-  set_long("functionLookupAddress", (jlong) os::dll_lookup);
+  set_long("dllLoad", (jlong) os::dll_load);
+  set_long("dllLookup", (jlong) os::dll_lookup);
   #if defined(TARGET_OS_FAMILY_bsd) || defined(TARGET_OS_FAMILY_linux)
   set_long("rtldDefault", (jlong) RTLD_DEFAULT);
   #endif