changeset 9047:1946c86f8842

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Fri, 12 Apr 2013 17:23:14 +0200
parents c6a1ffc707ff (current diff) d4da9378903d (diff)
children c7f289614722 c46b5c340660
files
diffstat 18 files changed, 175 insertions(+), 127 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Fri Apr 12 17:22:54 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Fri Apr 12 17:23:14 2013 +0200
@@ -405,6 +405,7 @@
                 }
                 long start = System.currentTimeMillis();
                 PhasePlan phasePlan = new PhasePlan();
+                StructuredGraph graphCopy = graph.copy();
                 GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
                 phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
                 phasePlan.addPhase(PhasePosition.LOW_LEVEL, new WriteBarrierAdditionPhase());
@@ -414,7 +415,7 @@
                 if (printCompilation) {
                     TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize()));
                 }
-                return addMethod(method, compResult);
+                return addMethod(method, compResult, graphCopy);
             }
         });
 
@@ -424,12 +425,12 @@
         return installedCode;
     }
 
-    protected InstalledCode addMethod(final ResolvedJavaMethod method, final CompilationResult compResult) {
+    protected InstalledCode addMethod(final ResolvedJavaMethod method, final CompilationResult compResult, final StructuredGraph graph) {
         return Debug.scope("CodeInstall", new Object[]{runtime, method}, new Callable<InstalledCode>() {
 
             @Override
             public InstalledCode call() throws Exception {
-                InstalledCode installedCode = runtime.addMethod(method, compResult);
+                InstalledCode installedCode = runtime.addMethod(method, compResult, graph);
                 if (Debug.isDumpEnabled()) {
                     Debug.dump(new Object[]{compResult, installedCode}, "After code installation");
                 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java	Fri Apr 12 17:22:54 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java	Fri Apr 12 17:23:14 2013 +0200
@@ -34,6 +34,7 @@
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.test.*;
 
 /**
  * Test that infopoints in {@link CompilationResult}s have correctly assigned reasons.
@@ -65,7 +66,7 @@
         }
     }
 
-    @Test
+    @LongTest
     public void lineInfopoints() {
         final Method method = getMethod("testMethod");
         final StructuredGraph graph = parseDebug(method);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Fri Apr 12 17:22:54 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Fri Apr 12 17:23:14 2013 +0200
@@ -36,6 +36,7 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
+import com.oracle.graal.test.*;
 
 @SuppressWarnings("unused")
 public class InliningTest extends GraalCompilerTest {
@@ -63,7 +64,7 @@
         assertInlined(getGraph("invokeMethodOnFinalClassSnippet", false));
     }
 
-    @Test
+    @LongTest
     public void testStaticBindableInliningIP() {
         assertManyMethodInfopoints(assertInlined(getGraph("invokeConstructorSnippet", true)));
         assertManyMethodInfopoints(assertInlined(getGraph("invokeFinalMethodSnippet", true)));
@@ -99,7 +100,7 @@
         assertNotInlined(getGraph("invokeOverriddenInterfaceMethodSnippet", false));
     }
 
-    @Test
+    @LongTest
     public void testClassHierarchyAnalysisIP() {
         assertManyMethodInfopoints(assertInlined(getGraph("invokeLeafClassMethodSnippet", true)));
         assertManyMethodInfopoints(assertInlined(getGraph("invokeConcreteMethodSnippet", true)));
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java	Fri Apr 12 17:22:54 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java	Fri Apr 12 17:23:14 2013 +0200
@@ -22,65 +22,77 @@
  */
 package com.oracle.graal.hotspot.test;
 
+import static com.oracle.graal.api.meta.MetaUtil.*;
+import static java.lang.reflect.Modifier.*;
+
 import java.lang.reflect.*;
 
+import org.junit.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.*;
 
 public class InstalledCodeExecuteHelperTest extends GraalCompilerTest {
 
-    private static final int ITERATIONS = 100000000;
+    private static final int ITERATIONS = 100000;
+    private final MetaAccessProvider metaAccessProvider;
+    Object[] argsToBind;
 
-    // TODO this is not a test, move it somewhere else
-    // CheckStyle: stop system..print check
-    public void test1() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException {
-
-        final Method benchrMethod = InstalledCodeExecuteHelperTest.class.getMethod("bench", long.class, long.class);
-        final ResolvedJavaMethod benchJavaMethod = Graal.getRequiredCapability(GraalCodeCacheProvider.class).lookupJavaMethod(benchrMethod);
-        HotSpotInstalledCode benchCode = (HotSpotInstalledCode) getCode(benchJavaMethod, parse(benchrMethod));
+    public InstalledCodeExecuteHelperTest() {
+        this.metaAccessProvider = Graal.getRequiredCapability(MetaAccessProvider.class);
+    }
 
-        final Method wrapperMethod = InstalledCodeExecuteHelperTest.class.getMethod("executeWrapper", long.class, long.class, Object.class, Object.class, Object.class);
-        final ResolvedJavaMethod wrapperJavaMethod = Graal.getRequiredCapability(GraalCodeCacheProvider.class).lookupJavaMethod(wrapperMethod);
-        HotSpotInstalledCode wrapperCode = (HotSpotInstalledCode) getCode(wrapperJavaMethod, parse(wrapperMethod));
+    @Test
+    public void test1() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException {
+        final Method fooMethod = InstalledCodeExecuteHelperTest.class.getMethod("foo", Object.class, Object.class, Object.class);
+        final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod);
+        final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod));
 
-        final Method fooMethod = InstalledCodeExecuteHelperTest.class.getMethod("foo", Object.class, Object.class, Object.class);
-        final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) Graal.getRequiredCapability(GraalCodeCacheProvider.class).lookupJavaMethod(fooMethod);
-        HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod));
+        argsToBind = new Object[]{fooCode};
 
-        System.out.println(wrapperCode.executeVarargs(fooCode.getnmethod(), fooJavaMethod.getMetaspaceMethod(), null, null, null));
+        final Method benchmarkMethod = InstalledCodeExecuteHelperTest.class.getMethod("benchmark", HotSpotInstalledCode.class);
+        final ResolvedJavaMethod benchmarkJavaMethod = metaAccessProvider.lookupJavaMethod(benchmarkMethod);
+        final HotSpotInstalledCode installedBenchmarkCode = (HotSpotInstalledCode) getCode(benchmarkJavaMethod, parse(benchmarkMethod));
 
-        long nmethod = fooCode.getnmethod();
-        long metaspacemethod = fooJavaMethod.getMetaspaceMethod();
+        Assert.assertEquals(Integer.valueOf(42), benchmark(fooCode));
 
-        System.out.println("Without replaced InstalledCode.execute:" + bench(nmethod, metaspacemethod));
-
-        System.out.println("WITH replaced InstalledCode.execute:" + benchCode.executeVarargs(nmethod, metaspacemethod));
+        Assert.assertEquals(Integer.valueOf(42), installedBenchmarkCode.executeVarargs(argsToBind[0]));
 
     }
 
-    // CheckStyle: resume system..print check
-
-    public static Long bench(long nmethod, long metaspacemethod) throws InvalidInstalledCodeException {
-        long start = System.currentTimeMillis();
-
-        for (int i = 0; i < ITERATIONS; i++) {
-            HotSpotInstalledCode.executeHelper(nmethod, metaspacemethod, null, null, null);
+    public static Integer benchmark(HotSpotInstalledCode code) throws InvalidInstalledCodeException {
+        int val = 0;
+        for (int j = 0; j < 100; j++) {
+            for (int i = 0; i < ITERATIONS; i++) {
+                val = (Integer) code.execute(null, null, null);
+            }
         }
-
-        long end = System.currentTimeMillis();
-        return (end - start);
+        return val;
     }
 
-    public static Object foo(@SuppressWarnings("unused") Object a1, @SuppressWarnings("unused") Object a2, @SuppressWarnings("unused") Object a3) {
+    public static Integer foo(@SuppressWarnings("unused") Object a1, @SuppressWarnings("unused") Object a2, @SuppressWarnings("unused") Object a3) {
         return 42;
     }
 
-    public static Object executeWrapper(long nmethod, long metaspaceMethod, Object arg1, Object arg2, Object arg3) throws InvalidInstalledCodeException {
-        return HotSpotInstalledCode.executeHelper(nmethod, metaspaceMethod, arg1, arg2, arg3);
+    @Override
+    protected StructuredGraph parse(Method m) {
+        StructuredGraph graph = super.parse(m);
+        if (argsToBind != null) {
+            Object receiver = isStatic(m.getModifiers()) ? null : this;
+            Object[] args = argsWithReceiver(receiver, argsToBind);
+            JavaType[] parameterTypes = signatureToTypes(runtime.lookupJavaMethod(m));
+            assert parameterTypes.length == args.length;
+            for (int i = 0; i < argsToBind.length; i++) {
+                LocalNode local = graph.getLocal(i);
+                Constant c = Constant.forBoxed(parameterTypes[i].getKind(), argsToBind[i]);
+                ConstantNode replacement = ConstantNode.forConstant(c, runtime, graph);
+                local.replaceAtUsages(replacement);
+            }
+        }
+        return graph;
     }
-
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Fri Apr 12 17:22:54 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Fri Apr 12 17:23:14 2013 +0200
@@ -33,6 +33,7 @@
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.internal.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -167,7 +168,7 @@
                 }
             }
 
-            installMethod(result);
+            installMethod(result, null);
         } catch (BailoutException bailout) {
             Debug.metric("Bailouts").increment();
             if (GraalOptions.ExitVMOnBailout) {
@@ -197,12 +198,12 @@
                         MetaUtil.format("%H::%n(%p)", method), isOSR ? "@ " + entryBCI + " " : "", method.getCodeSize()));
     }
 
-    private void installMethod(final CompilationResult compResult) {
+    private void installMethod(final CompilationResult compResult, final Graph graph) {
         Debug.scope("CodeInstall", new Object[]{new DebugDumpScope(String.valueOf(id), true), graalRuntime.getRuntime(), method}, new Runnable() {
 
             @Override
             public void run() {
-                HotSpotInstalledCode installedCode = graalRuntime.getRuntime().installMethod(method, entryBCI, compResult);
+                HotSpotInstalledCode installedCode = graalRuntime.getRuntime().installMethod(method, graph, entryBCI, compResult);
                 if (Debug.isDumpEnabled()) {
                     Debug.dump(new Object[]{compResult, installedCode}, "After code installation");
                 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Fri Apr 12 17:22:54 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Fri Apr 12 17:23:14 2013 +0200
@@ -37,6 +37,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.internal.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.debug.*;
 import com.oracle.graal.hotspot.meta.*;
@@ -205,9 +206,22 @@
             t.start();
         }
 
-        if (GraalOptions.BenchmarkDynamicCounters) {
-            System.setErr(new PrintStream(new BenchmarkCountersOutputStream(System.err, " starting =====", " PASSED in ", "\n")));
-            System.setOut(new PrintStream(new BenchmarkCountersOutputStream(System.out, "Iteration ~ (~s) begins: ", "Iteration ~ (~s) ends:   ", "\n")));
+        if (GraalOptions.BenchmarkDynamicCounters != null) {
+            String[] arguments = GraalOptions.BenchmarkDynamicCounters.split(",");
+            if (arguments.length == 0 || (arguments.length % 3) != 0) {
+                throw new GraalInternalError("invalid arguments to BenchmarkDynamicCounters: (err|out),start,end,(err|out),start,end,... (~ matches multiple digits)");
+            }
+            for (int i = 0; i < arguments.length; i += 3) {
+                if (arguments[i].equals("err")) {
+                    System.setErr(new PrintStream(new BenchmarkCountersOutputStream(System.err, arguments[i + 1], arguments[i + 2])));
+                } else if (arguments[i].equals("out")) {
+                    System.setOut(new PrintStream(new BenchmarkCountersOutputStream(System.out, arguments[i + 1], arguments[i + 2])));
+                } else {
+                    throw new GraalInternalError("invalid arguments to BenchmarkDynamicCounters: err|out");
+                }
+                // dacapo: "err, starting =====, PASSED in "
+                // specjvm2008: "out,Iteration ~ (~s) begins: ,Iteration ~ (~s) ends:   "
+            }
             DynamicCounterNode.excludedClassPrefix = "Lcom/oracle/graal/";
             DynamicCounterNode.enabled = true;
         }
@@ -222,8 +236,8 @@
         private long startTime;
         private boolean waitingForEnd;
 
-        private BenchmarkCountersOutputStream(PrintStream delegate, String... patterns) {
-            super(delegate, patterns);
+        private BenchmarkCountersOutputStream(PrintStream delegate, String start, String end) {
+            super(delegate, new String[]{start, end, "\n"});
         }
 
         @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java	Fri Apr 12 17:22:54 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java	Fri Apr 12 17:23:14 2013 +0200
@@ -26,6 +26,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
 
 /**
@@ -39,12 +40,13 @@
 
     private final HotSpotResolvedJavaMethod method;
     private final boolean isDefault;
-    private final long nmethod; // This field is set by the runtime upon code installation.
+    private final Graph graph;
+    long nmethod;
     long start;
 
-    public HotSpotInstalledCode(HotSpotResolvedJavaMethod method, boolean isDefault) {
-        this.nmethod = 0;
+    public HotSpotInstalledCode(HotSpotResolvedJavaMethod method, Graph graph, boolean isDefault) {
         this.method = method;
+        this.graph = graph;
         this.isDefault = isDefault;
     }
 
@@ -52,10 +54,14 @@
         return isDefault;
     }
 
-    public long getnmethod() {
+    public long getMethodAddress() {
         return nmethod;
     }
 
+    public Graph getGraph() {
+        return graph;
+    }
+
     @Override
     public ResolvedJavaMethod getMethod() {
         return method;
@@ -114,9 +120,4 @@
     public byte[] getCode() {
         return HotSpotGraalRuntime.getInstance().getCompilerToVM().getCode(nmethod);
     }
-
-    @SuppressWarnings("unused")
-    public static Object executeHelper(long nmethod, long metaspaceMethod, Object arg1, Object arg2, Object arg3) throws InvalidInstalledCodeException {
-        return HotSpotGraalRuntime.getInstance().getCompilerToVM().executeCompiledMethod(arg1, arg2, arg3, nmethod);
-    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Apr 12 17:22:54 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Apr 12 17:23:14 2013 +0200
@@ -766,16 +766,21 @@
         return graalRuntime.getCompilerToVM().getJavaField(reflectionField);
     }
 
-    public HotSpotInstalledCode installMethod(HotSpotResolvedJavaMethod method, int entryBCI, CompilationResult compResult) {
-        HotSpotInstalledCode installedCode = new HotSpotInstalledCode(method, true);
+    public HotSpotInstalledCode installMethod(HotSpotResolvedJavaMethod method, Graph graph, int entryBCI, CompilationResult compResult) {
+        HotSpotInstalledCode installedCode = new HotSpotInstalledCode(method, graph, true);
         graalRuntime.getCompilerToVM().installCode(new HotSpotCompilationResult(method, entryBCI, compResult), installedCode, method.getSpeculationLog());
         return installedCode;
     }
 
     @Override
     public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) {
+        return addMethod(method, compResult, null);
+    }
+
+    @Override
+    public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, Graph graph) {
         HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method;
-        HotSpotInstalledCode code = new HotSpotInstalledCode(hotspotMethod, false);
+        HotSpotInstalledCode code = new HotSpotInstalledCode(hotspotMethod, graph, false);
         CodeInstallResult result = graalRuntime.getCompilerToVM().installCode(new HotSpotCompilationResult(hotspotMethod, -1, compResult), code, null);
         if (result != CodeInstallResult.OK) {
             return null;
@@ -894,7 +899,7 @@
 
     public String disassemble(InstalledCode code) {
         if (code.isValid()) {
-            long nmethod = ((HotSpotInstalledCode) code).getnmethod();
+            long nmethod = ((HotSpotInstalledCode) code).getMethodAddress();
             return graalRuntime.getCompilerToVM().disassembleNMethod(nmethod);
         }
         return null;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotInstalledCodeExecuteNode.java	Fri Apr 12 17:22:54 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotInstalledCodeExecuteNode.java	Fri Apr 12 17:23:14 2013 +0200
@@ -24,22 +24,24 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.word.*;
+import com.oracle.graal.phases.common.*;
 
 public class HotSpotInstalledCodeExecuteNode extends AbstractCallNode implements Lowerable {
 
-    @Input private final ValueNode targetAddress;
-    @Input private final ValueNode metaspaceObject;
+    @Input private final ValueNode code;
     private final Class[] signature;
 
-    public HotSpotInstalledCodeExecuteNode(Kind kind, ValueNode targetAddress, ValueNode metaspaceObject, Class[] signature, ValueNode arg1, ValueNode arg2, ValueNode arg3) {
+    public HotSpotInstalledCodeExecuteNode(Kind kind, Class[] signature, ValueNode code, ValueNode arg1, ValueNode arg2, ValueNode arg3) {
         super(StampFactory.forKind(kind), new ValueNode[]{arg1, arg2, arg3});
-        this.targetAddress = targetAddress;
-        this.metaspaceObject = metaspaceObject;
+        this.code = code;
         this.signature = signature;
     }
 
@@ -50,30 +52,57 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        replaceWithInvoke(tool);
+        if (code.isConstant() && code.asConstant().asObject() instanceof HotSpotInstalledCode) {
+            HotSpotInstalledCode hsCode = (HotSpotInstalledCode) code.asConstant().asObject();
+            InvokeNode invoke = replaceWithInvoke(tool.getRuntime());
+            StructuredGraph graph = (StructuredGraph) hsCode.getGraph();
+            if (graph != null) {
+                InliningUtil.inline(invoke, (StructuredGraph) hsCode.getGraph(), false);
+            }
+        } else {
+            replaceWithInvoke(tool.getRuntime());
+        }
     }
 
-    private InvokeNode replaceWithInvoke(LoweringTool tool) {
-        InvokeNode invoke = createInvoke(tool);
-        ((StructuredGraph) graph()).replaceFixedWithFixed(this, invoke);
-        return invoke;
-    }
-
-    protected InvokeNode createInvoke(LoweringTool tool) {
+    protected InvokeNode replaceWithInvoke(MetaAccessProvider tool) {
         ResolvedJavaMethod method = null;
+        ResolvedJavaField methodField = null;
+        ResolvedJavaField metaspaceMethodField = null;
+        ResolvedJavaField nmethodField = null;
         try {
-            method = tool.getRuntime().lookupJavaMethod(HotSpotInstalledCodeExecuteNode.class.getMethod("placeholder", Object.class, Object.class, Object.class));
-        } catch (NoSuchMethodException | SecurityException e) {
-            throw new IllegalStateException();
+            method = tool.lookupJavaMethod(HotSpotInstalledCodeExecuteNode.class.getMethod("placeholder", Object.class, Object.class, Object.class));
+            methodField = tool.lookupJavaField(HotSpotInstalledCode.class.getDeclaredField("method"));
+            nmethodField = tool.lookupJavaField(HotSpotInstalledCode.class.getDeclaredField("nmethod"));
+            metaspaceMethodField = tool.lookupJavaField(HotSpotResolvedJavaMethod.class.getDeclaredField("metaspaceMethod"));
+        } catch (NoSuchMethodException | SecurityException | NoSuchFieldException e) {
+            throw new IllegalStateException(e);
         }
         ResolvedJavaType[] signatureTypes = new ResolvedJavaType[signature.length];
         for (int i = 0; i < signature.length; i++) {
-            signatureTypes[i] = tool.getRuntime().lookupJavaType(signature[i]);
+            signatureTypes[i] = tool.lookupJavaType(signature[i]);
         }
-        HotSpotIndirectCallTargetNode callTarget = graph().add(
-                        new HotSpotIndirectCallTargetNode(metaspaceObject, targetAddress, arguments, stamp(), signatureTypes, method, CallingConvention.Type.JavaCall));
-        InvokeNode invoke = graph().add(new InvokeNode(callTarget, 0));
+        final int verifiedEntryPointOffset = HotSpotSnippetUtils.verifiedEntryPointOffset();
+
+        StructuredGraph g = (StructuredGraph) graph();
+
+        LoadFieldNode loadnmethod = g.add(new LoadFieldNode(code, nmethodField));
+        UnsafeLoadNode load = g.add(new UnsafeLoadNode(loadnmethod, verifiedEntryPointOffset, ConstantNode.forLong(0, graph()), HotSpotGraalRuntime.getInstance().getTarget().wordKind));
+
+        LoadFieldNode loadMethod = g.add(new LoadFieldNode(code, methodField));
+        LoadFieldNode loadmetaspaceMethod = g.add(new LoadFieldNode(loadMethod, metaspaceMethodField));
+
+        HotSpotIndirectCallTargetNode callTarget = g.add(new HotSpotIndirectCallTargetNode(loadmetaspaceMethod, load, arguments, stamp(), signatureTypes, method, CallingConvention.Type.JavaCall));
+
+        InvokeNode invoke = g.add(new InvokeNode(callTarget, 0));
+
         invoke.setStateAfter(stateAfter());
+        g.replaceFixedWithFixed(this, invoke);
+
+        g.addBeforeFixed(invoke, loadmetaspaceMethod);
+        g.addBeforeFixed(loadmetaspaceMethod, loadMethod);
+        g.addBeforeFixed(invoke, load);
+        g.addBeforeFixed(load, loadnmethod);
+
         return invoke;
     }
 
@@ -82,6 +111,6 @@
     }
 
     @NodeIntrinsic
-    public static native <T> T call(@ConstantNodeParameter Kind kind, Word targetAddress, long metaspaceObject, @ConstantNodeParameter Class[] signature, Object arg1, Object arg2, Object arg3);
+    public static native <T> T call(@ConstantNodeParameter Kind kind, @ConstantNodeParameter Class[] signature, Object code, Object arg1, Object arg2, Object arg3);
 
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotInstalledCodeSubstitutions.java	Fri Apr 12 17:22:54 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotInstalledCodeSubstitutions.java	Fri Apr 12 17:23:14 2013 +0200
@@ -27,20 +27,18 @@
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.replacements.Snippet.Fold;
-import com.oracle.graal.word.*;
 
 @ClassSubstitution(HotSpotInstalledCode.class)
 public class HotSpotInstalledCodeSubstitutions {
 
-    @MethodSubstitution
-    public static Object executeHelper(long nmethod, long metaspaceMethod, final Object arg1, final Object arg2, final Object arg3) {
-        final int verifiedEntryPointOffset = HotSpotSnippetUtils.verifiedEntryPointOffset();
-        final Word callTarget = Word.unsigned(nmethod).readWord(verifiedEntryPointOffset);
-        return HotSpotInstalledCodeExecuteNode.call(Kind.Object, callTarget, metaspaceMethod, getSignature(), arg1, arg2, arg3);
+    @MethodSubstitution(isStatic = false)
+    public static Object execute(HotSpotInstalledCode code, final Object arg1, final Object arg2, final Object arg3) {
+        return HotSpotInstalledCodeExecuteNode.call(Kind.Object, getSignature(), code, arg1, arg2, arg3);
     }
 
     @Fold
     private static Class[] getSignature() {
         return new Class[]{Object.class, Object.class, Object.class};
     }
+
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java	Fri Apr 12 17:22:54 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java	Fri Apr 12 17:23:14 2013 +0200
@@ -121,6 +121,9 @@
 
     @Override
     public void lower(LoweringTool tool) {
+        if (!enabled) {
+            throw new GraalInternalError("counter nodes shouldn't exist when not enabled");
+        }
         StructuredGraph graph = (StructuredGraph) graph();
         if (excludedClassPrefix == null || !graph.method().getDeclaringClass().getName().startsWith(excludedClassPrefix)) {
             int index = addContext ? getIndex(name + " @ " + MetaUtil.format("%h.%n", ((StructuredGraph) graph()).method())) : getIndex(name);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraalCodeCacheProvider.java	Fri Apr 12 17:22:54 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraalCodeCacheProvider.java	Fri Apr 12 17:23:14 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.nodes.spi;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 
 /**
@@ -30,5 +31,17 @@
  */
 public interface GraalCodeCacheProvider extends CodeCacheProvider {
 
+    /**
+     * Adds the given compilation result as an implementation of the given method without making it
+     * the default implementation. The graph might be inlined later on.
+     * 
+     * @param method a method to which the executable code is begin added
+     * @param compResult the compilation result to be added
+     * @param graph the graph that represents the method
+     * @return a reference to the compiled and ready-to-run code or null if the code installation
+     *         failed
+     */
+    InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, Graph graph);
+
     void lower(Node n, LoweringTool tool);
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Fri Apr 12 17:22:54 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Fri Apr 12 17:23:14 2013 +0200
@@ -251,7 +251,6 @@
             final HashSet<Node> duplicatedNodes = buildDuplicatedNodeSet(fixedNodes, stateAfter);
             mergeAfter.clearEnds();
             expandDuplicated(duplicatedNodes, mergeAfter);
-            retargetDependencies(duplicatedNodes, anchor);
 
             List<EndNode> endSnapshot = merge.forwardEnds().snapshot();
             List<PhiNode> phiSnapshot = merge.phis().snapshot();
@@ -526,29 +525,6 @@
         }
 
         /**
-         * Moves all depdendencies that point outside the duplicated area to the supplied value
-         * anchor node.
-         * 
-         * @param duplicatedNodes The set of duplicated nodes.
-         * @param anchor The node that will be the new target for all dependencies that point
-         *            outside the duplicated set of nodes.
-         */
-        private static void retargetDependencies(HashSet<Node> duplicatedNodes, ValueAnchorNode anchor) {
-            for (Node node : duplicatedNodes) {
-                if (node instanceof ValueNode) {
-                    NodeInputList<ValueNode> dependencies = ((ValueNode) node).dependencies();
-                    for (int i = 0; i < dependencies.size(); i++) {
-                        Node dependency = dependencies.get(i);
-                        if (dependency != null && !duplicatedNodes.contains(dependency)) {
-                            Debug.log("retargeting dependency %s to %s on %s", dependency, anchor, node);
-                            dependencies.set(i, anchor);
-                        }
-                    }
-                }
-            }
-        }
-
-        /**
          * Checks if the given node has usages that are not within the given set of nodes.
          * 
          * @param node The node whose usages are checked.
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Fri Apr 12 17:22:54 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Fri Apr 12 17:23:14 2013 +0200
@@ -128,7 +128,7 @@
     public static String  MethodFilter                       = null;
     public static boolean DumpOnError                        = ____;
     public static boolean GenericDynamicCounters             = ____;
-    public static boolean BenchmarkDynamicCounters           = ____;
+    public static String  BenchmarkDynamicCounters           = null;
 
     // Ideal graph visualizer output settings
     public static boolean PrintBinaryGraphs                  = true;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Fri Apr 12 17:22:54 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Fri Apr 12 17:23:14 2013 +0200
@@ -816,6 +816,8 @@
                 buf.append("<null> ").append(name);
             } else if (value == UNUSED_PARAMETER) {
                 buf.append("<unused> ").append(name);
+            } else if (value == CONSTANT_PARAMETER) {
+                buf.append("<constant> ").append(name);
             } else if (value instanceof LocalNode) {
                 LocalNode local = (LocalNode) value;
                 buf.append(local.kind().getJavaName()).append(' ').append(name);
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java	Fri Apr 12 17:22:54 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java	Fri Apr 12 17:23:14 2013 +0200
@@ -30,7 +30,6 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.debug.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
@@ -123,14 +122,6 @@
                 }
             });
         }
-
-        if (DynamicCounterNode.enabled && readElimination) {
-            for (Node node : graph.getNodes()) {
-                if (node instanceof LoadFieldNode) {
-                    DynamicCounterNode.addCounterBefore("load non-elim", 1, false, (FixedNode) node);
-                }
-            }
-        }
     }
 
     private static boolean matches(StructuredGraph graph, String filter) {
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Fri Apr 12 17:22:54 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Fri Apr 12 17:23:14 2013 +0200
@@ -162,7 +162,6 @@
                         state.killReadCache(store.field());
 
                         if (cachedValue == store.value()) {
-                            effects.addCounterBefore("store elim", 1, false, lastFixedNode.next());
                             effects.deleteFixedNode(store);
                             changed = true;
                         } else {
@@ -173,7 +172,6 @@
                         ValueNode cachedValue = state.getReadCache(load.object(), load.field());
                         if (cachedValue != null) {
                             METRIC_LOADFIELD_ELIMINATED.increment();
-                            effects.addCounterBefore("load elim", 1, false, lastFixedNode.next());
                             effects.replaceAtUsages(load, cachedValue);
                             state.addScalarAlias(load, cachedValue);
                             changed = true;
--- a/src/share/vm/prims/unsafe.cpp	Fri Apr 12 17:22:54 2013 +0200
+++ b/src/share/vm/prims/unsafe.cpp	Fri Apr 12 17:23:14 2013 +0200
@@ -116,7 +116,9 @@
 inline void* index_oop_from_field_offset_long(oop p, jlong field_offset) {
   jlong byte_offset = field_offset_to_byte_offset(field_offset);
   // Don't allow unsafe to be used to read or write the header word of oops
-  assert(p == NULL || field_offset >= oopDesc::header_size(), "offset must be outside of header");
+  // unless running GRAAL which wants to read the misc word for example when
+  // interpreting computeHashCode().
+  assert(p == NULL || field_offset >= oopDesc::header_size() || GRAAL, "offset must be outside of header");
 #ifdef ASSERT
   if (p != NULL) {
     assert(byte_offset >= 0 && byte_offset <= (jlong)MAX_OBJECT_SIZE, "sane offset");