changeset 10034:6cbb7fb49de5

Merge
author Christos Kotselidis <christos.kotselidis@oracle.com>
date Thu, 13 Jun 2013 12:52:39 +0200
parents 9d6f0c55cda7 (current diff) 4ebe31e19892 (diff)
children 055430b5abb9
files
diffstat 25 files changed, 218 insertions(+), 175 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/BasicSPARCTest.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/BasicSPARCTest.java	Thu Jun 13 12:52:39 2013 +0200
@@ -26,7 +26,6 @@
 
 import org.junit.Test;
 
-
 public class BasicSPARCTest extends SPARCTestBase {
 
     @Test
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Thu Jun 13 12:52:39 2013 +0200
@@ -429,7 +429,6 @@
                 }
                 long start = System.currentTimeMillis();
                 PhasePlan phasePlan = new PhasePlan();
-                final StructuredGraph graphCopy = graph.copy();
                 GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
                 phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
                 editPhasePlan(method, graph, phasePlan);
@@ -443,7 +442,7 @@
 
                     @Override
                     public InstalledCode call() throws Exception {
-                        InstalledCode code = addMethod(method, compResult, graphCopy);
+                        InstalledCode code = addMethod(method, compResult);
                         if (Debug.isDumpEnabled()) {
                             Debug.dump(new Object[]{compResult, code}, "After code installation");
                         }
@@ -460,8 +459,8 @@
         return installedCode;
     }
 
-    protected InstalledCode addMethod(final ResolvedJavaMethod method, final CompilationResult compResult, final StructuredGraph graph) {
-        return runtime.addMethod(method, compResult, graph);
+    protected InstalledCode addMethod(final ResolvedJavaMethod method, final CompilationResult compResult) {
+        return runtime.addMethod(method, compResult);
     }
 
     /**
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Thu Jun 13 12:52:39 2013 +0200
@@ -141,7 +141,7 @@
             new VerifyUsageWithEquals(runtime, Register.class).apply(graph);
         }
 
-        CanonicalizerPhase canonicalizer = new CanonicalizerPhase(OptCanonicalizeReads.getValue());
+        CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue());
         HighTierContext highTierContext = new HighTierContext(runtime, assumptions, replacements);
 
         if (OptCanonicalizer.getValue()) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Thu Jun 13 12:52:39 2013 +0200
@@ -34,10 +34,10 @@
 public class HighTier extends PhaseSuite<HighTierContext> {
 
     public HighTier() {
-        CanonicalizerPhase canonicalizer = new CanonicalizerPhase(OptCanonicalizeReads.getValue());
+        CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue());
 
         if (FullUnroll.getValue()) {
-            addPhase(new LoopFullUnrollPhase(OptCanonicalizeReads.getValue()));
+            addPhase(new LoopFullUnrollPhase(!AOTCompilation.getValue()));
         }
 
         if (OptTailDuplication.getValue()) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java	Thu Jun 13 12:52:39 2013 +0200
@@ -32,7 +32,7 @@
 public class MidTier extends PhaseSuite<MidTierContext> {
 
     public MidTier() {
-        CanonicalizerPhase canonicalizer = new CanonicalizerPhase(OptCanonicalizeReads.getValue());
+        CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue());
 
         if (OptPushThroughPi.getValue()) {
             addPhase(new PushThroughPiPhase());
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Thu Jun 13 12:52:39 2013 +0200
@@ -35,7 +35,6 @@
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.hotspot.phases.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
@@ -55,6 +54,7 @@
 public class AheadOfTimeCompilationTest extends GraalCompilerTest {
 
     public static final Object STATICFINALOBJECT = new Object();
+    public static final String STATICFINALSTRING = "test string";
 
     public static Object getStaticFinalObject() {
         return AheadOfTimeCompilationTest.STATICFINALOBJECT;
@@ -63,15 +63,19 @@
     @Test
     public void testStaticFinalObjectAOT() {
         StructuredGraph result = compile("getStaticFinalObject", true);
-        assert result.getNodes().filter(ConstantNode.class).count() == 1;
-        assert result.getNodes(FloatingReadNode.class).count() == 2;
+        assertEquals(1, result.getNodes().filter(ConstantNode.class).count());
+        assertEquals(runtime.getTarget().wordKind, result.getNodes().filter(ConstantNode.class).first().kind());
+        assertEquals(2, result.getNodes(FloatingReadNode.class).count());
+        assertEquals(0, result.getNodes(ReadNode.class).count());
     }
 
     @Test
     public void testStaticFinalObject() {
         StructuredGraph result = compile("getStaticFinalObject", false);
-        assert result.getNodes().filter(ConstantNode.class).count() == 1;
-        assert result.getNodes(FloatingReadNode.class).count() == 0;
+        assertEquals(1, result.getNodes().filter(ConstantNode.class).count());
+        assertEquals(Kind.Object, result.getNodes().filter(ConstantNode.class).first().kind());
+        assertEquals(0, result.getNodes(FloatingReadNode.class).count());
+        assertEquals(0, result.getNodes(ReadNode.class).count());
     }
 
     public static Class getClassObject() {
@@ -83,12 +87,12 @@
         StructuredGraph result = compile("getClassObject", true);
 
         NodeIterable<ConstantNode> filter = result.getNodes().filter(ConstantNode.class);
-        assert filter.count() == 1;
+        assertEquals(1, filter.count());
         HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) runtime.lookupJavaType(AheadOfTimeCompilationTest.class);
-        assert filter.first().asConstant().equals(type.klass());
+        assertEquals(type.klass(), filter.first().asConstant());
 
-        assert result.getNodes(FloatingReadNode.class).count() == 1;
-        assert result.getNodes(ReadNode.class).count() == 0;
+        assertEquals(1, result.getNodes(FloatingReadNode.class).count());
+        assertEquals(0, result.getNodes(ReadNode.class).count());
     }
 
     @Test
@@ -96,37 +100,89 @@
         StructuredGraph result = compile("getClassObject", false);
 
         NodeIterable<ConstantNode> filter = result.getNodes().filter(ConstantNode.class);
-        assert filter.count() == 1;
+        assertEquals(1, filter.count());
+        Object mirror = filter.first().asConstant().asObject();
+        assertEquals(Class.class, mirror.getClass());
+        assertEquals(AheadOfTimeCompilationTest.class, mirror);
+
+        assertEquals(0, result.getNodes(FloatingReadNode.class).count());
+        assertEquals(0, result.getNodes(ReadNode.class).count());
+    }
+
+    public static Class getPrimitiveClassObject() {
+        return int.class;
+    }
+
+    @Test
+    public void testPrimitiveClassObjectAOT() {
+        StructuredGraph result = compile("getPrimitiveClassObject", true);
+        NodeIterable<ConstantNode> filter = result.getNodes().filter(ConstantNode.class);
+        assertEquals(1, filter.count());
+        assertEquals(runtime.getTarget().wordKind, filter.first().kind());
+
+        assertEquals(2, result.getNodes(FloatingReadNode.class).count());
+        assertEquals(0, result.getNodes(ReadNode.class).count());
+    }
+
+    @Test
+    public void testPrimitiveClassObject() {
+        StructuredGraph result = compile("getPrimitiveClassObject", false);
+        NodeIterable<ConstantNode> filter = result.getNodes().filter(ConstantNode.class);
+        assertEquals(1, filter.count());
         Object mirror = filter.first().asConstant().asObject();
-        assert mirror.getClass().equals(Class.class);
-        assert mirror.equals(AheadOfTimeCompilationTest.class);
+        assertEquals(Class.class, mirror.getClass());
+        assertEquals(Integer.TYPE, mirror);
+
+        assertEquals(0, result.getNodes(FloatingReadNode.class).count());
+        assertEquals(0, result.getNodes(ReadNode.class).count());
+    }
+
+    public static String getStringObject() {
+        return AheadOfTimeCompilationTest.STATICFINALSTRING;
+    }
+
+    @Test
+    public void testStringObjectAOT() {
+        // embedded strings are fine
+        testStringObjectCommon(true);
+    }
 
-        assert result.getNodes(FloatingReadNode.class).count() == 0;
-        assert result.getNodes(ReadNode.class).count() == 0;
+    @Test
+    public void testStringObject() {
+        testStringObjectCommon(false);
+    }
+
+    private void testStringObjectCommon(boolean compileAOT) {
+        StructuredGraph result = compile("getStringObject", compileAOT);
+
+        NodeIterable<ConstantNode> filter = result.getNodes().filter(ConstantNode.class);
+        assertEquals(1, filter.count());
+        Object mirror = filter.first().asConstant().asObject();
+        assertEquals(String.class, mirror.getClass());
+        assertEquals("test string", mirror);
+
+        assertEquals(0, result.getNodes(FloatingReadNode.class).count());
+        assertEquals(0, result.getNodes(ReadNode.class).count());
     }
 
     private StructuredGraph compile(String test, boolean compileAOT) {
         StructuredGraph graph = parse(test);
         ResolvedJavaMethod method = graph.method();
 
-        boolean originalSetting = OptCanonicalizeReads.getValue();
-        OptCanonicalizeReads.setValue(!compileAOT);
+        boolean originalSetting = AOTCompilation.getValue();
+        AOTCompilation.setValue(compileAOT);
         PhasePlan phasePlan = new PhasePlan();
-        final StructuredGraph graphCopy = graph.copy();
         GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
         phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
         editPhasePlan(method, graph, phasePlan);
         CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false);
         // create suites everytime, as we modify options for the compiler
         final Suites suitesLocal = Graal.getRequiredCapability(SuitesProvider.class).createSuites();
-        if (compileAOT) {
-            suitesLocal.getHighTier().addPhase(new LoadJavaMirrorWithKlassPhase());
-        }
         final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, runtime, replacements, backend, runtime().getTarget(), null, phasePlan, OptimisticOptimizations.ALL,
                         new SpeculationLog(), suitesLocal);
-        addMethod(method, compResult, graphCopy);
+        addMethod(method, compResult);
 
-        OptCanonicalizeReads.setValue(originalSetting);
+        AOTCompilation.setValue(originalSetting);
 
         return graph;
     }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Thu Jun 13 12:52:39 2013 +0200
@@ -46,9 +46,9 @@
 public class HotSpotCryptoSubstitutionTest extends GraalCompilerTest {
 
     @Override
-    protected InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, StructuredGraph graph) {
+    protected InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) {
         HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method;
-        HotSpotNmethod installedCode = new HotSpotNmethod(hsMethod, graph, true);
+        HotSpotNmethod installedCode = new HotSpotNmethod(hsMethod, true);
         HotSpotCompiledNmethod compiledNmethod = new HotSpotCompiledNmethod(hsMethod, StructuredGraph.INVOCATION_ENTRY_BCI, compResult);
         CodeInstallResult result = graalRuntime().getCompilerToVM().installCode(compiledNmethod, installedCode, null);
         Assert.assertEquals("Error installing method " + method + ": " + result, result, CodeInstallResult.OK);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Thu Jun 13 12:52:39 2013 +0200
@@ -215,7 +215,7 @@
 
             @Override
             public void run() {
-                HotSpotInstalledCode installedCode = graalRuntime.getRuntime().installMethod(method, graph, entryBCI, compResult);
+                HotSpotInstalledCode installedCode = graalRuntime.getRuntime().installMethod(method, 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/meta/HotSpotNmethod.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java	Thu Jun 13 12:52:39 2013 +0200
@@ -28,7 +28,6 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
 
 /**
  * Implementation of {@link InstalledCode} for code installed as an nmethod. The nmethod stores a
@@ -45,11 +44,9 @@
 
     private final HotSpotResolvedJavaMethod method;
     private final boolean isDefault;
-    private final Graph graph;
 
-    public HotSpotNmethod(HotSpotResolvedJavaMethod method, Graph graph, boolean isDefault) {
+    public HotSpotNmethod(HotSpotResolvedJavaMethod method, boolean isDefault) {
         this.method = method;
-        this.graph = graph;
         this.isDefault = isDefault;
     }
 
@@ -57,10 +54,6 @@
         return isDefault;
     }
 
-    public Graph getGraph() {
-        return graph;
-    }
-
     @Override
     public ResolvedJavaMethod getMethod() {
         return method;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Thu Jun 13 12:52:39 2013 +0200
@@ -922,21 +922,16 @@
         return graalRuntime.getCompilerToVM().getJavaField(reflectionField);
     }
 
-    public HotSpotInstalledCode installMethod(HotSpotResolvedJavaMethod method, Graph graph, int entryBCI, CompilationResult compResult) {
-        HotSpotInstalledCode installedCode = new HotSpotNmethod(method, graph, true);
+    public HotSpotInstalledCode installMethod(HotSpotResolvedJavaMethod method, int entryBCI, CompilationResult compResult) {
+        HotSpotInstalledCode installedCode = new HotSpotNmethod(method, true);
         graalRuntime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(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 HotSpotNmethod(hotspotMethod, graph, false);
+        HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, false);
         CodeInstallResult result = graalRuntime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(hotspotMethod, -1, compResult), code, null);
         if (result != CodeInstallResult.OK) {
             return null;
@@ -1073,6 +1068,14 @@
     public Suites createSuites() {
         Suites ret = Suites.createDefaultSuites();
 
+        if (AOTCompilation.getValue()) {
+            // lowering introduces class constants, therefore it must be after lowering
+            ret.getHighTier().addPhase(new LoadJavaMirrorWithKlassPhase());
+            if (VerifyPhases.getValue()) {
+                ret.getHighTier().addPhase(new AheadOfTimeVerifcationPhase());
+            }
+        }
+
         ret.getMidTier().addPhase(new WriteBarrierAdditionPhase());
         if (VerifyPhases.getValue()) {
             ret.getMidTier().addPhase(new WriteBarrierVerificationPhase());
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotNmethodExecuteNode.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotNmethodExecuteNode.java	Thu Jun 13 12:52:39 2013 +0200
@@ -33,7 +33,6 @@
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.phases.common.*;
 
 public class HotSpotNmethodExecuteNode extends AbstractCallNode implements Lowerable {
 
@@ -53,16 +52,7 @@
 
     @Override
     public void lower(LoweringTool tool, LoweringType loweringType) {
-        if (code.isConstant() && code.asConstant().asObject() instanceof HotSpotNmethod) {
-            HotSpotNmethod nmethod = (HotSpotNmethod) code.asConstant().asObject();
-            InvokeNode invoke = replaceWithInvoke(tool.getRuntime());
-            StructuredGraph graph = (StructuredGraph) nmethod.getGraph();
-            if (graph != null) {
-                InliningUtil.inline(invoke, (StructuredGraph) nmethod.getGraph(), false);
-            }
-        } else {
-            replaceWithInvoke(tool.getRuntime());
-        }
+        replaceWithInvoke(tool.getRuntime());
     }
 
     protected InvokeNode replaceWithInvoke(MetaAccessProvider tool) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerifcationPhase.java	Thu Jun 13 12:52:39 2013 +0200
@@ -0,0 +1,50 @@
+/*
+ * 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.phases;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.phases.*;
+
+public class AheadOfTimeVerifcationPhase extends VerifyPhase {
+
+    @Override
+    protected boolean verify(StructuredGraph graph) {
+        for (ConstantNode node : graph.getNodes().filter(ConstantNode.class)) {
+            assert !isOop(node) || isNullReference(node) || isString(node) : "embedded oop: " + node;
+        }
+        return true;
+    }
+
+    private static boolean isOop(ConstantNode node) {
+        return node.kind() == Kind.Object;
+    }
+
+    private static boolean isNullReference(ConstantNode node) {
+        return isOop(node) && node.asConstant().asObject() == null;
+    }
+
+    private static boolean isString(ConstantNode node) {
+        return isOop(node) && node.asConstant().asObject() instanceof String;
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java	Thu Jun 13 12:52:39 2013 +0200
@@ -27,7 +27,6 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.HeapAccess.WriteBarrierType;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.*;
@@ -41,22 +40,18 @@
             Constant constant = node.asConstant();
             if (constant.getKind() == Kind.Object && constant.asObject() instanceof Class<?>) {
                 ResolvedJavaType type = context.getRuntime().lookupJavaType((Class<?>) constant.asObject());
-                if (type instanceof HotSpotResolvedObjectType) {
-                    HotSpotRuntime runtime = (HotSpotRuntime) context.getRuntime();
+                assert type instanceof HotSpotResolvedObjectType;
 
-                    Constant klass = ((HotSpotResolvedObjectType) type).klass();
-                    ConstantNode klassNode = ConstantNode.forConstant(klass, runtime, graph);
+                HotSpotRuntime runtime = (HotSpotRuntime) context.getRuntime();
 
-                    Stamp stamp = StampFactory.exactNonNull(runtime.lookupJavaType(Class.class));
-                    LocationNode location = graph.unique(ConstantLocationNode.create(FINAL_LOCATION, stamp.kind(), runtime.config.classMirrorOffset, graph));
-                    ReadNode readNode = graph.add(new ReadNode(klassNode, location, stamp, WriteBarrierType.NONE, false));
+                Constant klass = ((HotSpotResolvedObjectType) type).klass();
+                ConstantNode klassNode = ConstantNode.forConstant(klass, runtime, graph);
 
-                    FixedNode afterStart = graph.start().next();
-                    graph.start().setNext(readNode);
-                    readNode.setNext(afterStart);
+                Stamp stamp = StampFactory.exactNonNull(runtime.lookupJavaType(Class.class));
+                LocationNode location = graph.unique(ConstantLocationNode.create(FINAL_LOCATION, stamp.kind(), runtime.config.classMirrorOffset, graph));
+                FloatingReadNode freadNode = graph.add(new FloatingReadNode(klassNode, location, null, stamp));
 
-                    graph.replaceFloating(node, readNode);
-                }
+                graph.replaceFloating(node, freadNode);
             }
         }
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Thu Jun 13 12:52:39 2013 +0200
@@ -39,6 +39,7 @@
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.phases.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.Snippet.VarargsParameter;
@@ -58,8 +59,10 @@
 public class InstanceOfSnippets implements Snippets {
 
     /**
-     * A test against a set of hints derived from a profile with 100% precise coverage of seen
-     * types. This snippet deoptimizes on any path that contradicts the profile.
+     * A test against a set of hints derived from a profile with very close to 100% precise coverage
+     * of seen types. This snippet deoptimizes on hint miss paths.
+     * 
+     * @see GraalOptions#InstanceOfFullCoverageSpeculationThreshold
      */
     @Snippet
     public static Object instanceofWithProfile(Object object, @VarargsParameter Word[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue, Object falseValue,
@@ -67,6 +70,8 @@
         if (probability(NOT_FREQUENT_PROBABILITY, checkNull && object == null)) {
             isNull.inc();
             if (!nullSeen) {
+                // In this case, the execution is contradicting the profile
+                // so invalidating and re-profiling is justified.
                 DeoptimizeNode.deopt(InvalidateReprofile, OptimizedTypeCheckViolated);
             }
             return falseValue;
@@ -82,6 +87,8 @@
                 return positive ? trueValue : falseValue;
             }
         }
+        // Don't throw away the code as we assume this is a rare event
+        // that will periodically occur.
         DeoptimizeNode.deopt(InvalidateReprofile, OptimizedTypeCheckViolated);
         return falseValue;
     }
@@ -189,7 +196,7 @@
                 ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, instanceOf.graph());
 
                 Arguments args;
-                if (hintInfo.hintHitProbability == 1.0D) {
+                if (hintInfo.hintHitProbability >= InstanceOfFullCoverageSpeculationThreshold.getValue()) {
                     Hints hints = createHints(hintInfo, runtime, false, hub.graph());
                     args = new Arguments(instanceofWithProfile);
                     args.add("object", object);
@@ -215,7 +222,7 @@
                 args.add("trueValue", replacer.trueValue);
                 args.add("falseValue", replacer.falseValue);
                 args.addConst("checkNull", !object.stamp().nonNull());
-                if (hintInfo.hintHitProbability == 1.0D) {
+                if (hintInfo.hintHitProbability >= InstanceOfFullCoverageSpeculationThreshold.getValue()) {
                     args.addConst("nullSeen", hintInfo.profile.getNullSeen() != TriState.FALSE);
                 }
                 return args;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java	Thu Jun 13 12:52:39 2013 +0200
@@ -24,6 +24,7 @@
 
 import static com.oracle.graal.api.meta.LocationIdentity.*;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
@@ -54,6 +55,13 @@
         return (stamp() == StampFactory.forVoid());
     }
 
+    /**
+     * The frame state upon entry to an exception handler is such that it is a
+     * {@link BytecodeFrame#rethrowException rethrow exception} state and the stack contains exactly
+     * the exception object (per the JVM spec) to rethrow. This means that the code creating this
+     * state (i.e. the {@link LoadExceptionObjectNode}) cannot cause a deoptimization as the
+     * runtime/interpreter would not have a valid location for the exception object to be rethrown.
+     */
     @Override
     public void lower(LoweringTool tool, LoweringType loweringType) {
         if (isLowered()) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java	Thu Jun 13 12:52:39 2013 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes.java;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -29,6 +30,12 @@
 /**
  * Loads an exception object passed by the runtime from a callee to an exception handler in a
  * caller. The node is only produced when lowering an {@link ExceptionObjectNode}.
+ * <p>
+ * The frame state upon entry to an exception handler is such that it is a
+ * {@link BytecodeFrame#rethrowException rethrow exception} state and the stack contains exactly the
+ * exception object (per the JVM spec) to rethrow. This means that the code generated for this node
+ * must not cause a deoptimization as the runtime/interpreter would not have a valid location to
+ * find the exception object to be rethrown.
  */
 public class LoadExceptionObjectNode extends AbstractStateSplit implements Lowerable {
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraalCodeCacheProvider.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraalCodeCacheProvider.java	Thu Jun 13 12:52:39 2013 +0200
@@ -37,11 +37,10 @@
      * 
      * @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);
+    InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult);
 
     void lower(Node n, LoweringTool tool);
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java	Thu Jun 13 12:52:39 2013 +0200
@@ -45,6 +45,6 @@
     protected void run(StructuredGraph graph, C context) {
         int mark = graph.getMark();
         super.run(graph, context);
-        new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), OptCanonicalizeReads.getValue(), mark, customCanonicalizer).apply(graph);
+        new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), !AOTCompilation.getValue(), mark, customCanonicalizer).apply(graph);
     }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Thu Jun 13 12:52:39 2013 +0200
@@ -195,7 +195,7 @@
 
             if (OptCanonicalizer.getValue()) {
                 int markBeforeCanonicalization = callerGraph.getMark();
-                new CanonicalizerPhase.Instance(runtime, callerAssumptions, OptCanonicalizeReads.getValue(), invokeUsages, markBeforeInlining, customCanonicalizer).apply(callerGraph);
+                new CanonicalizerPhase.Instance(runtime, callerAssumptions, !AOTCompilation.getValue(), invokeUsages, markBeforeInlining, customCanonicalizer).apply(callerGraph);
 
                 // process invokes that are possibly created during canonicalization
                 for (Node newNode : callerGraph.getNewNodes(markBeforeCanonicalization)) {
@@ -280,7 +280,7 @@
                 }
 
                 if (OptCanonicalizer.getValue()) {
-                    new CanonicalizerPhase.Instance(runtime, assumptions, OptCanonicalizeReads.getValue()).apply(newGraph);
+                    new CanonicalizerPhase.Instance(runtime, assumptions, !AOTCompilation.getValue()).apply(newGraph);
                 }
 
                 return newGraph;
@@ -309,7 +309,7 @@
         new DeadCodeEliminationPhase().apply(newGraph);
 
         if (OptCanonicalizer.getValue()) {
-            new CanonicalizerPhase.Instance(runtime, assumptions, OptCanonicalizeReads.getValue()).apply(newGraph);
+            new CanonicalizerPhase.Instance(runtime, assumptions, !AOTCompilation.getValue()).apply(newGraph);
         }
 
         if (CullFrameStates.getValue()) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java	Thu Jun 13 12:52:39 2013 +0200
@@ -46,7 +46,7 @@
             if (canonicalizationRoots.isEmpty()) {
                 break;
             }
-            new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), OptCanonicalizeReads.getValue(), canonicalizationRoots, null).apply(graph);
+            new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), !AOTCompilation.getValue(), canonicalizationRoots, null).apply(graph);
             canonicalizationRoots.clear();
         }
     }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Thu Jun 13 12:52:39 2013 +0200
@@ -300,7 +300,7 @@
                     phi.setMerge(mergeAfter);
                 }
             }
-            new CanonicalizerPhase.Instance(phaseContext.getRuntime(), phaseContext.getAssumptions(), OptCanonicalizeReads.getValue(), graph.getNewNodes(startMark), null).apply(graph);
+            new CanonicalizerPhase.Instance(phaseContext.getRuntime(), phaseContext.getAssumptions(), !AOTCompilation.getValue(), graph.getNewNodes(startMark), null).apply(graph);
             Debug.dump(graph, "After tail duplication at %s", merge);
         }
 
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Thu Jun 13 12:52:39 2013 +0200
@@ -241,6 +241,10 @@
     @Option(help = "")
     public static final OptionValue<Double> MinTableSwitchDensity = new OptionValue<>(0.5);
 
+    // Ahead of time compilation
+    @Option(help = "configure compiler to emit code compatible with AOT requirements for HotSpot")
+    public static final OptionValue<Boolean> AOTCompilation = new OptionValue<>(false);
+
     // Runtime settings
     @Option(help = "")
     public static final OptionValue<Integer> StackShadowPages = new OptionValue<>(2);
@@ -257,8 +261,6 @@
     @Option(help = "")
     public static final OptionValue<Boolean> OptCanonicalizer = new OptionValue<>(true);
     @Option(help = "")
-    public static final OptionValue<Boolean> OptCanonicalizeReads = new OptionValue<>(true);
-    @Option(help = "")
      public static final OptionValue<Boolean> OptScheduleOutOfLoops = new OptionValue<>(true);
     @Option(help = "")
     public static final OptionValue<Boolean> OptEliminateGuards = new OptionValue<>(true);
@@ -330,14 +332,25 @@
     public static final OptionValue<Integer> CheckcastMaxHints = new OptionValue<>(2);
 
     /**
-     * @see #CheckcastMinHintHitProbability
+     * If the probability that an instanceof will hit one the profiled types (up to {@link #InstanceOfMaxHints})
+     * is below this value, the instanceof will be compiled without hints.
      */
     @Option(help = "")
     public static final OptionValue<Double> InstanceOfMinHintHitProbability = new OptionValue<>(0.5);
 
     /**
-     * @see #CheckcastMaxHints
+     * The maximum number of hint types that will be used when compiling an instanceof for which
+     * profiling information is available. Note that {@link #InstanceOfMinHintHitProbability}
+     * also influences whether hints are used.
      */
     @Option(help = "")
     public static final OptionValue<Integer> InstanceOfMaxHints = new OptionValue<>(2);
+
+    /**
+     * If the probability that an instanceof will hit one the profiled types (up to {@link #InstanceOfMaxHints})
+     * is above this value, the compiled instanceof will deoptimize if all hints are missed.
+     */
+    @Option(help = "")
+    public static final OptionValue<Double> InstanceOfFullCoverageSpeculationThreshold = new OptionValue<>(0.998);
+
 }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeInliningRelevanceClosure.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeInliningRelevanceClosure.java	Thu Jun 13 12:52:39 2013 +0200
@@ -24,7 +24,6 @@
 
 import java.util.*;
 
-import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
 import com.oracle.graal.nodes.util.*;
@@ -94,8 +93,7 @@
             HashMap<FixedNode, Scope> result = new HashMap<>();
 
             for (Scope scope : computeScopes()) {
-                double lowestPathProbability = computeLowestPathProbability(scope);
-                scope.minPathProbability = Math.max(EPSILON, lowestPathProbability);
+                scope.minPathProbability = Math.max(EPSILON, nodeProbabilities.get(scope.start));
                 result.put(scope.start, scope);
             }
 
@@ -128,85 +126,6 @@
             processedLoops.put(loop, result);
             return result;
         }
-
-        private double computeLowestPathProbability(Scope scope) {
-            FixedNode scopeStart = scope.start;
-            ArrayList<FixedNode> pathBeginNodes = new ArrayList<>();
-            pathBeginNodes.add(scopeStart);
-            double minPathProbability = nodeProbabilities.get(scopeStart);
-            boolean isLoopScope = scopeStart instanceof LoopBeginNode;
-
-            do {
-                Node current = pathBeginNodes.remove(pathBeginNodes.size() - 1);
-                do {
-                    if (isLoopScope && current instanceof LoopExitNode && ((LoopBeginNode) scopeStart).loopExits().contains((LoopExitNode) current)) {
-                        return minPathProbability;
-                    } else if (current instanceof LoopBeginNode && current != scopeStart) {
-                        current = getMaxProbabilityLoopExit((LoopBeginNode) current, pathBeginNodes);
-                        minPathProbability = getMinPathProbability((FixedNode) current, minPathProbability);
-                    } else if (current instanceof ControlSplitNode) {
-                        current = getMaxProbabilitySux((ControlSplitNode) current, pathBeginNodes);
-                        minPathProbability = getMinPathProbability((FixedNode) current, minPathProbability);
-                    } else {
-                        assert current.successors().count() <= 1;
-                        current = current.successors().first();
-                    }
-                } while (current != null);
-            } while (!pathBeginNodes.isEmpty());
-
-            return minPathProbability;
-        }
-
-        private double getMinPathProbability(FixedNode current, double minPathProbability) {
-            if (current != null && nodeProbabilities.get(current) < minPathProbability) {
-                return nodeProbabilities.get(current);
-            }
-            return minPathProbability;
-        }
-
-        private Node getMaxProbabilitySux(ControlSplitNode controlSplit, ArrayList<FixedNode> pathBeginNodes) {
-            Node maxSux = null;
-            double maxProbability = 0.0;
-            int pathBeginCount = pathBeginNodes.size();
-
-            for (Node sux : controlSplit.successors()) {
-                double probability = controlSplit.probability((AbstractBeginNode) sux);
-                if (probability > maxProbability) {
-                    maxProbability = probability;
-                    maxSux = sux;
-                    truncate(pathBeginNodes, pathBeginCount);
-                } else if (probability == maxProbability) {
-                    pathBeginNodes.add((FixedNode) sux);
-                }
-            }
-
-            return maxSux;
-        }
-
-        private Node getMaxProbabilityLoopExit(LoopBeginNode loopBegin, ArrayList<FixedNode> pathBeginNodes) {
-            Node maxSux = null;
-            double maxProbability = 0.0;
-            int pathBeginCount = pathBeginNodes.size();
-
-            for (LoopExitNode sux : loopBegin.loopExits()) {
-                double probability = nodeProbabilities.get(sux);
-                if (probability > maxProbability) {
-                    maxProbability = probability;
-                    maxSux = sux;
-                    truncate(pathBeginNodes, pathBeginCount);
-                } else if (probability == maxProbability) {
-                    pathBeginNodes.add(sux);
-                }
-            }
-
-            return maxSux;
-        }
-
-        private void truncate(ArrayList<FixedNode> pathBeginNodes, int pathBeginCount) {
-            for (int i = pathBeginNodes.size() - pathBeginCount; i > 0; i--) {
-                pathBeginNodes.remove(pathBeginNodes.size() - 1);
-            }
-        }
     }
 
     private static class Scope {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Wed Jun 12 11:37:45 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Thu Jun 13 12:52:39 2013 +0200
@@ -241,13 +241,13 @@
             if (value instanceof char[]) {
                 return Arrays.toString((char[]) value);
             }
-            if (value instanceof float[]) {
+            if (value instanceof short[]) {
                 return Arrays.toString((short[]) value);
             }
-            if (value instanceof float[]) {
+            if (value instanceof int[]) {
                 return Arrays.toString((int[]) value);
             }
-            if (value instanceof float[]) {
+            if (value instanceof long[]) {
                 return Arrays.toString((long[]) value);
             }
             if (value instanceof float[]) {
--- a/mx/commands.py	Wed Jun 12 11:37:45 2013 +0200
+++ b/mx/commands.py	Thu Jun 13 12:52:39 2013 +0200
@@ -1044,6 +1044,11 @@
         vm(['-G:RegisterPressure=rbx,r11,r14,xmm3,xmm11,xmm14', '-esa', '-version'])
         tasks.append(t.stop())
 
+        _vmbuild = 'product'
+        t = Task('BootstrapWithAOTConfiguration:product')
+        vm(['-G:+AOTCompilation', '-esa', '-version'])
+        tasks.append(t.stop())
+
         originalVm = _vm
         _vm = 'server' # hosted mode
         t = Task('UnitTests:hosted-product')