changeset 20872:b1700db197c7

Move com.oracle.nfi implementation to graal.truffle.hotspot since it implements an interface that does not live in the graal class-loader
author Gilles Duboscq <gilles.m.duboscq@oracle.com>
date Thu, 09 Apr 2015 17:40:55 +0200
parents 762e03b40d3d
children c9a8c62c60fc 50a3be6223a7
files graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.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.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64RawNativeCallNodeFactory.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/HotSpotNativeFunctionHandle.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/HotSpotNativeFunctionInterface.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/HotSpotNativeFunctionPointer.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/HotSpotNativeLibraryHandle.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/NativeCallStubGraphBuilder.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/RawNativeCallNodeFactory.java mx/suite.py src/share/vm/graal/graalRuntime.cpp
diffstat 17 files changed, 689 insertions(+), 647 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Thu Apr 09 17:50:15 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Thu Apr 09 17:40:55 2015 +0200
@@ -41,7 +41,6 @@
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId;
 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.*;
@@ -50,7 +49,6 @@
 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.
@@ -326,18 +324,4 @@
         }
     }
 
-    /**
-     * Called from the VM.
-     */
-    public static NativeFunctionInterface createNativeFunctionInterface() {
-        HotSpotVMConfig config = HotSpotGraalRuntime.runtime().getConfig();
-        RawNativeCallNodeFactory factory = new RawNativeCallNodeFactory() {
-            public FixedWithNextNode createRawCallNode(Kind returnType, JavaConstant functionPointer, ValueNode... args) {
-                return new AMD64RawNativeCallNode(returnType, functionPointer, args);
-            }
-        };
-        Backend backend = HotSpotGraalRuntime.runtime().getHostBackend();
-        return new HotSpotNativeFunctionInterface(HotSpotGraalRuntime.runtime().getHostProviders(), factory, backend, config.dllLoad, config.dllLookup, config.rtldDefault);
-    }
-
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionHandle.java	Thu Apr 09 17:50:15 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +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.hotspot.nfi;
-
-import java.util.*;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-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 {
-
-    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.executeVarargs(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;
-    }
-
-    @Override
-    public String toString() {
-        return name + Arrays.toString(argumentTypes);
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionInterface.java	Thu Apr 09 17:50:15 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,201 +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.hotspot.nfi;
-
-import static com.oracle.graal.api.code.CodeUtil.*;
-import static com.oracle.graal.compiler.common.UnsafeAccess.*;
-import static com.oracle.graal.hotspot.nfi.NativeCallStubGraphBuilder.*;
-
-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.*;
-import com.oracle.graal.compiler.target.*;
-import com.oracle.graal.debug.*;
-import com.oracle.graal.debug.Debug.Scope;
-import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.lir.asm.*;
-import com.oracle.graal.lir.phases.*;
-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 {
-
-    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;
-        assert backend != null;
-        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, false);
-        return createHandle(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;
-        if (hs != null) {
-            InstalledCode code = installNativeFunctionStub(hs.value, returnType, argumentTypes);
-            return new HotSpotNativeFunctionHandle(code, hs.name, argumentTypes);
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * 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();
-        LIRSuites lirSuites = providers.getSuites().createLIRSuites();
-        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(), phaseSuite, OptimisticOptimizations.ALL,
-                        DefaultProfilingInfo.get(TriState.UNKNOWN), null, suites, lirSuites, new CompilationResult(), CompilationResultBuilderFactory.Default);
-        InstalledCode installedCode;
-        try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache(), g.method())) {
-            installedCode = providers.getCodeCache().addMethod(g.method(), compResult, null, null);
-        } catch (Throwable e) {
-            throw Debug.handle(e);
-        }
-        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, false);
-    }
-
-    public boolean isDefaultLibrarySearchSupported() {
-        return rtldDefault != null;
-    }
-
-    @Override
-    public NativeFunctionPointer getNativeFunctionPointerFromRawValue(long rawValue) {
-        return new HotSpotNativeFunctionPointer(rawValue, null);
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeFunctionPointer.java	Thu Apr 09 17:50:15 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +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.hotspot.nfi;
-
-import com.oracle.nfi.api.*;
-
-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 getRawValue() {
-        return value;
-    }
-
-    @Override
-    public String toString() {
-        return name + "@0x" + Long.toHexString(value);
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/HotSpotNativeLibraryHandle.java	Thu Apr 09 17:50:15 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +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.hotspot.nfi;
-
-import com.oracle.nfi.api.*;
-
-public class HotSpotNativeLibraryHandle implements NativeLibraryHandle {
-
-    final long value;
-    final String name;
-
-    public HotSpotNativeLibraryHandle(String name, long handle) {
-        this.name = name;
-        this.value = handle;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof HotSpotNativeLibraryHandle) {
-            HotSpotNativeLibraryHandle that = (HotSpotNativeLibraryHandle) obj;
-            return that.value == value;
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return (int) value;
-    }
-
-    @Override
-    public String toString() {
-        return name + "@" + value;
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java	Thu Apr 09 17:50:15 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,178 +0,0 @@
-/*
- * Copyright (c) 2014, 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.compiler.common.*;
-import com.oracle.graal.compiler.common.type.*;
-import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.virtual.*;
-
-/**
- * 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, AllowAssumptions.NO);
-            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(null, method, 0, Arrays.asList(new ValueNode[]{arg0, arg1, arg2}), 3, 0, false, false, null, new ArrayList<EscapeObjectState>()));
-            g.start().setStateAfter(frameState);
-            List<ValueNode> parameters = new ArrayList<>();
-            FixedWithNextNode fixedWithNext = getParameters(g, arg0, argumentTypes.length, argumentTypes, parameters, providers);
-            JavaConstant functionPointerNode = JavaConstant.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.getKind() != Kind.Void) {
-                if (callNode.getKind() == Kind.Object) {
-                    throw new IllegalArgumentException("Return type not supported: " + returnType.getName());
-                }
-                ResolvedJavaType type = providers.getMetaAccess().lookupJavaType(callNode.getKind().toBoxedJavaClass());
-                boxedResult = g.unique(new BoxNode(callNode, type, callNode.getKind()));
-            } 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);
-            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 = runtime().getArrayBaseOffset(arrayElementKind);
-                ConstantNode index = ConstantNode.forInt(0, g);
-                int indexScaling = runtime().getArrayIndexScale(arrayElementKind);
-                IndexedLocationNode locationNode = g.unique(new IndexedLocationNode(locationIdentity, displacement, index, indexScaling));
-                Stamp wordStamp = StampFactory.forKind(providers.getWordTypes().getWordKind());
-                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()) {
-            return 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");
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/RawNativeCallNodeFactory.java	Thu Apr 09 17:50:15 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2014, 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, JavaConstant functionPointer, ValueNode... args);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle.hotspot.amd64/src/com/oracle/graal/truffle/hotspot/amd64/AMD64RawNativeCallNodeFactory.java	Thu Apr 09 17:40:55 2015 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015, 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.truffle.hotspot.amd64;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.hotspot.amd64.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.truffle.hotspot.nfi.*;
+
+@ServiceProvider(RawNativeCallNodeFactory.class)
+public class AMD64RawNativeCallNodeFactory implements RawNativeCallNodeFactory {
+    public FixedWithNextNode createRawCallNode(Kind returnType, JavaConstant functionPointer, ValueNode... args) {
+        return new AMD64RawNativeCallNode(returnType, functionPointer, args);
+    }
+
+    public String getArchitecture() {
+        return "AMD64";
+    }
+}
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Thu Apr 09 17:50:15 2015 +0200
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Thu Apr 09 17:40:55 2015 +0200
@@ -57,6 +57,8 @@
 import com.oracle.graal.printer.*;
 import com.oracle.graal.runtime.*;
 import com.oracle.graal.truffle.*;
+import com.oracle.graal.truffle.hotspot.nfi.*;
+import com.oracle.nfi.api.*;
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.nodes.*;
 
@@ -337,4 +339,27 @@
             throw new GraalInternalError(e);
         }
     }
+
+    private static RawNativeCallNodeFactory getRawNativeCallNodeFactory(String arch) {
+        for (RawNativeCallNodeFactory factory : Services.load(RawNativeCallNodeFactory.class)) {
+            if (factory.getArchitecture().equals(arch)) {
+                return factory;
+            }
+        }
+        // No RawNativeCallNodeFactory on this platform.
+        return null;
+    }
+
+    /**
+     * Called from the VM.
+     */
+    public static NativeFunctionInterface createNativeFunctionInterface() {
+        HotSpotVMConfig config = HotSpotGraalRuntime.runtime().getConfig();
+        Backend backend = HotSpotGraalRuntime.runtime().getHostBackend();
+        RawNativeCallNodeFactory factory = getRawNativeCallNodeFactory(backend.getTarget().arch.getName());
+        if (factory == null) {
+            return null;
+        }
+        return new HotSpotNativeFunctionInterface(HotSpotGraalRuntime.runtime().getHostProviders(), factory, backend, config.dllLoad, config.dllLookup, config.rtldDefault);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/HotSpotNativeFunctionHandle.java	Thu Apr 09 17:40:55 2015 +0200
@@ -0,0 +1,95 @@
+/*
+ * 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.truffle.hotspot.nfi;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+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 {
+
+    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.executeVarargs(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;
+    }
+
+    @Override
+    public String toString() {
+        return name + Arrays.toString(argumentTypes);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/HotSpotNativeFunctionInterface.java	Thu Apr 09 17:40:55 2015 +0200
@@ -0,0 +1,201 @@
+/*
+ * 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.truffle.hotspot.nfi;
+
+import static com.oracle.graal.api.code.CodeUtil.*;
+import static com.oracle.graal.compiler.common.UnsafeAccess.*;
+import static com.oracle.graal.truffle.hotspot.nfi.NativeCallStubGraphBuilder.*;
+
+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.*;
+import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.lir.phases.*;
+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 {
+
+    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;
+        assert backend != null;
+        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, false);
+        return createHandle(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;
+        if (hs != null) {
+            InstalledCode code = installNativeFunctionStub(hs.value, returnType, argumentTypes);
+            return new HotSpotNativeFunctionHandle(code, hs.name, argumentTypes);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * 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();
+        LIRSuites lirSuites = providers.getSuites().createLIRSuites();
+        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(), phaseSuite, OptimisticOptimizations.ALL,
+                        DefaultProfilingInfo.get(TriState.UNKNOWN), null, suites, lirSuites, new CompilationResult(), CompilationResultBuilderFactory.Default);
+        InstalledCode installedCode;
+        try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache(), g.method())) {
+            installedCode = providers.getCodeCache().addMethod(g.method(), compResult, null, null);
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
+        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, false);
+    }
+
+    public boolean isDefaultLibrarySearchSupported() {
+        return rtldDefault != null;
+    }
+
+    @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.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/HotSpotNativeFunctionPointer.java	Thu Apr 09 17:40:55 2015 +0200
@@ -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.truffle.hotspot.nfi;
+
+import com.oracle.nfi.api.*;
+
+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 getRawValue() {
+        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.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/HotSpotNativeLibraryHandle.java	Thu Apr 09 17:40:55 2015 +0200
@@ -0,0 +1,59 @@
+/*
+ * 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.truffle.hotspot.nfi;
+
+import com.oracle.nfi.api.*;
+
+public class HotSpotNativeLibraryHandle implements NativeLibraryHandle {
+
+    final long value;
+    final String name;
+
+    public HotSpotNativeLibraryHandle(String name, long handle) {
+        this.name = name;
+        this.value = handle;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof HotSpotNativeLibraryHandle) {
+            HotSpotNativeLibraryHandle that = (HotSpotNativeLibraryHandle) obj;
+            return that.value == value;
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return (int) value;
+    }
+
+    @Override
+    public String toString() {
+        return name + "@" + value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/NativeCallStubGraphBuilder.java	Thu Apr 09 17:40:55 2015 +0200
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2014, 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.truffle.hotspot.nfi;
+
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.virtual.*;
+
+/**
+ * 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, AllowAssumptions.NO);
+            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(null, method, 0, Arrays.asList(new ValueNode[]{arg0, arg1, arg2}), 3, 0, false, false, null, new ArrayList<EscapeObjectState>()));
+            g.start().setStateAfter(frameState);
+            List<ValueNode> parameters = new ArrayList<>();
+            FixedWithNextNode fixedWithNext = getParameters(g, arg0, argumentTypes.length, argumentTypes, parameters, providers);
+            JavaConstant functionPointerNode = JavaConstant.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.getKind() != Kind.Void) {
+                if (callNode.getKind() == Kind.Object) {
+                    throw new IllegalArgumentException("Return type not supported: " + returnType.getName());
+                }
+                ResolvedJavaType type = providers.getMetaAccess().lookupJavaType(callNode.getKind().toBoxedJavaClass());
+                boxedResult = g.unique(new BoxNode(callNode, type, callNode.getKind()));
+            } 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);
+            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 = runtime().getArrayBaseOffset(arrayElementKind);
+                ConstantNode index = ConstantNode.forInt(0, g);
+                int indexScaling = runtime().getArrayIndexScale(arrayElementKind);
+                IndexedLocationNode locationNode = g.unique(new IndexedLocationNode(locationIdentity, displacement, index, indexScaling));
+                Stamp wordStamp = StampFactory.forKind(providers.getWordTypes().getWordKind());
+                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()) {
+            return 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.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/RawNativeCallNodeFactory.java	Thu Apr 09 17:40:55 2015 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014, 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.truffle.hotspot.nfi;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.nodes.*;
+
+/**
+ * Factory for creating a node that makes a direct call to a native function pointer.
+ */
+public interface RawNativeCallNodeFactory extends Service {
+    FixedWithNextNode createRawCallNode(Kind returnType, JavaConstant functionPointer, ValueNode... args);
+
+    String getArchitecture();
+}
--- a/mx/suite.py	Thu Apr 09 17:50:15 2015 +0200
+++ b/mx/suite.py	Thu Apr 09 17:40:55 2015 +0200
@@ -329,7 +329,6 @@
         "com.oracle.graal.runtime",
         "com.oracle.graal.printer",
         "com.oracle.graal.hotspotvmconfig",
-        "com.oracle.nfi",
       ],
       "checkstyle" : "com.oracle.graal.graph",
       "annotationProcessors" : [
@@ -1079,6 +1078,7 @@
       "dependencies" : [
         "com.oracle.graal.truffle",
         "com.oracle.graal.hotspot",
+        "com.oracle.nfi",
       ],
       "checkstyle" : "com.oracle.graal.graph",
       "javaCompliance" : "1.8",
@@ -1091,7 +1091,7 @@
       "sourceDirs" : ["src"],
       "dependencies" : [
         "com.oracle.graal.truffle.hotspot",
-        "com.oracle.graal.asm.amd64",
+        "com.oracle.graal.hotspot.amd64",
       ],
       "checkstyle" : "com.oracle.graal.graph",
       "javaCompliance" : "1.8",
--- a/src/share/vm/graal/graalRuntime.cpp	Thu Apr 09 17:50:15 2015 +0200
+++ b/src/share/vm/graal/graalRuntime.cpp	Thu Apr 09 17:40:55 2015 +0200
@@ -652,18 +652,8 @@
 
 // private static NativeFunctionInterfaceRuntime.createInterface()
 JVM_ENTRY(jobject, JVM_CreateNativeFunctionInterface(JNIEnv *env, jclass c))
-  const char* backendName = NULL;
-  #ifdef TARGET_ARCH_x86
-  #ifdef _LP64
-    backendName = "com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend";
-  #endif
-  #endif
-
-  if (backendName == NULL) {
-    return NULL;
-  }
   GraalRuntime::ensure_graal_class_loader_is_initialized();
-  TempNewSymbol name = SymbolTable::new_symbol(backendName, CHECK_NULL);
+  TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime", CHECK_NULL);
   KlassHandle klass = GraalRuntime::resolve_or_fail(name, CHECK_NULL);
 
   TempNewSymbol makeInstance = SymbolTable::new_symbol("createNativeFunctionInterface", CHECK_NULL);