changeset 12588:3b178baf3edb

fleshed out HSAIL backend a little to demonstrate changes needed after recent API/infrastructure updates
author Doug Simon <doug.simon@oracle.com>
date Fri, 25 Oct 2013 12:45:37 +0200
parents e0634d52796f
children 5310cc81f7e4 868dba721f1e
files graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/FloatSqrtTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodySpillTest.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodyTest.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotForeignCallsProvider.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotForeignCallsProviderImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRegisters.java
diffstat 10 files changed, 207 insertions(+), 176 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/FloatSqrtTest.java	Fri Oct 25 11:24:48 2013 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/FloatSqrtTest.java	Fri Oct 25 12:45:37 2013 +0200
@@ -27,9 +27,7 @@
 
 import org.junit.*;
 
-import com.oracle.graal.compiler.hsail.*;
 import com.oracle.graal.compiler.hsail.test.infra.*;
-import com.oracle.graal.graph.*;
 
 /**
  * Tests floating point square root.
@@ -58,10 +56,7 @@
         dispatchMethodKernel(64, input, output);
     }
 
-    /**
-     * Requires {@link HSAILLIRGenerator#emitDirectCall} to be implemented.
-     */
-    @Test(expected = GraalInternalError.class)
+    @Test
     public void test() {
         testGeneratedHsail();
     }
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodySpillTest.java	Fri Oct 25 11:24:48 2013 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodySpillTest.java	Fri Oct 25 12:45:37 2013 +0200
@@ -27,9 +27,7 @@
 
 import org.junit.*;
 
-import com.oracle.graal.compiler.hsail.*;
 import com.oracle.graal.compiler.hsail.test.infra.*;
-import com.oracle.graal.graph.*;
 
 /**
  * This version of NBody causes Graal to generate register spilling code.
@@ -98,10 +96,7 @@
     }
 
     // Marked to only run on hardware until simulator spill bug is fixed.
-    /**
-     * Requires {@link HSAILLIRGenerator#emitDirectCall} to be implemented.
-     */
-    @Test(expected = GraalInternalError.class)
+    @Test
     public void test() {
         testGeneratedHsail();
     }
--- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodyTest.java	Fri Oct 25 11:24:48 2013 +0200
+++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodyTest.java	Fri Oct 25 12:45:37 2013 +0200
@@ -29,7 +29,6 @@
 
 import com.oracle.graal.compiler.hsail.*;
 import com.oracle.graal.compiler.hsail.test.infra.*;
-import com.oracle.graal.graph.*;
 
 /**
  * Unit test of NBody demo app.
@@ -100,7 +99,7 @@
     /**
      * Requires {@link HSAILLIRGenerator#emitDirectCall} to be implemented.
      */
-    @Test(expected = GraalInternalError.class)
+    @Test
     public void test() {
         testGeneratedHsail();
     }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Fri Oct 25 11:24:48 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Fri Oct 25 12:45:37 2013 +0200
@@ -60,6 +60,12 @@
     }
 
     @Override
+    public void completeInitialization() {
+        HSAILHotSpotForeignCallsProvider foreignCalls = (HSAILHotSpotForeignCallsProvider) getProviders().getForeignCalls();
+        foreignCalls.initialize(getProviders(), getRuntime().getConfig());
+    }
+
+    @Override
     public boolean shouldAllocateRegisters() {
         return true;
     }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java	Fri Oct 25 11:24:48 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java	Fri Oct 25 12:45:37 2013 +0200
@@ -41,13 +41,13 @@
         HotSpotMetaAccessProvider metaAccess = host.getMetaAccess();
         HSAILHotSpotCodeCacheProvider codeCache = new HSAILHotSpotCodeCacheProvider(runtime, createTarget());
         ConstantReflectionProvider constantReflection = host.getConstantReflection();
-        HotSpotForeignCallsProvider foreignCalls = new HSAILHotSpotForeignCallsProvider(host.getForeignCalls());
+        HotSpotForeignCallsProvider foreignCalls = new HSAILHotSpotForeignCallsProvider(runtime, metaAccess, codeCache);
         LoweringProvider lowerer = new HSAILHotSpotLoweringProvider(host.getLowerer());
         // Replacements cannot have speculative optimizations since they have
         // to be valid for the entire run of the VM.
         Assumptions assumptions = new Assumptions(false);
         Providers p = new Providers(metaAccess, codeCache, constantReflection, foreignCalls, lowerer, null);
-        Replacements replacements = new HSAILHotSpotReplacementsImpl(p, assumptions);
+        Replacements replacements = new HSAILHotSpotReplacementsImpl(p, assumptions, host.getReplacements());
         HotSpotDisassemblerProvider disassembler = host.getDisassembler();
         HotSpotSuitesProvider suites = host.getSuites();
         HotSpotRegisters registers = new HotSpotRegisters(Register.None, Register.None, Register.None);
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotForeignCallsProvider.java	Fri Oct 25 11:24:48 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotForeignCallsProvider.java	Fri Oct 25 12:45:37 2013 +0200
@@ -22,36 +22,34 @@
  */
 package com.oracle.graal.hotspot.hsail;
 
+import static com.oracle.graal.api.meta.LocationIdentity.*;
+import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*;
+import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 
-public class HSAILHotSpotForeignCallsProvider implements HotSpotForeignCallsProvider {
+public class HSAILHotSpotForeignCallsProvider extends HotSpotForeignCallsProviderImpl {
 
-    private final ForeignCallsProvider host;
-
-    public HSAILHotSpotForeignCallsProvider(ForeignCallsProvider host) {
-        this.host = host;
+    public HSAILHotSpotForeignCallsProvider(HotSpotGraalRuntime runtime, MetaAccessProvider metaAccess, CodeCacheProvider codeCache) {
+        super(runtime, metaAccess, codeCache);
     }
 
-    public boolean isReexecutable(ForeignCallDescriptor descriptor) {
-        return host.isReexecutable(descriptor);
-    }
-
-    public LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor) {
-        return host.getKilledLocations(descriptor);
-    }
-
-    public boolean canDeoptimize(ForeignCallDescriptor descriptor) {
-        return host.canDeoptimize(descriptor);
-    }
-
-    public ForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) {
-        throw GraalInternalError.unimplemented();
+    @Override
+    public HotSpotForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) {
+        return super.lookupForeignCall(descriptor);
     }
 
     public Value[] getNativeABICallerSaveRegisters() {
-        throw GraalInternalError.unimplemented();
+        // TODO is this correct?
+        return new Value[0];
+    }
+
+    public void initialize(HotSpotProviders providers, HotSpotVMConfig c) {
+        // TODO are these correct? what other foreign calls are supported on HSAIL?
+        linkForeignCall(providers, CREATE_NULL_POINTER_EXCEPTION, c.createNullPointerExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
+        linkForeignCall(providers, CREATE_OUT_OF_BOUNDS_EXCEPTION, c.createOutOfBoundsExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
     }
 }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java	Fri Oct 25 11:24:48 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java	Fri Oct 25 12:45:37 2013 +0200
@@ -22,38 +22,33 @@
  */
 package com.oracle.graal.hotspot.hsail;
 
-import java.lang.reflect.*;
-
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 
 /**
- * Filters the substitutions and snippets supported by HSAIL.
+ * The substitutions and snippets supported by HSAIL.
  */
 public class HSAILHotSpotReplacementsImpl extends ReplacementsImpl {
 
-    public HSAILHotSpotReplacementsImpl(Providers providers, Assumptions assumptions) {
+    private final Replacements host;
+
+    public HSAILHotSpotReplacementsImpl(Providers providers, Assumptions assumptions, Replacements host) {
         super(providers, assumptions);
+        this.host = host;
     }
 
     @Override
-    protected ResolvedJavaMethod registerMethodSubstitution(Member originalMethod, Method substituteMethod) {
-        // TODO decide here what methods substitutions are supported
-        return null;
-    }
-
-    @Override
-    public Class<? extends FixedWithNextNode> getMacroSubstitution(ResolvedJavaMethod method) {
-        // TODO decide here what macro substitutions are supported
-        return null;
-    }
-
-    @Override
-    public StructuredGraph getSnippet(ResolvedJavaMethod method) {
-        // TODO must work in cooperation with HSAILHotSpotLoweringProvider
-        return null;
+    public StructuredGraph getMethodSubstitution(ResolvedJavaMethod original) {
+        StructuredGraph m = super.getMethodSubstitution(original);
+        if (m == null) {
+            if (original.getDeclaringClass().equals(providers.getMetaAccess().lookupJavaType(Math.class))) {
+                return host.getMethodSubstitution(original);
+            }
+        }
+        return m;
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotForeignCallsProviderImpl.java	Fri Oct 25 12:45:37 2013 +0200
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.meta;
+
+import static com.oracle.graal.api.code.CallingConvention.Type.*;
+import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*;
+import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*;
+
+import java.util.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect;
+import com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition;
+import com.oracle.graal.hotspot.stubs.*;
+import com.oracle.graal.word.*;
+
+/**
+ * HotSpot implementation of {@link HotSpotForeignCallsProvider}.
+ */
+public abstract class HotSpotForeignCallsProviderImpl implements HotSpotForeignCallsProvider {
+
+    public static final ForeignCallDescriptor OSR_MIGRATION_END = new ForeignCallDescriptor("OSR_migration_end", void.class, long.class);
+    public static final ForeignCallDescriptor IDENTITY_HASHCODE = new ForeignCallDescriptor("identity_hashcode", int.class, Object.class);
+    public static final ForeignCallDescriptor VERIFY_OOP = new ForeignCallDescriptor("verify_oop", Object.class, Object.class);
+    public static final ForeignCallDescriptor LOAD_AND_CLEAR_EXCEPTION = new ForeignCallDescriptor("load_and_clear_exception", Object.class, Word.class);
+
+    protected final HotSpotGraalRuntime runtime;
+
+    protected final Map<ForeignCallDescriptor, HotSpotForeignCallLinkage> foreignCalls = new HashMap<>();
+    protected final MetaAccessProvider metaAccess;
+    protected final CodeCacheProvider codeCache;
+
+    public HotSpotForeignCallsProviderImpl(HotSpotGraalRuntime runtime, MetaAccessProvider metaAccess, CodeCacheProvider codeCache) {
+        this.runtime = runtime;
+        this.metaAccess = metaAccess;
+        this.codeCache = codeCache;
+    }
+
+    /**
+     * Registers the linkage for a foreign call.
+     */
+    protected HotSpotForeignCallLinkage register(HotSpotForeignCallLinkage linkage) {
+        assert !foreignCalls.containsKey(linkage.getDescriptor()) : "already registered linkage for " + linkage.getDescriptor();
+        foreignCalls.put(linkage.getDescriptor(), linkage);
+        return linkage;
+    }
+
+    /**
+     * Creates and registers the details for linking a foreign call to a {@link Stub}.
+     * 
+     * @param descriptor the signature of the call to the stub
+     * @param reexecutable specifies if the stub call can be re-executed without (meaningful) side
+     *            effects. Deoptimization will not return to a point before a stub call that cannot
+     *            be re-executed.
+     * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call
+     * @param killedLocations the memory locations killed by the stub call
+     */
+    protected HotSpotForeignCallLinkage registerStubCall(ForeignCallDescriptor descriptor, boolean reexecutable, Transition transition, LocationIdentity... killedLocations) {
+        return register(HotSpotForeignCallLinkage.create(metaAccess, codeCache, this, descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, killedLocations));
+    }
+
+    /**
+     * Creates and registers the linkage for a foreign call.
+     * 
+     * @param descriptor the signature of the foreign call
+     * @param address the address of the code to call
+     * @param outgoingCcType outgoing (caller) calling convention type
+     * @param effect specifies if the call destroys or preserves all registers (apart from
+     *            temporaries which are always destroyed)
+     * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call
+     * @param reexecutable specifies if the foreign call can be re-executed without (meaningful)
+     *            side effects. Deoptimization will not return to a point before a foreign call that
+     *            cannot be re-executed.
+     * @param killedLocations the memory locations killed by the foreign call
+     */
+    protected HotSpotForeignCallLinkage registerForeignCall(ForeignCallDescriptor descriptor, long address, CallingConvention.Type outgoingCcType, RegisterEffect effect, Transition transition,
+                    boolean reexecutable, LocationIdentity... killedLocations) {
+        Class<?> resultType = descriptor.getResultType();
+        assert transition == LEAF || resultType.isPrimitive() || Word.class.isAssignableFrom(resultType) : "non-leaf foreign calls must return objects in thread local storage: " + descriptor;
+        return register(HotSpotForeignCallLinkage.create(metaAccess, codeCache, this, descriptor, address, effect, outgoingCcType, null, transition, reexecutable, killedLocations));
+    }
+
+    /**
+     * Creates a {@linkplain ForeignCallStub stub} for a foreign call.
+     * 
+     * @param descriptor the signature of the call to the stub
+     * @param address the address of the foreign code to call
+     * @param prependThread true if the JavaThread value for the current thread is to be prepended
+     *            to the arguments for the call to {@code address}
+     * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call
+     * @param reexecutable specifies if the foreign call can be re-executed without (meaningful)
+     *            side effects. Deoptimization will not return to a point before a foreign call that
+     *            cannot be re-executed.
+     * @param killedLocations the memory locations killed by the foreign call
+     */
+    protected void linkForeignCall(HotSpotProviders providers, ForeignCallDescriptor descriptor, long address, boolean prependThread, Transition transition, boolean reexecutable,
+                    LocationIdentity... killedLocations) {
+        ForeignCallStub stub = new ForeignCallStub(providers, address, descriptor, prependThread, transition, reexecutable, killedLocations);
+        HotSpotForeignCallLinkage linkage = stub.getLinkage();
+        HotSpotForeignCallLinkage targetLinkage = stub.getTargetLinkage();
+        linkage.setCompiledStub(stub);
+        register(linkage);
+        register(targetLinkage);
+    }
+
+    public static final boolean PREPEND_THREAD = true;
+    public static final boolean DONT_PREPEND_THREAD = !PREPEND_THREAD;
+
+    public static final boolean REEXECUTABLE = true;
+    public static final boolean NOT_REEXECUTABLE = !REEXECUTABLE;
+
+    public static final LocationIdentity[] NO_LOCATIONS = {};
+
+    public HotSpotForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) {
+        HotSpotForeignCallLinkage callTarget = foreignCalls.get(descriptor);
+        assert foreignCalls != null : descriptor;
+        callTarget.finalizeAddress(runtime.getHostBackend());
+        return callTarget;
+    }
+
+    @Override
+    public boolean isReexecutable(ForeignCallDescriptor descriptor) {
+        assert foreignCalls.containsKey(descriptor) : "unknown foreign call: " + descriptor;
+        return foreignCalls.get(descriptor).isReexecutable();
+    }
+
+    public boolean canDeoptimize(ForeignCallDescriptor descriptor) {
+        assert foreignCalls.containsKey(descriptor) : "unknown foreign call: " + descriptor;
+        return foreignCalls.get(descriptor).canDeoptimize();
+    }
+
+    public LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor) {
+        assert foreignCalls.containsKey(descriptor) : "unknown foreign call: " + descriptor;
+        return foreignCalls.get(descriptor).getKilledLocations();
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java	Fri Oct 25 11:24:48 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java	Fri Oct 25 12:45:37 2013 +0200
@@ -48,117 +48,24 @@
 import static com.oracle.graal.replacements.Log.*;
 import static com.oracle.graal.replacements.MathSubstitutionsX86.*;
 
-import java.util.*;
-
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect;
-import com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition;
 import com.oracle.graal.hotspot.stubs.*;
-import com.oracle.graal.word.*;
 
 /**
  * HotSpot implementation of {@link ForeignCallsProvider}.
  */
-public abstract class HotSpotHostForeignCallsProvider implements HotSpotForeignCallsProvider {
-
-    public static final ForeignCallDescriptor OSR_MIGRATION_END = new ForeignCallDescriptor("OSR_migration_end", void.class, long.class);
-    public static final ForeignCallDescriptor IDENTITY_HASHCODE = new ForeignCallDescriptor("identity_hashcode", int.class, Object.class);
-    public static final ForeignCallDescriptor VERIFY_OOP = new ForeignCallDescriptor("verify_oop", Object.class, Object.class);
-    public static final ForeignCallDescriptor LOAD_AND_CLEAR_EXCEPTION = new ForeignCallDescriptor("load_and_clear_exception", Object.class, Word.class);
-
-    protected final HotSpotGraalRuntime runtime;
-
-    private final Map<ForeignCallDescriptor, HotSpotForeignCallLinkage> foreignCalls = new HashMap<>();
-    private final MetaAccessProvider metaAccess;
-    private final CodeCacheProvider codeCache;
+public abstract class HotSpotHostForeignCallsProvider extends HotSpotForeignCallsProviderImpl {
 
     public HotSpotHostForeignCallsProvider(HotSpotGraalRuntime runtime, MetaAccessProvider metaAccess, CodeCacheProvider codeCache) {
-        this.runtime = runtime;
-        this.metaAccess = metaAccess;
-        this.codeCache = codeCache;
-    }
-
-    /**
-     * Registers the linkage for a foreign call.
-     */
-    protected HotSpotForeignCallLinkage register(HotSpotForeignCallLinkage linkage) {
-        assert !foreignCalls.containsKey(linkage.getDescriptor()) : "already registered linkage for " + linkage.getDescriptor();
-        foreignCalls.put(linkage.getDescriptor(), linkage);
-        return linkage;
-    }
-
-    /**
-     * Creates and registers the details for linking a foreign call to a {@link Stub}.
-     * 
-     * @param descriptor the signature of the call to the stub
-     * @param reexecutable specifies if the stub call can be re-executed without (meaningful) side
-     *            effects. Deoptimization will not return to a point before a stub call that cannot
-     *            be re-executed.
-     * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call
-     * @param killedLocations the memory locations killed by the stub call
-     */
-    protected HotSpotForeignCallLinkage registerStubCall(ForeignCallDescriptor descriptor, boolean reexecutable, Transition transition, LocationIdentity... killedLocations) {
-        return register(HotSpotForeignCallLinkage.create(metaAccess, codeCache, this, descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, killedLocations));
-    }
-
-    /**
-     * Creates and registers the linkage for a foreign call.
-     * 
-     * @param descriptor the signature of the foreign call
-     * @param address the address of the code to call
-     * @param outgoingCcType outgoing (caller) calling convention type
-     * @param effect specifies if the call destroys or preserves all registers (apart from
-     *            temporaries which are always destroyed)
-     * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call
-     * @param reexecutable specifies if the foreign call can be re-executed without (meaningful)
-     *            side effects. Deoptimization will not return to a point before a foreign call that
-     *            cannot be re-executed.
-     * @param killedLocations the memory locations killed by the foreign call
-     */
-    protected HotSpotForeignCallLinkage registerForeignCall(ForeignCallDescriptor descriptor, long address, CallingConvention.Type outgoingCcType, RegisterEffect effect, Transition transition,
-                    boolean reexecutable, LocationIdentity... killedLocations) {
-        Class<?> resultType = descriptor.getResultType();
-        assert transition == LEAF || resultType.isPrimitive() || Word.class.isAssignableFrom(resultType) : "non-leaf foreign calls must return objects in thread local storage: " + descriptor;
-        return register(HotSpotForeignCallLinkage.create(metaAccess, codeCache, this, descriptor, address, effect, outgoingCcType, null, transition, reexecutable, killedLocations));
+        super(runtime, metaAccess, codeCache);
     }
 
     private static void link(Stub stub) {
         stub.getLinkage().setCompiledStub(stub);
     }
 
-    /**
-     * Creates a {@linkplain ForeignCallStub stub} for a foreign call.
-     * 
-     * @param descriptor the signature of the call to the stub
-     * @param address the address of the foreign code to call
-     * @param prependThread true if the JavaThread value for the current thread is to be prepended
-     *            to the arguments for the call to {@code address}
-     * @param transition specifies if this is a {@linkplain Transition#LEAF leaf} call
-     * @param reexecutable specifies if the foreign call can be re-executed without (meaningful)
-     *            side effects. Deoptimization will not return to a point before a foreign call that
-     *            cannot be re-executed.
-     * @param killedLocations the memory locations killed by the foreign call
-     */
-    private void linkForeignCall(HotSpotProviders providers, ForeignCallDescriptor descriptor, long address, boolean prependThread, Transition transition, boolean reexecutable,
-                    LocationIdentity... killedLocations) {
-        ForeignCallStub stub = new ForeignCallStub(providers, address, descriptor, prependThread, transition, reexecutable, killedLocations);
-        HotSpotForeignCallLinkage linkage = stub.getLinkage();
-        HotSpotForeignCallLinkage targetLinkage = stub.getTargetLinkage();
-        linkage.setCompiledStub(stub);
-        register(linkage);
-        register(targetLinkage);
-    }
-
-    public static final boolean PREPEND_THREAD = true;
-    public static final boolean DONT_PREPEND_THREAD = !PREPEND_THREAD;
-
-    public static final boolean REEXECUTABLE = true;
-    public static final boolean NOT_REEXECUTABLE = !REEXECUTABLE;
-
-    public static final LocationIdentity[] NO_LOCATIONS = {};
-
     public void initialize(HotSpotProviders providers, HotSpotVMConfig c) {
         TargetDescription target = providers.getCodeCache().getTarget();
 
@@ -203,29 +110,4 @@
         linkForeignCall(providers, G1WBPOSTCALL, c.writeBarrierPostAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
         linkForeignCall(providers, VALIDATE_OBJECT, c.validateObject, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
     }
-
-    public HotSpotForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) {
-        HotSpotForeignCallLinkage callTarget = foreignCalls.get(descriptor);
-        assert foreignCalls != null : descriptor;
-        callTarget.finalizeAddress(runtime.getHostBackend());
-        return callTarget;
-    }
-
-    @Override
-    public boolean isReexecutable(ForeignCallDescriptor descriptor) {
-        return foreignCalls.get(descriptor).isReexecutable();
-    }
-
-    public boolean canDeoptimize(ForeignCallDescriptor descriptor) {
-        return foreignCalls.get(descriptor).canDeoptimize();
-    }
-
-    public LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor) {
-        return foreignCalls.get(descriptor).getKilledLocations();
-    }
-
-    /**
-     * Gets the registers that must be saved across a foreign call into the runtime.
-     */
-    public abstract Value[] getNativeABICallerSaveRegisters();
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRegisters.java	Fri Oct 25 11:24:48 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRegisters.java	Fri Oct 25 12:45:37 2013 +0200
@@ -37,14 +37,17 @@
     }
 
     public Register getThreadRegister() {
+        assert !threadRegister.equals(Register.None) : "thread register is not defined";
         return threadRegister;
     }
 
     public Register getHeapBaseRegister() {
+        assert !heapBaseRegister.equals(Register.None) : "heap base register is not defined";
         return heapBaseRegister;
     }
 
     public Register getStackPointerRegister() {
+        assert !stackPointerRegister.equals(Register.None) : "stack pointer register is not defined";
         return stackPointerRegister;
     }
 }