changeset 16691:dd8449afc086

GNFI: move GNFI interfaces to oracle.nfi - interface does not depend on graal
author Matthias Grimmer <grimmer@ssw.jku.at>
date Tue, 05 Aug 2014 15:58:11 +0200
parents 7e8ecfe7d2e5
children 387c0fea76d4
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.compiler/src/com/oracle/graal/compiler/target/HostBackend.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.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.nfi.test/test/com/oracle/nfi/test/NativeFunctionInterfaceTest.java graal/com.oracle.nfi/src/com/oracle/nfi/NativeFunctionInterfaceRuntime.java graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionHandle.java graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionInterface.java graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionPointer.java graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeLibraryHandle.java mx/projects src/share/vm/graal/graalRuntime.cpp src/share/vm/prims/nativeLookup.cpp
diffstat 22 files changed, 743 insertions(+), 709 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionHandle.java	Tue Aug 05 12:34:55 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.api.code;
-
-/**
- * A handle that can be used to {@linkplain #call(Object[]) call} a native function.
- */
-public interface NativeFunctionHandle {
-
-    /**
-     * Calls the native function.
-     * <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 function
-     * @return boxed return value of the function call
-     */
-    Object call(Object... args);
-
-    /**
-     * Returns the installed code of the call stub for the native function call.
-     * 
-     * @return the installed code of the native call stub
-     */
-    InstalledCode getCallStub();
-}
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionInterface.java	Tue Aug 05 12:34:55 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.api.code;
-
-/**
- * Interface to get a {@linkplain NativeFunctionHandle handle} or {@linkplain NativeFunctionPointer
- * pointer} to a native function or a {@linkplain NativeLibraryHandle handle} to an open native
- * library.
- */
-public interface NativeFunctionInterface {
-
-    /**
-     * Resolves and returns a handle to an open native library. This method will open the library
-     * only if it is not already open.
-     *
-     * @param libPath the absolute path to the library
-     * @return the resolved library handle
-     * @throws UnsatisfiedLinkError if the library could not be found or opened
-     */
-    NativeLibraryHandle getLibraryHandle(String libPath);
-
-    /**
-     * Determines if the underlying platform/runtime supports the notion of a default library search
-     * path. For example, on *nix systems, this is typically defined by the {@code LD_LIBRARY_PATH}
-     * environment variable.
-     */
-    boolean isDefaultLibrarySearchSupported();
-
-    /**
-     * Resolves the function pointer {@code NativeFunctionPointer} of a native function.
-     *
-     * @param libraries the ordered list of libraries to search for the function
-     * @param name the name of the function to be resolved
-     * @return a pointer to the native function
-     * @throws UnsatisfiedLinkError if the function could not be resolved
-     */
-    NativeFunctionPointer getFunctionPointer(NativeLibraryHandle[] libraries, String name);
-
-    /**
-     * Resolves a function name to a {@linkplain NativeFunctionHandle handle} that can be called
-     * with a given signature. The signature contains the types of the arguments that will be passed
-     * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}.
-     *
-     * @param library the handle to a resolved library
-     * @param name the name of the function to be resolved
-     * @param returnType the type of the return value
-     * @param argumentTypes the types of the arguments
-     * @return the function handle of the native function
-     * @throws UnsatisfiedLinkError if the function handle could not be resolved
-     */
-    NativeFunctionHandle getFunctionHandle(NativeLibraryHandle library, String name, Class<?> returnType, Class<?>... argumentTypes);
-
-    /**
-     * Resolves a function pointer to a {@linkplain NativeFunctionHandle handle} that can be called
-     * with a given signature. The signature contains the types of the arguments that will be passed
-     * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}.
-     *
-     * @param functionPointer a function pointer
-     * @param returnType the type of the return value
-     * @param argumentTypes the types of the arguments
-     * @return the function handle of the native function
-     * @throws UnsatisfiedLinkError the function handle could not be created
-     */
-    NativeFunctionHandle getFunctionHandle(NativeFunctionPointer functionPointer, Class<?> returnType, Class<?>... argumentTypes);
-
-    /**
-     * Resolves a function name to a {@linkplain NativeFunctionHandle handle} that can be called
-     * with a given signature. The signature contains the types of the arguments that will be passed
-     * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}.
-     *
-     * @param libraries the ordered list of libraries to search for the function
-     * @param name the name of the function to be resolved
-     * @param returnType the type of the return value
-     * @param argumentTypes the types of the arguments
-     * @return the function handle of the native function
-     * @throws UnsatisfiedLinkError if the function handle could not be created
-     */
-    NativeFunctionHandle getFunctionHandle(NativeLibraryHandle[] libraries, String name, Class<?> returnType, Class<?>... argumentTypes);
-
-    /**
-     * Resolves a function name to a {@linkplain NativeFunctionHandle handle} that can be called
-     * with a given signature. The signature contains the types of the arguments that will be passed
-     * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}.
-     *
-     * @param name the name of the function to be resolved
-     * @param returnType the type of the return value
-     * @param argumentTypes the types of the arguments
-     * @return the function handle of the native function
-     * @throws UnsatisfiedLinkError if default library searching is not
-     *             {@linkplain #isDefaultLibrarySearchSupported() supported} or if the function
-     *             could not be resolved
-     */
-    NativeFunctionHandle getFunctionHandle(String name, Class<?> returnType, Class<?>... argumentTypes);
-
-    /**
-     * Creates a {@link NativeFunctionPointer} from a raw value.
-     *
-     * @param rawValue raw function pointer
-     * @return {@code NativeFunctionPointer} for {@code rawValue}
-     */
-    NativeFunctionPointer getNativeFunctionPointerFromRawValue(long rawValue);
-}
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeFunctionPointer.java	Tue Aug 05 12:34:55 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.api.code;
-
-/**
- * An opaque representation of a native function pointer.
- * <p>
- * Use {@code NativeFunctionInterface#getFunctionHandle(NativeFunctionPointer, Class, Class...)} to
- * get a handle enabling the native function to be {@linkplain NativeFunctionHandle#call(Object...)
- * called}.
- */
-public interface NativeFunctionPointer {
-
-    /**
-     * Returns the name of the function.
-     * 
-     * @return name of the function
-     */
-    String getName();
-
-}
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/NativeLibraryHandle.java	Tue Aug 05 12:34:55 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.api.code;
-
-/**
- * An opaque representation of a native library handle. A handle is obtained via
- * {@link NativeFunctionInterface#getLibraryHandle(String)}. A handle is used to resolve a string to
- * a {@linkplain NativeFunctionInterface#getFunctionHandle(String, Class, Class...) handle} or
- * {@linkplain NativeFunctionInterface#getFunctionPointer(NativeLibraryHandle[], String) pointer}.
- */
-public interface NativeLibraryHandle {
-    /**
-     * Gets a name for this library. This may be the path for the file from which the library was
-     * loaded.
-     */
-    String getName();
-}
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/nfi/NativeFunctionInterfaceTest.java	Tue Aug 05 12:34:55 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,401 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.compiler.test.nfi;
-
-import static com.oracle.graal.compiler.common.UnsafeAccess.*;
-import static java.io.File.*;
-import static java.lang.System.*;
-import static org.junit.Assert.*;
-import static org.junit.Assume.*;
-
-import java.io.*;
-import java.util.*;
-
-import org.junit.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.runtime.*;
-
-@Ignore
-public class NativeFunctionInterfaceTest {
-
-    public final NativeFunctionInterface nfi;
-
-    public NativeFunctionInterfaceTest() {
-        RuntimeProvider runtimeProvider = Graal.getRequiredCapability(RuntimeProvider.class);
-        Assume.assumeTrue(runtimeProvider.getHostBackend() instanceof HostBackend);
-        nfi = ((HostBackend) runtimeProvider.getHostBackend()).getNativeFunctionInterface();
-    }
-
-    private List<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() {
-        assumeTrue(nfi.isDefaultLibrarySearchSupported());
-        NativeFunctionHandle malloc = nfi.getFunctionHandle("malloc", long.class, int.class);
-        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class);
-        NativeFunctionHandle free = nfi.getFunctionHandle("free", void.class, long.class);
-
-        String string = "GRAAL";
-        int bufferLength = string.length() + 1;
-        long cString = (long) malloc.call(bufferLength);
-        writeCString(string, cString);
-
-        long cStringCopy = malloc(bufferLength);
-        int result = (int) snprintf.call(cStringCopy, bufferLength, cString);
-        Assert.assertEquals(string.length(), result);
-        assertCStringEquals(cString, string);
-        assertCStringEquals(cStringCopy, string);
-
-        free.call(cString);
-    }
-
-    @Test
-    public void test2() {
-        assumeTrue(nfi.isDefaultLibrarySearchSupported());
-        String formatString = "AB %f%f";
-        long formatCString = writeCString("AB %f%f", malloc(formatString.length() + 1));
-
-        String referenceString = "AB 1.0000001.000000";
-        int bufferLength = referenceString.length() + 1;
-        long buffer = malloc(bufferLength);
-
-        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, double.class, double.class);
-        int result = (int) snprintf.call(buffer, bufferLength, formatCString, 1.0D, 1.0D);
-
-        assertCStringEquals(buffer, referenceString);
-        Assert.assertEquals(referenceString.length(), result);
-    }
-
-    @Test
-    public void test3() {
-        assumeTrue(nfi.isDefaultLibrarySearchSupported());
-        String format = "%i%i%i%i%i%i%i%i%i%i%i%i";
-        long formatCString = writeCString(format, malloc(format.length() + 1));
-        String referenceString = "01234567891011";
-
-        int bufferLength = referenceString.length() + 1;
-        long buffer = malloc(bufferLength);
-
-        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
-                        int.class, int.class, int.class, int.class, int.class);
-
-        int result = (int) snprintf.call(buffer, bufferLength, formatCString, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
-        assertCStringEquals(buffer, referenceString);
-        Assert.assertEquals(referenceString.length(), result);
-    }
-
-    @Test
-    public void test4() {
-        assumeTrue(nfi.isDefaultLibrarySearchSupported());
-        long str = malloc(49);
-        int[] val = new int[12];
-        for (int i = 0; i < 12; i++) {
-            unsafe.putByte(str + 2 * i, (byte) '%');
-            unsafe.putByte(str + 2 * i + 1, (byte) 'i');
-            val[i] = i;
-        }
-        double[] dval = new double[12];
-        for (int i = 12; i < 24; i++) {
-            unsafe.putByte(str + 2 * i, (byte) '%');
-            unsafe.putByte(str + 2 * i + 1, (byte) 'f');
-            dval[i - 12] = i + 0.5;
-        }
-        unsafe.putByte(str + 48, (byte) '\0');
-
-        String referenceString = "0123456789101112.50000013.50000014.50000015.50000016.50000017.50000018.50000019.50000020.500000" + "21.50000022.50000023.500000";
-        int bufferLength = referenceString.length() + 1;
-
-        long buffer = malloc(bufferLength);
-
-        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
-                        int.class, int.class, int.class, int.class, int.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class,
-                        double.class, double.class, double.class, double.class);
-
-        int result = (int) snprintf.call(buffer, bufferLength, str, val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8], val[9], val[10], val[11], dval[0], dval[1], dval[2],
-                        dval[3], dval[4], dval[5], dval[6], dval[7], dval[8], dval[9], dval[10], dval[11]);
-        assertCStringEquals(buffer, referenceString);
-        Assert.assertEquals(referenceString.length(), result);
-    }
-
-    @Test
-    public void test5() {
-        assumeTrue(nfi.isDefaultLibrarySearchSupported());
-        long str = malloc(73);
-        int[] val = new int[12];
-        for (int i = 0; i < 12; i++) {
-            unsafe.putByte(str + 2 * i, (byte) '%');
-            unsafe.putByte(str + 2 * i + 1, (byte) 'i');
-            val[i] = i;
-        }
-        double[] dval = new double[12];
-        for (int i = 12; i < 24; i++) {
-            unsafe.putByte(str + 2 * i, (byte) '%');
-            unsafe.putByte(str + 2 * i + 1, (byte) 'f');
-            dval[i - 12] = i + 0.5;
-        }
-        char[] cval = new char[12];
-        for (int i = 24; i < 36; i++) {
-            unsafe.putByte(str + 2 * i, (byte) '%');
-            unsafe.putByte(str + 2 * i + 1, (byte) 'c');
-            cval[i - 24] = (char) ('a' + (i - 24));
-        }
-        unsafe.putByte(str + 72, (byte) '\0');
-
-        String referenceString = "0123456789101112.50000013.50000014.50000015.50000016.50000017.50000018.50000019.50000020.50000021.50000022.50000023.500000abcdefghijkl";
-        int bufferLength = referenceString.length() + 1;
-
-        long buffer = malloc(bufferLength);
-
-        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
-                        int.class, int.class, int.class, int.class, int.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class,
-                        double.class, double.class, double.class, double.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class,
-                        char.class, char.class);
-
-        int result = (int) snprintf.call(buffer, bufferLength, str, val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8], val[9], val[10], val[11], dval[0], dval[1], dval[2],
-                        dval[3], dval[4], dval[5], dval[6], dval[7], dval[8], dval[9], dval[10], dval[11], cval[0], cval[1], cval[2], cval[3], cval[4], cval[5], cval[6], cval[7], cval[8], cval[9],
-                        cval[10], cval[11]);
-        assertCStringEquals(buffer, referenceString);
-        Assert.assertEquals(referenceString.length(), result);
-    }
-
-    @Test
-    public void test6() {
-        assumeTrue(nfi.isDefaultLibrarySearchSupported());
-        NativeFunctionHandle handle = nfi.getFunctionHandle("pow", double.class, double.class, double.class);
-        double result = (double) handle.call(3D, 5.5D);
-        assertEquals(Math.pow(3D, 5.5D), result, 0);
-    }
-
-    @Test
-    public void test7() {
-        assumeTrue(nfi.isDefaultLibrarySearchSupported());
-        double result = 0;
-        NativeFunctionHandle handle = nfi.getFunctionHandle("pow", double.class, double.class, double.class);
-        for (int i = 0; i < 10; i++) {
-            result = (double) handle.call(3D, 5.5D);
-        }
-        assertEquals(Math.pow(3D, 5.5D), result, 0);
-    }
-
-    @Test
-    public void test8() {
-        assumeTrue(nfi.isDefaultLibrarySearchSupported());
-        String formatString = "AB %f%f";
-        long formatCString = writeCString("AB %f%f", malloc(formatString.length() + 1));
-
-        String expected = "AB 1.0000001.000000";
-        int bufferLength = expected.length() + 1;
-        byte[] buffer = new byte[bufferLength];
-
-        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, byte[].class, int.class, long.class, double.class, double.class);
-        int result = (int) snprintf.call(buffer, bufferLength, formatCString, 1.0D, 1.0D);
-
-        // trim trailing '\0'
-        String actual = new String(buffer, 0, expected.length());
-
-        assertEquals(expected, actual);
-        Assert.assertEquals(expected.length(), result);
-    }
-
-    private static double[] someDoubles = {2454.346D, 98789.22D, Double.MAX_VALUE, Double.MIN_NORMAL, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY};
-
-    @Test
-    public void test9() {
-        assumeTrue(nfi.isDefaultLibrarySearchSupported());
-        double[] src = someDoubles.clone();
-        double[] dst = new double[src.length];
-
-        NativeFunctionHandle memcpy = nfi.getFunctionHandle("memcpy", void.class, double[].class, double[].class, int.class);
-        memcpy.call(dst, src, src.length * (Double.SIZE / Byte.SIZE));
-
-        assertArrayEquals(src, dst, 0.0D);
-    }
-
-    private static String getVMName() {
-        String vmName = System.getProperty("java.vm.name").toLowerCase();
-        String vm = null;
-        if (vmName.contains("server")) {
-            vm = "server";
-        } else if (vmName.contains("graal")) {
-            vm = "graal";
-        } else if (vmName.contains("client")) {
-            vm = "client";
-        }
-
-        Assume.assumeTrue(vm != null);
-        return vm;
-    }
-
-    private static String getVMLibPath() {
-        String vm = getVMName();
-
-        String path = String.format("%s%c%s%c%s", getProperty("sun.boot.library.path"), separatorChar, vm, separatorChar, mapLibraryName("jvm"));
-        // Only continue if the library file exists
-        Assume.assumeTrue(new File(path).exists());
-        return path;
-    }
-
-    @Test
-    public void test10() {
-        NativeLibraryHandle vmLib = nfi.getLibraryHandle(getVMLibPath());
-        NativeFunctionHandle currentTimeMillis = nfi.getFunctionHandle(vmLib, "JVM_CurrentTimeMillis", long.class);
-        long time1 = (long) currentTimeMillis.call();
-        long time2 = System.currentTimeMillis();
-        long delta = time2 - time1;
-
-        // The 2 calls to get the current time should not differ by more than
-        // 100 milliseconds at the very most
-        assertTrue(String.valueOf(delta), delta >= 0);
-        assertTrue(String.valueOf(delta), delta < 100);
-    }
-
-    private static String getJavaLibPath() {
-        String path = String.format("%s%c%s", getProperty("sun.boot.library.path"), separatorChar, mapLibraryName("java"));
-        Assume.assumeTrue(new File(path).exists());
-        return path;
-    }
-
-    private static void testD2L(NativeFunctionHandle d2l) {
-        for (double d : someDoubles) {
-            long expected = Double.doubleToRawLongBits(d);
-            long actual = (long) d2l.call(0L, 0L, d);
-            assertEquals(Double.toString(d), expected, actual);
-        }
-    }
-
-    @Test
-    public void test11() {
-        NativeLibraryHandle javaLib = nfi.getLibraryHandle(getJavaLibPath());
-        NativeFunctionHandle d2l = nfi.getFunctionHandle(javaLib, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class);
-        testD2L(d2l);
-    }
-
-    @Test
-    public void test12() {
-        NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())};
-        NativeFunctionHandle d2l = nfi.getFunctionHandle(libs, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class);
-        testD2L(d2l);
-
-        NativeLibraryHandle[] libsReveresed = {libs[1], libs[0]};
-        d2l = nfi.getFunctionHandle(libsReveresed, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class);
-        testD2L(d2l);
-    }
-
-    @Test
-    public void test13() {
-        NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())};
-        NativeFunctionPointer functionPointer = nfi.getFunctionPointer(libs, "Java_java_lang_Double_doubleToRawLongBits");
-        NativeFunctionHandle d2l = nfi.getFunctionHandle(functionPointer, long.class, long.class, long.class, double.class);
-        testD2L(d2l);
-
-        NativeLibraryHandle[] libsReveresed = {libs[1], libs[0]};
-        functionPointer = nfi.getFunctionPointer(libsReveresed, "Java_java_lang_Double_doubleToRawLongBits");
-        d2l = nfi.getFunctionHandle(functionPointer, long.class, long.class, long.class, double.class);
-        testD2L(d2l);
-    }
-
-    @Test
-    public void test14() {
-        if (!nfi.isDefaultLibrarySearchSupported()) {
-            try {
-                nfi.getFunctionHandle("snprintf", int.class);
-                fail();
-            } catch (UnsatisfiedLinkError e) {
-            }
-        }
-    }
-
-    @Test
-    public void test15() {
-        assumeTrue(nfi.isDefaultLibrarySearchSupported());
-        try {
-            nfi.getFunctionHandle("an invalid function name", int.class);
-            fail();
-        } catch (UnsatisfiedLinkError e) {
-        }
-    }
-
-    @Test
-    public void test16() {
-        NativeLibraryHandle javaLib = nfi.getLibraryHandle(getJavaLibPath());
-        try {
-
-            nfi.getFunctionHandle(javaLib, "an invalid function name", int.class);
-            fail();
-        } catch (UnsatisfiedLinkError e) {
-        }
-    }
-
-    @Test
-    public void test17() {
-        NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())};
-        try {
-            nfi.getFunctionPointer(libs, "an invalid function name");
-            fail();
-        } catch (UnsatisfiedLinkError e) {
-        }
-    }
-
-    @Test
-    public void test18() {
-        NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())};
-        try {
-            nfi.getFunctionHandle(libs, "an invalid function name", int.class);
-            fail();
-        } catch (UnsatisfiedLinkError e) {
-        }
-    }
-
-    @Test
-    public void test19() {
-        try {
-            nfi.getLibraryHandle("an invalid library name");
-            fail();
-        } catch (UnsatisfiedLinkError e) {
-        }
-    }
-
-}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/HostBackend.java	Tue Aug 05 12:34:55 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.compiler.target;
-
-import com.oracle.graal.api.code.*;
-
-/**
- * Common functionality of host backends.
- */
-public interface HostBackend {
-    NativeFunctionInterface getNativeFunctionInterface();
-}
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Tue Aug 05 12:34:55 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Tue Aug 05 15:58:11 2014 +0200
@@ -49,6 +49,7 @@
 import com.oracle.graal.lir.gen.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.nfi.api.*;
 
 /**
  * HotSpot AMD64 specific backend.
@@ -321,15 +322,16 @@
         }
     }
 
-    @Override
-    public NativeFunctionInterface getNativeFunctionInterface() {
-        HotSpotVMConfig config = getRuntime().getConfig();
+    // used by native code, don't remove!
+    public static NativeFunctionInterface createNativeFunctionInterface() {
+        HotSpotVMConfig config = HotSpotGraalRuntime.runtime().getConfig();
         RawNativeCallNodeFactory factory = new RawNativeCallNodeFactory() {
             public FixedWithNextNode createRawCallNode(Kind returnType, Constant functionPointer, ValueNode... args) {
                 return new AMD64RawNativeCallNode(returnType, functionPointer, args);
             }
         };
-        return new HotSpotNativeFunctionInterface(getProviders(), factory, this, config.dllLoad, config.dllLookup, config.rtldDefault);
+        Backend backend = HotSpotGraalRuntime.runtime().getBackend(AMD64.class);
+        return new HotSpotNativeFunctionInterface(HotSpotGraalRuntime.runtime().getHostProviders(), factory, backend, config.dllLoad, config.dllLookup, config.rtldDefault);
     }
 
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Tue Aug 05 12:34:55 2014 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Tue Aug 05 15:58:11 2014 +0200
@@ -44,7 +44,6 @@
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Nop;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.RestoreWindow;
 import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
-import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId;
 import com.oracle.graal.hotspot.meta.*;
@@ -247,9 +246,4 @@
         }
     }
 
-    @Override
-    public NativeFunctionInterface getNativeFunctionInterface() {
-        throw GraalInternalError.unimplemented("No NativeFunctionInterface of SPARC");
-    }
-
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Tue Aug 05 12:34:55 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Tue Aug 05 15:58:11 2014 +0200
@@ -27,7 +27,6 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.hotspot.meta.*;
@@ -37,7 +36,7 @@
 /**
  * Common functionality of HotSpot host backends.
  */
-public abstract class HotSpotHostBackend extends HotSpotBackend implements HostBackend {
+public abstract class HotSpotHostBackend extends HotSpotBackend {
 
     /**
      * Descriptor for {@link DeoptimizationStub#deoptimizationHandler}.
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionHandle.java	Tue Aug 05 12:34:55 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionHandle.java	Tue Aug 05 15:58:11 2014 +0200
@@ -29,6 +29,7 @@
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
+import com.oracle.nfi.api.*;
 
 public class HotSpotNativeFunctionHandle implements NativeFunctionHandle {
 
@@ -87,10 +88,6 @@
         return true;
     }
 
-    public InstalledCode getCallStub() {
-        return code;
-    }
-
     @Override
     public String toString() {
         return name + Arrays.toString(argumentTypes);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java	Tue Aug 05 12:34:55 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java	Tue Aug 05 15:58:11 2014 +0200
@@ -40,6 +40,7 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.nfi.api.*;
 
 public class HotSpotNativeFunctionInterface implements NativeFunctionInterface {
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionPointer.java	Tue Aug 05 12:34:55 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionPointer.java	Tue Aug 05 15:58:11 2014 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.hotspot.nfi;
 
-import com.oracle.graal.api.code.*;
+import com.oracle.nfi.api.*;
 
 public class HotSpotNativeFunctionPointer implements NativeFunctionPointer {
 
@@ -41,7 +41,7 @@
         return name;
     }
 
-    public long getValue() {
+    public long getRawValue() {
         return value;
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeLibraryHandle.java	Tue Aug 05 12:34:55 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeLibraryHandle.java	Tue Aug 05 15:58:11 2014 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.hotspot.nfi;
 
-import com.oracle.graal.api.code.*;
+import com.oracle.nfi.api.*;
 
 public class HotSpotNativeLibraryHandle implements NativeLibraryHandle {
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.nfi.test/test/com/oracle/nfi/test/NativeFunctionInterfaceTest.java	Tue Aug 05 15:58:11 2014 +0200
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.nfi.test;
+
+import static com.oracle.graal.compiler.common.UnsafeAccess.*;
+import static java.io.File.*;
+import static java.lang.System.*;
+import static org.junit.Assert.*;
+import static org.junit.Assume.*;
+
+import java.io.*;
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.nfi.*;
+import com.oracle.nfi.api.*;
+
+@Ignore
+public class NativeFunctionInterfaceTest {
+
+    public final NativeFunctionInterface nfi;
+
+    public NativeFunctionInterfaceTest() {
+        nfi = NativeFunctionInterfaceRuntime.getNativeFunctionInterface();
+    }
+
+    private List<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() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        NativeFunctionHandle malloc = nfi.getFunctionHandle("malloc", long.class, int.class);
+        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class);
+        NativeFunctionHandle free = nfi.getFunctionHandle("free", void.class, long.class);
+
+        String string = "GRAAL";
+        int bufferLength = string.length() + 1;
+        long cString = (long) malloc.call(bufferLength);
+        writeCString(string, cString);
+
+        long cStringCopy = malloc(bufferLength);
+        int result = (int) snprintf.call(cStringCopy, bufferLength, cString);
+        Assert.assertEquals(string.length(), result);
+        assertCStringEquals(cString, string);
+        assertCStringEquals(cStringCopy, string);
+
+        free.call(cString);
+    }
+
+    @Test
+    public void test2() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        String formatString = "AB %f%f";
+        long formatCString = writeCString("AB %f%f", malloc(formatString.length() + 1));
+
+        String referenceString = "AB 1.0000001.000000";
+        int bufferLength = referenceString.length() + 1;
+        long buffer = malloc(bufferLength);
+
+        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, double.class, double.class);
+        int result = (int) snprintf.call(buffer, bufferLength, formatCString, 1.0D, 1.0D);
+
+        assertCStringEquals(buffer, referenceString);
+        Assert.assertEquals(referenceString.length(), result);
+    }
+
+    @Test
+    public void test3() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        String format = "%i%i%i%i%i%i%i%i%i%i%i%i";
+        long formatCString = writeCString(format, malloc(format.length() + 1));
+        String referenceString = "01234567891011";
+
+        int bufferLength = referenceString.length() + 1;
+        long buffer = malloc(bufferLength);
+
+        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
+                        int.class, int.class, int.class, int.class, int.class);
+
+        int result = (int) snprintf.call(buffer, bufferLength, formatCString, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
+        assertCStringEquals(buffer, referenceString);
+        Assert.assertEquals(referenceString.length(), result);
+    }
+
+    @Test
+    public void test4() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        long str = malloc(49);
+        int[] val = new int[12];
+        for (int i = 0; i < 12; i++) {
+            unsafe.putByte(str + 2 * i, (byte) '%');
+            unsafe.putByte(str + 2 * i + 1, (byte) 'i');
+            val[i] = i;
+        }
+        double[] dval = new double[12];
+        for (int i = 12; i < 24; i++) {
+            unsafe.putByte(str + 2 * i, (byte) '%');
+            unsafe.putByte(str + 2 * i + 1, (byte) 'f');
+            dval[i - 12] = i + 0.5;
+        }
+        unsafe.putByte(str + 48, (byte) '\0');
+
+        String referenceString = "0123456789101112.50000013.50000014.50000015.50000016.50000017.50000018.50000019.50000020.500000" + "21.50000022.50000023.500000";
+        int bufferLength = referenceString.length() + 1;
+
+        long buffer = malloc(bufferLength);
+
+        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
+                        int.class, int.class, int.class, int.class, int.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class,
+                        double.class, double.class, double.class, double.class);
+
+        int result = (int) snprintf.call(buffer, bufferLength, str, val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8], val[9], val[10], val[11], dval[0], dval[1], dval[2],
+                        dval[3], dval[4], dval[5], dval[6], dval[7], dval[8], dval[9], dval[10], dval[11]);
+        assertCStringEquals(buffer, referenceString);
+        Assert.assertEquals(referenceString.length(), result);
+    }
+
+    @Test
+    public void test5() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        long str = malloc(73);
+        int[] val = new int[12];
+        for (int i = 0; i < 12; i++) {
+            unsafe.putByte(str + 2 * i, (byte) '%');
+            unsafe.putByte(str + 2 * i + 1, (byte) 'i');
+            val[i] = i;
+        }
+        double[] dval = new double[12];
+        for (int i = 12; i < 24; i++) {
+            unsafe.putByte(str + 2 * i, (byte) '%');
+            unsafe.putByte(str + 2 * i + 1, (byte) 'f');
+            dval[i - 12] = i + 0.5;
+        }
+        char[] cval = new char[12];
+        for (int i = 24; i < 36; i++) {
+            unsafe.putByte(str + 2 * i, (byte) '%');
+            unsafe.putByte(str + 2 * i + 1, (byte) 'c');
+            cval[i - 24] = (char) ('a' + (i - 24));
+        }
+        unsafe.putByte(str + 72, (byte) '\0');
+
+        String referenceString = "0123456789101112.50000013.50000014.50000015.50000016.50000017.50000018.50000019.50000020.50000021.50000022.50000023.500000abcdefghijkl";
+        int bufferLength = referenceString.length() + 1;
+
+        long buffer = malloc(bufferLength);
+
+        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, long.class, int.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class, int.class,
+                        int.class, int.class, int.class, int.class, int.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class, double.class,
+                        double.class, double.class, double.class, double.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class, char.class,
+                        char.class, char.class);
+
+        int result = (int) snprintf.call(buffer, bufferLength, str, val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8], val[9], val[10], val[11], dval[0], dval[1], dval[2],
+                        dval[3], dval[4], dval[5], dval[6], dval[7], dval[8], dval[9], dval[10], dval[11], cval[0], cval[1], cval[2], cval[3], cval[4], cval[5], cval[6], cval[7], cval[8], cval[9],
+                        cval[10], cval[11]);
+        assertCStringEquals(buffer, referenceString);
+        Assert.assertEquals(referenceString.length(), result);
+    }
+
+    @Test
+    public void test6() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        NativeFunctionHandle handle = nfi.getFunctionHandle("pow", double.class, double.class, double.class);
+        double result = (double) handle.call(3D, 5.5D);
+        assertEquals(Math.pow(3D, 5.5D), result, 0);
+    }
+
+    @Test
+    public void test7() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        double result = 0;
+        NativeFunctionHandle handle = nfi.getFunctionHandle("pow", double.class, double.class, double.class);
+        for (int i = 0; i < 10; i++) {
+            result = (double) handle.call(3D, 5.5D);
+        }
+        assertEquals(Math.pow(3D, 5.5D), result, 0);
+    }
+
+    @Test
+    public void test8() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        String formatString = "AB %f%f";
+        long formatCString = writeCString("AB %f%f", malloc(formatString.length() + 1));
+
+        String expected = "AB 1.0000001.000000";
+        int bufferLength = expected.length() + 1;
+        byte[] buffer = new byte[bufferLength];
+
+        NativeFunctionHandle snprintf = nfi.getFunctionHandle("snprintf", int.class, byte[].class, int.class, long.class, double.class, double.class);
+        int result = (int) snprintf.call(buffer, bufferLength, formatCString, 1.0D, 1.0D);
+
+        // trim trailing '\0'
+        String actual = new String(buffer, 0, expected.length());
+
+        assertEquals(expected, actual);
+        Assert.assertEquals(expected.length(), result);
+    }
+
+    private static double[] someDoubles = {2454.346D, 98789.22D, Double.MAX_VALUE, Double.MIN_NORMAL, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY};
+
+    @Test
+    public void test9() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        double[] src = someDoubles.clone();
+        double[] dst = new double[src.length];
+
+        NativeFunctionHandle memcpy = nfi.getFunctionHandle("memcpy", void.class, double[].class, double[].class, int.class);
+        memcpy.call(dst, src, src.length * (Double.SIZE / Byte.SIZE));
+
+        assertArrayEquals(src, dst, 0.0D);
+    }
+
+    private static String getVMName() {
+        String vmName = System.getProperty("java.vm.name").toLowerCase();
+        String vm = null;
+        if (vmName.contains("server")) {
+            vm = "server";
+        } else if (vmName.contains("graal")) {
+            vm = "graal";
+        } else if (vmName.contains("client")) {
+            vm = "client";
+        }
+
+        Assume.assumeTrue(vm != null);
+        return vm;
+    }
+
+    private static String getVMLibPath() {
+        String vm = getVMName();
+
+        String path = String.format("%s%c%s%c%s", getProperty("sun.boot.library.path"), separatorChar, vm, separatorChar, mapLibraryName("jvm"));
+        // Only continue if the library file exists
+        Assume.assumeTrue(new File(path).exists());
+        return path;
+    }
+
+    @Test
+    public void test10() {
+        NativeLibraryHandle vmLib = nfi.getLibraryHandle(getVMLibPath());
+        NativeFunctionHandle currentTimeMillis = nfi.getFunctionHandle(vmLib, "JVM_CurrentTimeMillis", long.class);
+        long time1 = (long) currentTimeMillis.call();
+        long time2 = System.currentTimeMillis();
+        long delta = time2 - time1;
+
+        // The 2 calls to get the current time should not differ by more than
+        // 100 milliseconds at the very most
+        assertTrue(String.valueOf(delta), delta >= 0);
+        assertTrue(String.valueOf(delta), delta < 100);
+    }
+
+    private static String getJavaLibPath() {
+        String path = String.format("%s%c%s", getProperty("sun.boot.library.path"), separatorChar, mapLibraryName("java"));
+        Assume.assumeTrue(new File(path).exists());
+        return path;
+    }
+
+    private static void testD2L(NativeFunctionHandle d2l) {
+        for (double d : someDoubles) {
+            long expected = Double.doubleToRawLongBits(d);
+            long actual = (long) d2l.call(0L, 0L, d);
+            assertEquals(Double.toString(d), expected, actual);
+        }
+    }
+
+    @Test
+    public void test11() {
+        NativeLibraryHandle javaLib = nfi.getLibraryHandle(getJavaLibPath());
+        NativeFunctionHandle d2l = nfi.getFunctionHandle(javaLib, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class);
+        testD2L(d2l);
+    }
+
+    @Test
+    public void test12() {
+        NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())};
+        NativeFunctionHandle d2l = nfi.getFunctionHandle(libs, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class);
+        testD2L(d2l);
+
+        NativeLibraryHandle[] libsReveresed = {libs[1], libs[0]};
+        d2l = nfi.getFunctionHandle(libsReveresed, "Java_java_lang_Double_doubleToRawLongBits", long.class, long.class, long.class, double.class);
+        testD2L(d2l);
+    }
+
+    @Test
+    public void test13() {
+        NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())};
+        NativeFunctionPointer functionPointer = nfi.getFunctionPointer(libs, "Java_java_lang_Double_doubleToRawLongBits");
+        NativeFunctionHandle d2l = nfi.getFunctionHandle(functionPointer, long.class, long.class, long.class, double.class);
+        testD2L(d2l);
+
+        NativeLibraryHandle[] libsReveresed = {libs[1], libs[0]};
+        functionPointer = nfi.getFunctionPointer(libsReveresed, "Java_java_lang_Double_doubleToRawLongBits");
+        d2l = nfi.getFunctionHandle(functionPointer, long.class, long.class, long.class, double.class);
+        testD2L(d2l);
+    }
+
+    @Test
+    public void test14() {
+        if (!nfi.isDefaultLibrarySearchSupported()) {
+            try {
+                nfi.getFunctionHandle("snprintf", int.class);
+                fail();
+            } catch (UnsatisfiedLinkError e) {
+            }
+        }
+    }
+
+    @Test
+    public void test15() {
+        assumeTrue(nfi.isDefaultLibrarySearchSupported());
+        try {
+            nfi.getFunctionHandle("an invalid function name", int.class);
+            fail();
+        } catch (UnsatisfiedLinkError e) {
+        }
+    }
+
+    @Test
+    public void test16() {
+        NativeLibraryHandle javaLib = nfi.getLibraryHandle(getJavaLibPath());
+        try {
+
+            nfi.getFunctionHandle(javaLib, "an invalid function name", int.class);
+            fail();
+        } catch (UnsatisfiedLinkError e) {
+        }
+    }
+
+    @Test
+    public void test17() {
+        NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())};
+        try {
+            nfi.getFunctionPointer(libs, "an invalid function name");
+            fail();
+        } catch (UnsatisfiedLinkError e) {
+        }
+    }
+
+    @Test
+    public void test18() {
+        NativeLibraryHandle[] libs = {nfi.getLibraryHandle(getVMLibPath()), nfi.getLibraryHandle(getJavaLibPath())};
+        try {
+            nfi.getFunctionHandle(libs, "an invalid function name", int.class);
+            fail();
+        } catch (UnsatisfiedLinkError e) {
+        }
+    }
+
+    @Test
+    public void test19() {
+        try {
+            nfi.getLibraryHandle("an invalid library name");
+            fail();
+        } catch (UnsatisfiedLinkError e) {
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.nfi/src/com/oracle/nfi/NativeFunctionInterfaceRuntime.java	Tue Aug 05 15:58:11 2014 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.nfi;
+
+import com.oracle.nfi.api.*;
+
+public final class NativeFunctionInterfaceRuntime {
+    private static final NativeFunctionInterface INTERFACE;
+
+    private static native NativeFunctionInterface createInterface();
+
+    public static NativeFunctionInterface getNativeFunctionInterface() {
+        return INTERFACE;
+    }
+
+    static {
+        NativeFunctionInterface instance;
+        try {
+            instance = createInterface();
+        } catch (UnsatisfiedLinkError e) {
+            System.err.println("Graal Native Function Interface not supported!");
+            e.printStackTrace();
+            instance = null;
+        }
+        INTERFACE = instance;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionHandle.java	Tue Aug 05 15:58:11 2014 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.nfi.api;
+
+/**
+ * A handle that can be used to {@linkplain #call(Object[]) call} a native function.
+ */
+public interface NativeFunctionHandle {
+
+    /**
+     * Calls the native function.
+     * <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 function
+     * @return boxed return value of the function call
+     */
+    Object call(Object... args);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionInterface.java	Tue Aug 05 15:58:11 2014 +0200
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.nfi.api;
+
+/**
+ * Interface to get a {@linkplain NativeFunctionHandle handle} or {@linkplain NativeFunctionPointer
+ * pointer} to a native function or a {@linkplain NativeLibraryHandle handle} to an open native
+ * library.
+ */
+public interface NativeFunctionInterface {
+
+    /**
+     * Resolves and returns a handle to an open native library. This method will open the library
+     * only if it is not already open.
+     *
+     * @param libPath the absolute path to the library
+     * @return the resolved library handle
+     * @throws UnsatisfiedLinkError if the library could not be found or opened
+     */
+    NativeLibraryHandle getLibraryHandle(String libPath);
+
+    /**
+     * Determines if the underlying platform/runtime supports the notion of a default library search
+     * path. For example, on *nix systems, this is typically defined by the {@code LD_LIBRARY_PATH}
+     * environment variable.
+     */
+    boolean isDefaultLibrarySearchSupported();
+
+    /**
+     * Resolves the function pointer {@code NativeFunctionPointer} of a native function.
+     *
+     * @param libraries the ordered list of libraries to search for the function
+     * @param name the name of the function to be resolved
+     * @return a pointer to the native function
+     * @throws UnsatisfiedLinkError if the function could not be resolved
+     */
+    NativeFunctionPointer getFunctionPointer(NativeLibraryHandle[] libraries, String name);
+
+    /**
+     * Resolves a function name to a {@linkplain NativeFunctionHandle handle} that can be called
+     * with a given signature. The signature contains the types of the arguments that will be passed
+     * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}.
+     *
+     * @param library the handle to a resolved library
+     * @param name the name of the function to be resolved
+     * @param returnType the type of the return value
+     * @param argumentTypes the types of the arguments
+     * @return the function handle of the native function
+     * @throws UnsatisfiedLinkError if the function handle could not be resolved
+     */
+    NativeFunctionHandle getFunctionHandle(NativeLibraryHandle library, String name, Class<?> returnType, Class<?>... argumentTypes);
+
+    /**
+     * Resolves a function pointer to a {@linkplain NativeFunctionHandle handle} that can be called
+     * with a given signature. The signature contains the types of the arguments that will be passed
+     * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}.
+     *
+     * @param functionPointer a function pointer
+     * @param returnType the type of the return value
+     * @param argumentTypes the types of the arguments
+     * @return the function handle of the native function
+     * @throws UnsatisfiedLinkError the function handle could not be created
+     */
+    NativeFunctionHandle getFunctionHandle(NativeFunctionPointer functionPointer, Class<?> returnType, Class<?>... argumentTypes);
+
+    /**
+     * Resolves a function name to a {@linkplain NativeFunctionHandle handle} that can be called
+     * with a given signature. The signature contains the types of the arguments that will be passed
+     * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}.
+     *
+     * @param libraries the ordered list of libraries to search for the function
+     * @param name the name of the function to be resolved
+     * @param returnType the type of the return value
+     * @param argumentTypes the types of the arguments
+     * @return the function handle of the native function
+     * @throws UnsatisfiedLinkError if the function handle could not be created
+     */
+    NativeFunctionHandle getFunctionHandle(NativeLibraryHandle[] libraries, String name, Class<?> returnType, Class<?>... argumentTypes);
+
+    /**
+     * Resolves a function name to a {@linkplain NativeFunctionHandle handle} that can be called
+     * with a given signature. The signature contains the types of the arguments that will be passed
+     * to the handle when it is {@linkplain NativeFunctionHandle#call(Object...) called}.
+     *
+     * @param name the name of the function to be resolved
+     * @param returnType the type of the return value
+     * @param argumentTypes the types of the arguments
+     * @return the function handle of the native function
+     * @throws UnsatisfiedLinkError if default library searching is not
+     *             {@linkplain #isDefaultLibrarySearchSupported() supported} or if the function
+     *             could not be resolved
+     */
+    NativeFunctionHandle getFunctionHandle(String name, Class<?> returnType, Class<?>... argumentTypes);
+
+    /**
+     * Creates a {@link NativeFunctionPointer} from a raw value.
+     *
+     * @param rawValue raw function pointer
+     * @return {@code NativeFunctionPointer} for {@code rawValue}
+     */
+    NativeFunctionPointer getNativeFunctionPointerFromRawValue(long rawValue);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionPointer.java	Tue Aug 05 15:58:11 2014 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.nfi.api;
+
+/**
+ * An opaque representation of a native function pointer.
+ * <p>
+ * Use {@code NativeFunctionInterface#getFunctionHandle(NativeFunctionPointer, Class, Class...)} to
+ * get a handle enabling the native function to be {@linkplain NativeFunctionHandle#call(Object...)
+ * called}.
+ */
+public interface NativeFunctionPointer {
+
+    /**
+     * Returns the name of the function.
+     *
+     * @return name of the function
+     */
+    String getName();
+
+    /**
+     * Returns the raw function pointer value.
+     * 
+     * @return raw function pointer value
+     */
+    long getRawValue();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeLibraryHandle.java	Tue Aug 05 15:58:11 2014 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.nfi.api;
+
+/**
+ * An opaque representation of a native library handle. A handle is obtained via
+ * {@link NativeFunctionInterface#getLibraryHandle(String)}. A handle is used to resolve a string to
+ * a {@linkplain NativeFunctionInterface#getFunctionHandle(String, Class, Class...) handle} or
+ * {@linkplain NativeFunctionInterface#getFunctionPointer(NativeLibraryHandle[], String) pointer}.
+ */
+public interface NativeLibraryHandle {
+    /**
+     * Gets a name for this library. This may be the path for the file from which the library was
+     * loaded.
+     */
+    String getName();
+}
--- a/mx/projects	Tue Aug 05 12:34:55 2014 +0200
+++ b/mx/projects	Tue Aug 05 15:58:11 2014 +0200
@@ -103,7 +103,8 @@
 distribution@TRUFFLE@subDir=graal
 distribution@TRUFFLE@sourcesPath=build/truffle.src.zip
 distribution@TRUFFLE@dependencies=\
-com.oracle.truffle.api.dsl
+com.oracle.truffle.api.dsl,\
+com.oracle.nfi
 
 distribution@GRAAL_TRUFFLE@path=build/graal-truffle.jar
 distribution@GRAAL_TRUFFLE@subDir=graal
@@ -121,6 +122,20 @@
 com.oracle.truffle.dsl.processor
 distribution@TRUFFLE-DSL-PROCESSOR@distDependencies=TRUFFLE
 
+# nfi
+project@com.oracle.nfi@subDir=graal
+project@com.oracle.nfi@sourceDirs=src
+project@com.oracle.nfi@dependencies=
+project@com.oracle.nfi@checkstyle=com.oracle.graal.graph
+project@com.oracle.nfi@javaCompliance=1.8
+
+# nfi.test
+project@com.oracle.nfi.test@subDir=graal
+project@com.oracle.nfi.test@sourceDirs=test
+project@com.oracle.nfi.test@dependencies=com.oracle.nfi,com.oracle.graal.compiler.common,JUNIT
+project@com.oracle.nfi.test@checkstyle=com.oracle.graal.graph
+project@com.oracle.nfi.test@javaCompliance=1.8
+
 # graal.api.collections
 project@com.oracle.graal.api.collections@subDir=graal
 project@com.oracle.graal.api.collections@sourceDirs=src
@@ -161,7 +176,7 @@
 # graal.api.code
 project@com.oracle.graal.api.code@subDir=graal
 project@com.oracle.graal.api.code@sourceDirs=src
-project@com.oracle.graal.api.code@dependencies=com.oracle.graal.api.meta
+project@com.oracle.graal.api.code@dependencies=com.oracle.graal.api.meta,com.oracle.nfi
 project@com.oracle.graal.api.code@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.api.code@javaCompliance=1.8
 project@com.oracle.graal.api.code@workingSets=API,Graal
@@ -515,7 +530,7 @@
 # graal.compiler
 project@com.oracle.graal.compiler@subDir=graal
 project@com.oracle.graal.compiler@sourceDirs=src
-project@com.oracle.graal.compiler@dependencies=com.oracle.graal.virtual,com.oracle.graal.loop,com.oracle.graal.alloc
+project@com.oracle.graal.compiler@dependencies=com.oracle.graal.virtual,com.oracle.graal.loop,com.oracle.graal.alloc,com.oracle.nfi
 project@com.oracle.graal.compiler@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.compiler@javaCompliance=1.8
 project@com.oracle.graal.compiler@annotationProcessors=com.oracle.graal.service.processor
--- a/src/share/vm/graal/graalRuntime.cpp	Tue Aug 05 12:34:55 2014 +0200
+++ b/src/share/vm/graal/graalRuntime.cpp	Tue Aug 05 15:58:11 2014 +0200
@@ -664,6 +664,18 @@
   return JNIHandles::make_local((oop) result.get_jobject());
 JVM_END
 
+// private static NativeFunctionInterfaceRuntime.createInterface()
+JVM_ENTRY(jobject, JVM_CreateNativeFunctionInterface(JNIEnv *env, jclass c))
+  TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend", CHECK_NULL);
+  KlassHandle klass = GraalRuntime::resolve_or_fail(name, CHECK_NULL);
+
+  TempNewSymbol makeInstance = SymbolTable::new_symbol("createNativeFunctionInterface", CHECK_NULL);
+  TempNewSymbol sig = SymbolTable::new_symbol("()Lcom/oracle/nfi/api/NativeFunctionInterface;", CHECK_NULL);
+  JavaValue result(T_OBJECT);
+  JavaCalls::call_static(&result, klass, makeInstance, sig, CHECK_NULL);
+  return JNIHandles::make_local((oop) result.get_jobject());
+JVM_END
+
 void GraalRuntime::check_generated_sources_sha1(TRAPS) {
   TempNewSymbol name = SymbolTable::new_symbol("GeneratedSourcesSha1", CHECK_ABORT);
   KlassHandle klass = load_required_class(name);
--- a/src/share/vm/prims/nativeLookup.cpp	Tue Aug 05 12:34:55 2014 +0200
+++ b/src/share/vm/prims/nativeLookup.cpp	Tue Aug 05 15:58:11 2014 +0200
@@ -128,6 +128,7 @@
   jobject  JNICALL JVM_GetGraalRuntime(JNIEnv *env, jclass c);
   jobject  JNICALL JVM_GetGraalServiceImpls(JNIEnv *env, jclass c);
   jobject  JNICALL JVM_CreateTruffleRuntime(JNIEnv *env, jclass c);
+  jobject  JNICALL JVM_CreateNativeFunctionInterface(JNIEnv *env, jclass c);
   jboolean JNICALL JVM_ParseGraalOptions(JNIEnv *env, jclass hotspotOptionsClass);
 #ifdef COMPILERGRAAL
   void     JNICALL JVM_PrintAndResetGraalCompRate(JNIEnv *env, jclass c);
@@ -144,11 +145,12 @@
   { CC"Java_sun_misc_Perf_registerNatives",                        NULL, FN_PTR(JVM_RegisterPerfMethods)         },
   { CC"Java_sun_hotspot_WhiteBox_registerNatives",                 NULL, FN_PTR(JVM_RegisterWhiteBoxMethods)     },
 #ifdef GRAAL
-  { CC"Java_com_oracle_graal_api_runtime_Graal_initializeRuntime",            NULL, FN_PTR(JVM_GetGraalRuntime)           },
-  { CC"Java_com_oracle_graal_api_runtime_Services_getServiceImpls",           NULL, FN_PTR(JVM_GetGraalServiceImpls)      },
-  { CC"Java_com_oracle_truffle_api_Truffle_createRuntime",                    NULL, FN_PTR(JVM_CreateTruffleRuntime)      },
-  { CC"Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_init",           NULL, FN_PTR(JVM_InitializeGraalNatives)    },
-  { CC"Java_com_oracle_graal_hotspot_HotSpotOptions_parseVMOptions",          NULL, FN_PTR(JVM_ParseGraalOptions)         },
+  { CC"Java_com_oracle_graal_api_runtime_Graal_initializeRuntime",                                        NULL, FN_PTR(JVM_GetGraalRuntime)                           },
+  { CC"Java_com_oracle_graal_api_runtime_Services_getServiceImpls",                                       NULL, FN_PTR(JVM_GetGraalServiceImpls)                      },
+  { CC"Java_com_oracle_truffle_api_Truffle_createRuntime",                                                NULL, FN_PTR(JVM_CreateTruffleRuntime)                      },
+  { CC"Java_com_oracle_nfi_NativeFunctionInterfaceRuntime_createInterface",                        NULL, FN_PTR(JVM_CreateNativeFunctionInterface)      },
+  { CC"Java_com_oracle_graal_hotspot_bridge_CompilerToVMImpl_init",                                       NULL, FN_PTR(JVM_InitializeGraalNatives)                    },
+  { CC"Java_com_oracle_graal_hotspot_HotSpotOptions_parseVMOptions",                                      NULL, FN_PTR(JVM_ParseGraalOptions)                         },
 #endif
 };