changeset 10057:e90e48dae0ab

Merge.
author Christian Haeubl <haeubl@ssw.jku.at>
date Fri, 14 Jun 2013 19:13:32 +0200
parents a323a9e20f9d 10fbede11db0
children 440661cc7908
files graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CullFrameStatesPhase.java
diffstat 26 files changed, 141 insertions(+), 181 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java	Fri Jun 14 19:13:32 2013 +0200
@@ -53,7 +53,7 @@
      * @return {@code true} if the value is a power of two; {@code false} otherwise
      */
     public static boolean isPowerOf2(int val) {
-        return val != 0 && (val & val - 1) == 0;
+        return val > 0 && (val & val - 1) == 0;
     }
 
     /**
@@ -63,7 +63,7 @@
      * @return {@code true} if the value is a power of two; {@code false} otherwise
      */
     public static boolean isPowerOf2(long val) {
-        return val != 0 && (val & val - 1) == 0;
+        return val > 0 && (val & val - 1) == 0;
     }
 
     /**
@@ -74,7 +74,7 @@
      * @return the log base 2 of the value
      */
     public static int log2(int val) {
-        assert val > 0 && isPowerOf2(val);
+        assert val > 0;
         return 31 - Integer.numberOfLeadingZeros(val);
     }
 
@@ -86,7 +86,7 @@
      * @return the log base 2 of the value
      */
     public static int log2(long val) {
-        assert val > 0 && isPowerOf2(val);
+        assert val > 0;
         return 63 - Long.numberOfLeadingZeros(val);
     }
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Fri Jun 14 19:13:32 2013 +0200
@@ -310,7 +310,6 @@
         HighTierContext context = new HighTierContext(runtime(), assumptions, replacements);
         new InliningPhase(runtime(), null, replacements, assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph);
         new PartialEscapePhase(false, new CanonicalizerPhase(true)).apply(graph, context);
-        new CullFrameStatesPhase().apply(graph);
     }
 
     private void compareGraphs(final String snippet, final String referenceSnippet) {
@@ -335,7 +334,6 @@
                 canonicalizer.apply(graph, context);
                 new PartialEscapePhase(false, canonicalizer).apply(graph, context);
 
-                new CullFrameStatesPhase().apply(graph);
                 new DeadCodeEliminationPhase().apply(graph);
                 canonicalizer.apply(graph, context);
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java	Fri Jun 14 19:13:32 2013 +0200
@@ -96,6 +96,17 @@
         testZeroReturn("divStamp2");
     }
 
+    public static int distinctMask(int a, int b) {
+        int x = a & 0xaaaa;
+        int y = (b & 0x5555) | 0x1;
+        return x == y ? 1 : 0;
+    }
+
+    @Test
+    public void testDistinctMask() {
+        testZeroReturn("distinctMask");
+    }
+
     private void testZeroReturn(String methodName) {
         StructuredGraph graph = parse(methodName);
         new CanonicalizerPhase.Instance(runtime(), new Assumptions(false), true).apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java	Fri Jun 14 19:13:32 2013 +0200
@@ -168,7 +168,9 @@
                 canonicalizer.apply(graph, context);
                 new PartialEscapePhase(false, canonicalizer).apply(graph, context);
 
-                new CullFrameStatesPhase().apply(graph);
+                for (MergeNode merge : graph.getNodes(MergeNode.class)) {
+                    merge.setStateAfter(null);
+                }
                 new DeadCodeEliminationPhase().apply(graph);
                 canonicalizer.apply(graph, context);
                 return graph;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Fri Jun 14 19:13:32 2013 +0200
@@ -60,10 +60,6 @@
         }
         appendPhase(new RemoveValueProxyPhase());
 
-        if (CullFrameStates.getValue()) {
-            appendPhase(new CullFrameStatesPhase());
-        }
-
         if (OptCanonicalizer.getValue()) {
             appendPhase(canonicalizer);
         }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeFlood.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeFlood.java	Fri Jun 14 19:13:32 2013 +0200
@@ -43,7 +43,7 @@
         }
     }
 
-    public void addAll(Iterable<Node> nodes) {
+    public void addAll(Iterable<? extends Node> nodes) {
         for (Node node : nodes) {
             this.add(node);
         }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Fri Jun 14 19:13:32 2013 +0200
@@ -48,7 +48,7 @@
     @Override
     protected InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) {
         HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method;
-        HotSpotNmethod installedCode = new HotSpotNmethod(hsMethod, true);
+        HotSpotNmethod installedCode = new HotSpotNmethod(hsMethod, true, null);
         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/meta/HotSpotNmethod.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java	Fri Jun 14 19:13:32 2013 +0200
@@ -28,6 +28,7 @@
 
 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
@@ -44,16 +45,22 @@
 
     private final HotSpotResolvedJavaMethod method;
     private final boolean isDefault;
+    private final Graph graph;
 
-    public HotSpotNmethod(HotSpotResolvedJavaMethod method, boolean isDefault) {
+    public HotSpotNmethod(HotSpotResolvedJavaMethod method, boolean isDefault, Graph graph) {
         this.method = method;
         this.isDefault = isDefault;
+        this.graph = graph;
     }
 
     public boolean isDefault() {
         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	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Jun 14 19:13:32 2013 +0200
@@ -927,15 +927,20 @@
     }
 
     public HotSpotInstalledCode installMethod(HotSpotResolvedJavaMethod method, int entryBCI, CompilationResult compResult) {
-        HotSpotInstalledCode installedCode = new HotSpotNmethod(method, true);
+        HotSpotInstalledCode installedCode = new HotSpotNmethod(method, true, null);
         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, false);
+        HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, false, graph);
         CodeInstallResult result = graalRuntime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(hotspotMethod, -1, compResult), code, null);
         if (result != CodeInstallResult.OK) {
             return null;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotNmethodExecuteNode.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/HotSpotNmethodExecuteNode.java	Fri Jun 14 19:13:32 2013 +0200
@@ -33,6 +33,7 @@
 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 {
 
@@ -52,7 +53,16 @@
 
     @Override
     public void lower(LoweringTool tool, LoweringType loweringType) {
-        replaceWithInvoke(tool.getRuntime());
+        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, graph, false);
+            }
+        } else {
+            replaceWithInvoke(tool.getRuntime());
+        }
     }
 
     protected InvokeNode replaceWithInvoke(MetaAccessProvider tool) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Fri Jun 14 19:13:32 2013 +0200
@@ -89,7 +89,7 @@
         }
         // Don't throw away the code as we assume this is a rare event
         // that will periodically occur.
-        DeoptimizeNode.deopt(InvalidateReprofile, OptimizedTypeCheckViolated);
+        DeoptimizeNode.deopt(DeoptimizationAction.None, OptimizedTypeCheckViolated);
         return falseValue;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java	Fri Jun 14 19:13:32 2013 +0200
@@ -95,7 +95,7 @@
         if (condition() instanceof LogicConstantNode) {
             LogicConstantNode c = (LogicConstantNode) condition();
             if (c.getValue() != negated) {
-                return getGuard().asNode();
+                return graph().start();
             }
         }
         return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java	Fri Jun 14 19:13:32 2013 +0200
@@ -32,10 +32,9 @@
  * A node that changes the type of its input, usually narrowing it. For example, a PI node refines
  * the type of a receiver during type-guarded inlining to be the type tested by the guard.
  */
-public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, Node.IterableNodeType, GuardingNode {
+public class PiNode extends FloatingGuardedNode implements LIRLowerable, Virtualizable, Node.IterableNodeType, GuardingNode, Canonicalizable {
 
     @Input private ValueNode object;
-    @Input private FixedNode anchor;
 
     public ValueNode object() {
         return object;
@@ -46,10 +45,9 @@
         this.object = object;
     }
 
-    public PiNode(ValueNode object, Stamp stamp, FixedNode anchor) {
-        super(stamp);
+    public PiNode(ValueNode object, Stamp stamp, GuardingNode anchor) {
+        super(stamp, anchor);
         this.object = object;
-        this.anchor = anchor;
     }
 
     @Override
@@ -71,4 +69,15 @@
             tool.replaceWithVirtual(state.getVirtualObject());
         }
     }
+
+    @Override
+    public ValueNode canonical(CanonicalizerTool tool) {
+        if (getGuard() == graph().start()) {
+            inferStamp();
+            if (stamp().equals(object().stamp())) {
+                return object();
+            }
+        }
+        return this;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java	Fri Jun 14 19:13:32 2013 +0200
@@ -64,7 +64,7 @@
         return graph.unique(new IndexedLocationNode(identity, kind, displacement, index, indexScaling));
     }
 
-    private IndexedLocationNode(LocationIdentity identity, Kind kind, long displacement, ValueNode index, int indexScaling) {
+    public IndexedLocationNode(LocationIdentity identity, Kind kind, long displacement, ValueNode index, int indexScaling) {
         super(StampFactory.extension());
         assert kind != Kind.Illegal && kind != Kind.Void;
         this.valueKind = kind;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeArrayCastNode.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeArrayCastNode.java	Fri Jun 14 19:13:32 2013 +0200
@@ -42,11 +42,15 @@
         this.length = length;
     }
 
-    public UnsafeArrayCastNode(ValueNode object, ValueNode length, Stamp stamp, ValueNode anchor) {
+    public UnsafeArrayCastNode(ValueNode object, ValueNode length, Stamp stamp, GuardingNode anchor) {
         super(object, stamp, anchor);
         this.length = length;
     }
 
+    private UnsafeArrayCastNode(ValueNode object, ValueNode length, Stamp stamp, ValueNode anchor) {
+        this(object, length, stamp, (GuardingNode) anchor);
+    }
+
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         if (!(object() instanceof ArrayLengthProvider) || length() != ((ArrayLengthProvider) object()).length()) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Fri Jun 14 19:13:32 2013 +0200
@@ -36,8 +36,12 @@
         super(object, stamp);
     }
 
+    public UnsafeCastNode(ValueNode object, Stamp stamp, GuardingNode anchor) {
+        super(object, stamp, anchor);
+    }
+
     public UnsafeCastNode(ValueNode object, Stamp stamp, ValueNode anchor) {
-        super(object, stamp, (FixedNode) anchor);
+        this(object, stamp, (GuardingNode) anchor);
     }
 
     public UnsafeCastNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) {
@@ -100,7 +104,7 @@
     public static native <T> T unsafeCast(Object object, @ConstantNodeParameter Stamp stamp);
 
     @NodeIntrinsic
-    public static native <T> T unsafeCast(Object object, @ConstantNodeParameter Stamp stamp, ValueNode anchor);
+    public static native <T> T unsafeCast(Object object, @ConstantNodeParameter Stamp stamp, GuardingNode anchor);
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraalCodeCacheProvider.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraalCodeCacheProvider.java	Fri Jun 14 19:13:32 2013 +0200
@@ -37,10 +37,11 @@
      * 
      * @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);
+    InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, Graph graph);
 
     void lower(Node n, LoweringTool tool);
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java	Fri Jun 14 19:13:32 2013 +0200
@@ -129,7 +129,15 @@
     @Override
     public boolean alwaysDistinct(Stamp otherStamp) {
         IntegerStamp other = (IntegerStamp) otherStamp;
-        return lowerBound > other.upperBound || upperBound < other.lowerBound;
+        if (lowerBound > other.upperBound || upperBound < other.lowerBound) {
+            return true;
+        } else {
+            if ((mask & other.mask) == 0) {
+                // zero is the only common value if the masks don't overlap => check for non-zero
+                return lowerBound > 0 || upperBound < 0 || other.lowerBound > 0 || other.upperBound < 0;
+            }
+            return false;
+        }
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Fri Jun 14 19:13:32 2013 +0200
@@ -101,6 +101,10 @@
     private static final long LONG_SIGN_BIT = 0x8000000000000000L;
 
     private static Stamp stampForMask(Kind kind, long mask) {
+        return stampForMask(kind, mask, 0);
+    }
+
+    private static Stamp stampForMask(Kind kind, long mask, long alwaysSetBits) {
         long lowerBound;
         long upperBound;
         if (kind == Kind.Int && (mask & INTEGER_SIGN_BIT) != 0) {
@@ -112,7 +116,7 @@
             lowerBound = Long.MIN_VALUE;
             upperBound = mask ^ LONG_SIGN_BIT;
         } else {
-            lowerBound = 0;
+            lowerBound = alwaysSetBits;
             upperBound = mask;
         }
         return StampFactory.forInteger(kind, lowerBound, upperBound, mask);
@@ -127,7 +131,11 @@
     public static Stamp or(IntegerStamp stamp1, IntegerStamp stamp2) {
         Kind kind = stamp1.kind();
         long mask = stamp1.mask() | stamp2.mask();
-        return stampForMask(kind, mask);
+        if (stamp1.lowerBound() >= 0 && stamp2.lowerBound() >= 0) {
+            return stampForMask(kind, mask, stamp1.lowerBound() | stamp2.lowerBound());
+        } else {
+            return stampForMask(kind, mask);
+        }
     }
 
     public static Stamp xor(IntegerStamp stamp1, IntegerStamp stamp2) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CullFrameStatesPhase.java	Fri Jun 14 19:12:56 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2012, 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.phases.common;
-
-import java.util.*;
-
-import com.oracle.graal.debug.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.util.*;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.graph.*;
-
-/**
- * This phase culls unused FrameStates from the graph. It does a post order iteration over the
- * graph, and
- */
-public class CullFrameStatesPhase extends Phase {
-
-    private static final DebugMetric metricFrameStatesCulled = Debug.metric("FrameStatesCulled");
-    private static final DebugMetric metricNodesRemoved = Debug.metric("NodesRemoved");
-    private static final DebugMetric metricMergesTraversed = Debug.metric("MergesTraversed");
-
-    @Override
-    protected void run(StructuredGraph graph) {
-        int initialNodes = graph.getNodeCount();
-        new CullFrameStates(graph.start(), new State(null)).apply();
-        metricNodesRemoved.add(initialNodes - graph.getNodeCount());
-    }
-
-    public static class State implements MergeableState<State> {
-
-        private FrameState lastFrameState;
-
-        public State(FrameState lastFrameState) {
-            this.lastFrameState = lastFrameState;
-        }
-
-        @Override
-        public boolean merge(MergeNode merge, List<State> withStates) {
-            FrameState stateAfter = merge.stateAfter();
-            if (merge instanceof LoopBeginNode) {
-                if (stateAfter != null) {
-                    lastFrameState = stateAfter;
-                }
-                return true;
-            }
-            metricMergesTraversed.increment();
-            if (stateAfter != null) {
-                for (State other : withStates) {
-                    if (other.lastFrameState != lastFrameState) {
-                        lastFrameState = stateAfter;
-                        return true;
-                    }
-                }
-                metricFrameStatesCulled.increment();
-                merge.setStateAfter(null);
-                if (stateAfter.usages().isEmpty()) {
-                    GraphUtil.killWithUnusedFloatingInputs(stateAfter);
-                }
-            }
-            return true;
-        }
-
-        @Override
-        public void loopBegin(LoopBeginNode loopBegin) {
-        }
-
-        @Override
-        public void loopEnds(LoopBeginNode loopBegin, List<State> loopEndStates) {
-        }
-
-        @Override
-        public void afterSplit(AbstractBeginNode node) {
-        }
-
-        @Override
-        public State clone() {
-            return new State(lastFrameState);
-        }
-    }
-
-    public static class CullFrameStates extends PostOrderNodeIterator<State> {
-
-        public CullFrameStates(FixedNode start, State initialState) {
-            super(start, initialState);
-        }
-
-        @Override
-        protected void node(FixedNode node) {
-            if (node instanceof StateSplit) {
-                FrameState stateAfter = ((StateSplit) node).stateAfter();
-                if (stateAfter != null) {
-                    state.lastFrameState = stateAfter;
-                }
-            }
-        }
-    }
-
-}
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Fri Jun 14 19:13:32 2013 +0200
@@ -91,6 +91,16 @@
         this.optimisticOpts = optimisticOpts;
     }
 
+    public InliningPhase(MetaAccessProvider runtime, Replacements replacements, Assumptions assumptions, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts, InliningPolicy policy) {
+        this.runtime = runtime;
+        this.replacements = replacements;
+        this.compilationAssumptions = assumptions;
+        this.cache = cache;
+        this.plan = plan;
+        this.inliningPolicy = policy;
+        this.optimisticOpts = optimisticOpts;
+    }
+
     public void setCustomCanonicalizer(CustomCanonicalizer customCanonicalizer) {
         this.customCanonicalizer = customCanonicalizer;
     }
@@ -312,9 +322,6 @@
             new CanonicalizerPhase.Instance(runtime, assumptions, !AOTCompilation.getValue()).apply(newGraph);
         }
 
-        if (CullFrameStates.getValue()) {
-            new CullFrameStatesPhase().apply(newGraph);
-        }
         if (CacheGraphs.getValue() && cache != null) {
             cache.put(newGraph.copy(), hasMatureProfilingInfo);
         }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Fri Jun 14 19:13:32 2013 +0200
@@ -491,15 +491,13 @@
             LoadHubNode receiverHub = graph.add(new LoadHubNode(receiver, typeHub.kind()));
             CompareNode typeCheck = CompareNode.createCompareNode(Condition.EQ, receiverHub, typeHub);
             FixedGuardNode guard = graph.add(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile));
-            ValueAnchorNode anchor = graph.add(new ValueAnchorNode());
             assert invoke.predecessor() != null;
 
-            ValueNode anchoredReceiver = createAnchoredReceiver(graph, anchor, type, receiver, true);
+            ValueNode anchoredReceiver = createAnchoredReceiver(graph, guard, type, receiver, true);
             invoke.callTarget().replaceFirstInput(receiver, anchoredReceiver);
 
             graph.addBeforeFixed(invoke.asNode(), receiverHub);
             graph.addBeforeFixed(invoke.asNode(), guard);
-            graph.addBeforeFixed(invoke.asNode(), anchor);
         }
 
         @Override
@@ -1227,9 +1225,13 @@
         }
     }
 
-    private static PiNode createAnchoredReceiver(StructuredGraph graph, FixedNode anchor, ResolvedJavaType commonType, ValueNode receiver, boolean exact) {
+    private static PiNode createAnchoredReceiver(StructuredGraph graph, GuardingNode anchor, ResolvedJavaType commonType, ValueNode receiver, boolean exact) {
+        return createAnchoredReceiver(graph, anchor, receiver, exact ? StampFactory.exactNonNull(commonType) : StampFactory.declaredNonNull(commonType));
+    }
+
+    private static PiNode createAnchoredReceiver(StructuredGraph graph, GuardingNode anchor, ValueNode receiver, Stamp stamp) {
         // to avoid that floating reads on receiver fields float above the type check
-        return graph.unique(new PiNode(receiver, exact ? StampFactory.exactNonNull(commonType) : StampFactory.declaredNonNull(commonType), anchor));
+        return graph.unique(new PiNode(receiver, stamp, anchor));
     }
 
     // TODO (chaeubl): cleanup this method
@@ -1298,9 +1300,17 @@
 
         FrameState stateAfter = invoke.stateAfter();
         assert stateAfter == null || stateAfter.isAlive();
-        GuardingNode receiverNullCheckNode = null;
         if (receiverNullCheck) {
-            receiverNullCheckNode = receiverNullCheck(invoke);
+            GuardingNode receiverNullCheckNode = receiverNullCheck(invoke);
+            if (receiverNullCheckNode != null) {
+                ValueNode receiver = invoke.callTarget().arguments().get(0);
+                Stamp piStamp = receiver.stamp();
+                if (piStamp instanceof ObjectStamp) {
+                    piStamp = piStamp.join(StampFactory.objectNonNull());
+                }
+                ValueNode anchoredReceiver = createAnchoredReceiver(graph, receiverNullCheckNode, receiver, piStamp);
+                invoke.callTarget().replaceFirstInput(receiver, anchoredReceiver);
+            }
         }
 
         IdentityHashMap<Node, Node> replacements = new IdentityHashMap<>();
@@ -1313,18 +1323,7 @@
             if (node == entryPointNode || node == entryPointNode.stateAfter()) {
                 // Do nothing.
             } else if (node instanceof LocalNode) {
-                int localIndex = ((LocalNode) node).index();
-                ValueNode parameter = parameters.get(localIndex);
-                if (receiverNullCheckNode != null && localIndex == 0) {
-                    Stamp piStamp = parameter.stamp();
-                    if (piStamp instanceof ObjectStamp) {
-                        piStamp = piStamp.join(StampFactory.objectNonNull());
-                    }
-                    PiNode piReceiver = graph.add(new PiNode(parameter, piStamp));
-                    piReceiver.setGuard(receiverNullCheckNode);
-                    parameter = piReceiver;
-                }
-                replacements.put(node, parameter);
+                replacements.put(node, parameters.get(((LocalNode) node).index()));
             } else {
                 nodes.add(node);
                 if (node instanceof ReturnNode) {
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Fri Jun 14 19:13:32 2013 +0200
@@ -198,8 +198,6 @@
     @Option(help = "")
     public static final OptionValue<Boolean> ConditionalElimination = new OptionValue<>(true);
     @Option(help = "")
-    public static final OptionValue<Boolean> CullFrameStates = new OptionValue<>(false);
-    @Option(help = "")
     public static final OptionValue<Boolean> UseProfilingInformation = new OptionValue<>(true);
     @Option(help = "")
            static final OptionValue<Boolean> RemoveNeverExecutedCode = new OptionValue<>(true);
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java	Fri Jun 14 19:13:32 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.virtual.phases.ea;
 
+import static com.oracle.graal.phases.GraalOptions.*;
+
 import java.util.*;
 
 import com.oracle.graal.debug.*;
@@ -82,7 +84,9 @@
             @Override
             protected Void processBlock(Block block, Void currentState) {
                 apply(blockEffects.get(block), block);
-                Debug.dump(graph, "after processing block %s", block);
+                if (TraceEscapeAnalysis.getValue()) {
+                    Debug.dump(graph, "after processing block %s", block);
+                }
                 return currentState;
             }
 
@@ -109,7 +113,7 @@
 
     @Override
     protected BlockT processBlock(Block block, BlockT state) {
-        VirtualUtil.trace("\nBlock: %s (", block);
+        VirtualUtil.trace("\nBlock: %s, preds: %s, succ: %s (", block, block.getPredecessors(), block.getSuccessors());
 
         GraphEffectList effects = blockEffects.get(block);
         FixedWithNextNode lastFixedNode = null;
@@ -130,6 +134,7 @@
         assert blockEffects.get(merge).isEmpty();
         MergeProcessor processor = createMergeProcessor(merge);
         processor.merge(states);
+        processor.commitEnds(states);
         blockEffects.get(merge).addAll(processor.mergeEffects);
         blockEffects.get(merge).addAll(processor.afterMergeEffects);
         return processor.newState;
@@ -138,7 +143,7 @@
     @Override
     protected final List<BlockT> processLoop(Loop loop, BlockT initialState) {
         BlockT loopEntryState = initialState;
-        BlockT lastMergedState = initialState;
+        BlockT lastMergedState = cloneState(initialState);
         MergeProcessor mergeProcessor = createMergeProcessor(loop.header);
         for (int iteration = 0; iteration < 10; iteration++) {
             LoopInfo<BlockT> info = ReentrantBlockIterator.processLoop(this, loop, cloneState(lastMergedState));
@@ -154,6 +159,8 @@
             Debug.log("%s", lastMergedState);
 
             if (mergeProcessor.newState.equivalentTo(lastMergedState)) {
+                mergeProcessor.commitEnds(states);
+
                 blockEffects.get(loop.header).insertAll(mergeProcessor.mergeEffects, 0);
                 loopMergeEffects.put(loop, mergeProcessor.afterMergeEffects);
 
@@ -198,6 +205,12 @@
         protected void merge(List<BlockT> states) {
             newState = getInitialState();
             newState.meetAliases(states);
+            mergeEffects.clear();
+            afterMergeEffects.clear();
+        }
+
+        @SuppressWarnings("unused")
+        protected void commitEnds(List<BlockT> states) {
         }
     }
 }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Fri Jun 14 19:12:56 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Fri Jun 14 19:13:32 2013 +0200
@@ -349,9 +349,7 @@
                         locksMatch &= obj.locksEqual(startObj);
                     }
 
-                    assert virtual < states.size() || locksMatch : "mismatching lock counts at " + merge;
-
-                    if (virtual < states.size()) {
+                    if (virtual < states.size() || !locksMatch) {
                         if (singleValue == null) {
                             PhiNode materializedValuePhi = getCachedPhi(object, Kind.Object);
                             mergeEffects.addFloatingNode(materializedValuePhi, "materializedPhi");
--- a/mxtool/mx.py	Fri Jun 14 19:12:56 2013 +0200
+++ b/mxtool/mx.py	Fri Jun 14 19:13:32 2013 +0200
@@ -2652,6 +2652,7 @@
         shutil.rmtree(join(p.dir, 'nbproject'), ignore_errors=True)
         rm(join(p.dir, '.classpath'))
         rm(join(p.dir, '.project'))
+        rm(join(p.dir, '.factorypath'))
         rm(join(p.dir, 'build.xml'))
         rm(join(p.dir, 'eclipse-build.xml'))
         try: