changeset 20873:c9a8c62c60fc

Merge.
author Doug Simon <doug.simon@oracle.com>
date Thu, 09 Apr 2015 18:56:06 +0200
parents d2ce468854b4 (current diff) b1700db197c7 (diff)
children 9ea32f3fc8ce
files 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.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java mx/suite.py
diffstat 21 files changed, 797 insertions(+), 668 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:04:05 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Thu Apr 09 18:56:06 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:04:05 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:04:05 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:04:05 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:04:05 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:04:05 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:04:05 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);
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Thu Apr 09 17:04:05 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Thu Apr 09 18:56:06 2015 +0200
@@ -407,7 +407,7 @@
                         TLAB_END_LOCATION);
         private final SnippetInfo allocateInstanceDynamic = snippet(NewObjectSnippets.class, "allocateInstanceDynamic", INIT_LOCATION, MARK_WORD_LOCATION, HUB_WRITE_LOCATION, TLAB_TOP_LOCATION,
                         TLAB_END_LOCATION);
-        private final SnippetInfo newmultiarray = snippet(NewObjectSnippets.class, "newmultiarray", INIT_LOCATION);
+        private final SnippetInfo newmultiarray = snippet(NewObjectSnippets.class, "newmultiarray", INIT_LOCATION, TLAB_TOP_LOCATION, TLAB_END_LOCATION);
         private final SnippetInfo verifyHeap = snippet(NewObjectSnippets.class, "verifyHeap");
 
         public Templates(HotSpotProviders providers, TargetDescription target) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/UnsignedIntegerTest.java	Thu Apr 09 18:56:06 2015 +0200
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2015, 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.replacements.test;
+
+import org.junit.*;
+
+import com.oracle.graal.compiler.test.*;
+
+/**
+ * Tests the unsigned operations on {@link Integer} and {@link Long}.
+ */
+public class UnsignedIntegerTest extends GraalCompilerTest {
+
+    public static int compareInteger(int a, int b) {
+        return Integer.compareUnsigned(a, b);
+    }
+
+    public static int divideInteger(int a, int b) {
+        return Integer.divideUnsigned(a, b);
+    }
+
+    public static int remainderInteger(int a, int b) {
+        return Integer.remainderUnsigned(a, b);
+    }
+
+    public static long compareLong(long a, long b) {
+        return Long.compareUnsigned(a, b);
+    }
+
+    public static long divideLong(long a, long b) {
+        return Long.divideUnsigned(a, b);
+    }
+
+    public static long remainderLong(long a, long b) {
+        return Long.remainderUnsigned(a, b);
+    }
+
+    private void testInteger(int a, int b) {
+        test("compareInteger", a, b);
+        test("divideInteger", a, b);
+        test("remainderInteger", a, b);
+    }
+
+    private void testLong(long a, long b) {
+        test("compareLong", a, b);
+        test("divideLong", a, b);
+        test("remainderLong", a, b);
+    }
+
+    @Test
+    public void testInteger() {
+        testInteger(5, 7);
+        testInteger(-3, -7);
+        testInteger(-3, 7);
+        testInteger(42, -5);
+    }
+
+    @Test
+    public void testLong() {
+        testLong(5, 7);
+        testLong(-3, -7);
+        testLong(-3, 7);
+        testLong(42, -5);
+    }
+}
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Thu Apr 09 17:04:05 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Thu Apr 09 18:56:06 2015 +0200
@@ -725,7 +725,7 @@
 
         assert checkAllVarargPlaceholdersAreDeleted(parameterCount, placeholders);
 
-        new FloatingReadPhase(false, true).apply(snippetCopy);
+        new FloatingReadPhase(true, true).apply(snippetCopy);
 
         MemoryAnchorNode anchor = snippetCopy.add(new MemoryAnchorNode());
         snippetCopy.start().replaceAtUsages(InputType.Memory, anchor);
@@ -1003,14 +1003,14 @@
             LocationIdentity locationIdentity = ((MemoryCheckpoint.Single) replacee).getLocationIdentity();
             if (locationIdentity.isAny()) {
                 assert !(memoryMap.getLastLocationAccess(any()) instanceof MemoryAnchorNode) : replacee + " kills ANY_LOCATION, but snippet does not";
+                // if the replacee kills ANY_LOCATION, the snippet can kill arbitrary locations
+                return true;
             }
             assert kills.contains(locationIdentity) : replacee + " kills " + locationIdentity + ", but snippet doesn't contain a kill to this location";
-            return true;
+            kills.remove(locationIdentity);
         }
         assert !(replacee instanceof MemoryCheckpoint.Multi) : replacee + " multi not supported (yet)";
 
-        Debug.log("WARNING: %s is not a MemoryCheckpoint, but the snippet graph contains kills (%s). You might want %s to be a MemoryCheckpoint", replacee, kills, replacee);
-
         // remove ANY_LOCATION if it's just a kill by the start node
         if (memoryMap.getLastLocationAccess(any()) instanceof MemoryAnchorNode) {
             kills.remove(any());
@@ -1019,24 +1019,26 @@
         // node can only lower to a ANY_LOCATION kill if the replacee also kills ANY_LOCATION
         assert !kills.contains(any()) : "snippet graph contains a kill to ANY_LOCATION, but replacee (" + replacee + ") doesn't kill ANY_LOCATION.  kills: " + kills;
 
+        if (SnippetCounters.getValue()) {
+            /*
+             * accesses to snippet counters are artificially introduced and violate the memory
+             * semantics.
+             */
+            kills.remove(SnippetCounter.SNIPPET_COUNTER_LOCATION);
+        }
+
         /*
-         * kills to other locations than ANY_LOCATION can be still inserted if there aren't any
-         * floating reads accessing this locations. Example: In HotSpot, InstanceOfNode is lowered
-         * to a snippet containing a write to SECONDARY_SUPER_CACHE_LOCATION. This is runtime
-         * specific, so the runtime independent InstanceOfNode can not kill this location. However,
-         * if no FloatingReadNode is reading from this location, the kill to this location is fine.
+         * Kills to private locations are safe, since there can be no floating read to these
+         * locations except reads that are introduced by the snippet itself or related snippets in
+         * the same lowering round. These reads are anchored to a MemoryAnchor at the beginning of
+         * their snippet, so they can not float above a kill in another instance of the same
+         * snippet.
          */
-        for (FloatingReadNode frn : replacee.graph().getNodes().filter(FloatingReadNode.class)) {
-            LocationIdentity locationIdentity = frn.location().getLocationIdentity();
-            if (SnippetCounters.getValue()) {
-                // accesses to snippet counters are artificially introduced and violate the memory
-                // semantics.
-                if (locationIdentity.equals(SnippetCounter.SNIPPET_COUNTER_LOCATION)) {
-                    continue;
-                }
-            }
-            assert !kills.contains(locationIdentity) : frn + " reads from location \"" + locationIdentity + "\" but " + replacee + " does not kill this location";
+        for (LocationIdentity p : this.info.privateLocations) {
+            kills.remove(p);
         }
+
+        assert kills.isEmpty() : "snippet graph kills non-private locations " + Arrays.toString(kills.toArray()) + " that replacee (" + replacee + ") doesn't kill";
         return true;
     }
 
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java	Thu Apr 09 17:04:05 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java	Thu Apr 09 18:56:06 2015 +0200
@@ -194,7 +194,7 @@
         });
         r.register2("remainderUnsigned", type, type, new InvocationPlugin() {
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode dividend, ValueNode divisor) {
-                b.push(kind, b.recursiveAppend(new UnsignedDivNode(dividend, divisor).canonical(null, dividend, divisor)));
+                b.push(kind, b.recursiveAppend(new UnsignedRemNode(dividend, divisor).canonical(null, dividend, divisor)));
                 return true;
             }
         });
--- /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 18:56:06 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:04:05 2015 +0200
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Thu Apr 09 18:56:06 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 18:56:06 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 18:56:06 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 18:56:06 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 18:56:06 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 18:56:06 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 18:56:06 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:04:05 2015 +0200
+++ b/mx/suite.py	Thu Apr 09 18:56:06 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" : [
@@ -1093,6 +1092,7 @@
       "dependencies" : [
         "com.oracle.graal.truffle",
         "com.oracle.graal.hotspot",
+        "com.oracle.nfi",
       ],
       "checkstyle" : "com.oracle.graal.graph",
       "javaCompliance" : "1.8",
@@ -1105,7 +1105,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:04:05 2015 +0200
+++ b/src/share/vm/graal/graalRuntime.cpp	Thu Apr 09 18:56:06 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);