changeset 8664:31f1390766d9

Merge.
author Christian Humer <christian.humer@gmail.com>
date Sun, 07 Apr 2013 12:45:27 +0200
parents e2b471ba533a (current diff) d47b52b0ff68 (diff)
children 89ea104f29ac 9dfefdee8f3f
files graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsProvider.java
diffstat 23 files changed, 310 insertions(+), 101 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sat Apr 06 16:30:23 2013 +0200
+++ b/.hgignore	Sun Apr 07 12:45:27 2013 +0200
@@ -30,6 +30,7 @@
 \.dot$
 \.pyc$
 \.hprof$
+\javafilelist.txt$
 \.hprof\.txt$
 ^graal/.*/build.xml
 ^graal/.*/nbproject/
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Sat Apr 06 16:30:23 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Sun Apr 07 12:45:27 2013 +0200
@@ -60,13 +60,6 @@
     RegisterConfig lookupRegisterConfig();
 
     /**
-     * Custom area on the stack of each compiled method that the VM can use for its own purposes.
-     * 
-     * @return the size of the custom area in bytes
-     */
-    int getCustomStackAreaSize();
-
-    /**
      * Minimum size of the stack area reserved for outgoing parameters. This area is reserved in all
      * cases, even when the compiled method has no regular call instructions.
      * 
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java	Sat Apr 06 16:30:23 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java	Sun Apr 07 12:45:27 2013 +0200
@@ -57,13 +57,13 @@
      * @param profile the profiling information available for the instruction (if any)
      * @param assumptions the object in which speculations are recorded. This is null if
      *            speculations are not supported.
-     * @param minHintHitProbability if the probability that the type check will hit one the profiled
-     *            types (up to {@code maxHints}) is below this value, then {@link #types} will be
-     *            null
+     * @param minHintHitProbability if the probability that the type check will hit one of the
+     *            profiled types (up to {@code maxHints}) is below this value, then {@link #types}
+     *            will be null
      * @param maxHints the maximum length of {@link #types}
      */
     public TypeCheckHints(ResolvedJavaType type, JavaTypeProfile profile, Assumptions assumptions, double minHintHitProbability, int maxHints) {
-        if (type != null && canHaveSubtype(type)) {
+        if (type != null && !canHaveSubtype(type)) {
             types = new ResolvedJavaType[]{type};
             exact = true;
         } else {
@@ -113,9 +113,9 @@
      * Determines if a given type can have subtypes other than itself. This analysis is purely
      * static; no assumptions are made.
      * 
-     * @return true if {@code type} has no subtype(s)
+     * @return true if {@code type} can have subtypes
      */
     public static boolean canHaveSubtype(ResolvedJavaType type) {
-        return isFinal(getElementalType(type).getModifiers());
+        return !isFinal(getElementalType(type).getModifiers());
     }
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java	Sat Apr 06 16:30:23 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java	Sun Apr 07 12:45:27 2013 +0200
@@ -24,6 +24,8 @@
 
 import java.io.*;
 
+import com.oracle.graal.api.meta.ProfilingInfo.*;
+
 /**
  * This profile object represents the type profile at a specific BCI. The precision of the supplied
  * values may vary, but a runtime that provides this information should be aware that it will be
@@ -78,6 +80,7 @@
         }
     }
 
+    private final TriState nullSeen;
     private final double notRecordedProbability;
     private final ProfiledType[] ptypes;
 
@@ -94,7 +97,8 @@
         return true;
     }
 
-    public JavaTypeProfile(double notRecordedProbability, ProfiledType... ptypes) {
+    public JavaTypeProfile(TriState nullSeen, double notRecordedProbability, ProfiledType... ptypes) {
+        this.nullSeen = nullSeen;
         this.ptypes = ptypes;
         this.notRecordedProbability = notRecordedProbability;
         assert isSorted(ptypes);
@@ -111,6 +115,13 @@
     }
 
     /**
+     * Returns whether a null value was at the type check.
+     */
+    public TriState getNullSeen() {
+        return nullSeen;
+    }
+
+    /**
      * A list of types for which the runtime has recorded probability information.
      */
     public ProfiledType[] getTypes() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java	Sun Apr 07 12:45:27 2013 +0200
@@ -0,0 +1,92 @@
+/*
+ * 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.compiler.test;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.phases.common.*;
+
+public class PushNodesThroughPiTest extends GraalCompilerTest {
+
+    public static class A {
+
+        public long x = 20;
+    }
+
+    public static class B extends A {
+
+        public long y = 10;
+    }
+
+    public static long test1Snippet(A a) {
+        B b = (B) a;
+        long ret = b.x; // this can be moved before the checkcast
+        ret += b.y;
+        // the null-check should be canonicalized with the null-check of the checkcast
+        ret += b != null ? 100 : 200;
+        return ret;
+    }
+
+    @Test
+    public void test1() {
+        final String snippet = "test1Snippet";
+        Debug.scope("PushThroughPi", new DebugDumpScope(snippet), new Runnable() {
+
+            public void run() {
+                StructuredGraph graph = compileTestSnippet(snippet);
+
+                for (ReadNode rn : graph.getNodes().filter(ReadNode.class)) {
+                    Object locId = rn.location().locationIdentity();
+                    if (locId instanceof ResolvedJavaField) {
+                        ResolvedJavaField field = (ResolvedJavaField) locId;
+                        if (field.getName().equals("x")) {
+                            Assert.assertTrue(rn.object() instanceof LocalNode);
+                        } else {
+                            Assert.assertTrue(rn.object() instanceof UnsafeCastNode);
+                        }
+                    }
+                }
+
+                Assert.assertTrue(graph.getNodes().filter(IsNullNode.class).count() == 1);
+            }
+        });
+    }
+
+    private StructuredGraph compileTestSnippet(final String snippet) {
+        StructuredGraph graph = parse(snippet);
+        new LoweringPhase(null, runtime(), replacements, new Assumptions(false)).apply(graph);
+        new CanonicalizerPhase(runtime(), null).apply(graph);
+        new PushNodesThroughPi().apply(graph);
+        new CanonicalizerPhase(runtime(), null).apply(graph);
+
+        return graph;
+    }
+}
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Sat Apr 06 16:30:23 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Sun Apr 07 12:45:27 2013 +0200
@@ -179,6 +179,13 @@
 
         new LoweringPhase(target, runtime, replacements, assumptions).apply(graph);
 
+        if (GraalOptions.OptPushThroughPi) {
+            new PushNodesThroughPi().apply(graph);
+            if (GraalOptions.OptCanonicalizer) {
+                new CanonicalizerPhase(runtime, assumptions).apply(graph);
+            }
+        }
+
         if (GraalOptions.OptFloatingReads) {
             int mark = graph.getMark();
             new FloatingReadPhase().apply(graph);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Sat Apr 06 16:30:23 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Sun Apr 07 12:45:27 2013 +0200
@@ -364,12 +364,12 @@
             }
 
             totalCount += getTypesNotRecordedExecutionCount(data, position);
-            return createTypeProfile(types, counts, totalCount, entries);
+            return createTypeProfile(getNullSeen(data, position), types, counts, totalCount, entries);
         }
 
         protected abstract long getTypesNotRecordedExecutionCount(HotSpotMethodData data, int position);
 
-        private static JavaTypeProfile createTypeProfile(ResolvedJavaType[] types, long[] counts, long totalCount, int entries) {
+        private static JavaTypeProfile createTypeProfile(TriState nullSeen, ResolvedJavaType[] types, long[] counts, long totalCount, int entries) {
             if (entries <= 0 || totalCount < GraalOptions.MatureExecutionsTypeProfile) {
                 return null;
             }
@@ -387,7 +387,7 @@
 
             double notRecordedTypeProbability = entries < config.typeProfileWidth ? 0.0 : Math.min(1.0, Math.max(0.0, 1.0 - totalProbability));
             assert notRecordedTypeProbability == 0 || entries == config.typeProfileWidth;
-            return new JavaTypeProfile(notRecordedTypeProbability, ptypes);
+            return new JavaTypeProfile(nullSeen, notRecordedTypeProbability, ptypes);
         }
 
         private static int getReceiverOffset(int row) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Sat Apr 06 16:30:23 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Sun Apr 07 12:45:27 2013 +0200
@@ -478,15 +478,6 @@
         return regConfig;
     }
 
-    /**
-     * HotSpots needs an area suitable for storing a program counter for temporary use during the
-     * deoptimization process.
-     */
-    @Override
-    public int getCustomStackAreaSize() {
-        return graalRuntime.getTarget().wordSize;
-    }
-
     @Override
     public int getMinimumOutgoingSize() {
         return config.runtimeCallStackSize;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotInstalledCodeIntrinsics.java	Sat Apr 06 16:30:23 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotInstalledCodeIntrinsics.java	Sun Apr 07 12:45:27 2013 +0200
@@ -25,7 +25,6 @@
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
-import com.oracle.graal.replacements.*;
 
 @ServiceProvider(ReplacementsProvider.class)
 public class HotSpotInstalledCodeIntrinsics implements ReplacementsProvider {
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Sat Apr 06 16:30:23 2013 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Sun Apr 07 12:45:27 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.java;
 
 import static com.oracle.graal.api.code.DeoptimizationAction.*;
+import static com.oracle.graal.api.code.TypeCheckHints.*;
 import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.bytecode.Bytecodes.*;
 import static java.lang.reflect.Modifier.*;
@@ -771,12 +772,12 @@
     }
 
     private JavaTypeProfile getProfileForTypeCheck(ResolvedJavaType type) {
-        if (!optimisticOpts.useTypeCheckHints() || TypeCheckHints.canHaveSubtype(type)) {
+        if (!optimisticOpts.useTypeCheckHints() || !canHaveSubtype(type)) {
             return null;
         } else {
             ResolvedJavaType uniqueSubtype = type.findUniqueConcreteSubtype();
             if (uniqueSubtype != null) {
-                return new JavaTypeProfile(0.0D, new ProfiledType(uniqueSubtype, 1.0D));
+                return new JavaTypeProfile(profilingInfo.getNullSeen(bci()), 0.0D, new ProfiledType(uniqueSubtype, 1.0D));
             } else {
                 return profilingInfo.getTypeProfile(bci());
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java	Sat Apr 06 16:30:23 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java	Sun Apr 07 12:45:27 2013 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.nodes;
 
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -30,23 +31,23 @@
  * 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 FloatingNode implements LIRLowerable, Virtualizable {
+public class PiNode extends FloatingNode implements LIRLowerable, Virtualizable, Node.IterableNodeType {
 
     @Input private ValueNode object;
-    @Input(notDataflow = true) private final FixedNode anchor;
 
     public ValueNode object() {
         return object;
     }
 
-    public FixedNode anchor() {
-        return anchor;
+    public PiNode(ValueNode object, Stamp stamp) {
+        super(stamp);
+        this.object = object;
     }
 
-    public PiNode(ValueNode object, FixedNode anchor, Stamp stamp) {
-        super(stamp);
+    public PiNode(ValueNode object, Stamp stamp, ValueNode anchor) {
+        super(stamp, anchor);
+        assert anchor instanceof FixedNode;
         this.object = object;
-        this.anchor = anchor;
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java	Sat Apr 06 16:30:23 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java	Sun Apr 07 12:45:27 2013 +0200
@@ -29,7 +29,7 @@
 /**
  * An IsNullNode will be true if the supplied value is null, and false if it is non-null.
  */
-public final class IsNullNode extends LogicNode implements Canonicalizable, LIRLowerable, Virtualizable {
+public final class IsNullNode extends LogicNode implements Canonicalizable, LIRLowerable, Virtualizable, PiPushable {
 
     @Input private ValueNode object;
 
@@ -78,4 +78,10 @@
             tool.replaceWithValue(LogicConstantNode.contradiction(graph()));
         }
     }
+
+    @Override
+    public boolean push(PiNode parent) {
+        replaceFirstInput(parent, parent.object());
+        return true;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Sat Apr 06 16:30:23 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Sun Apr 07 12:45:27 2013 +0200
@@ -33,7 +33,7 @@
 /**
  * Reads an {@linkplain AccessNode accessed} value.
  */
-public final class ReadNode extends FloatableAccessNode implements Node.IterableNodeType, LIRLowerable, Canonicalizable {
+public final class ReadNode extends FloatableAccessNode implements Node.IterableNodeType, LIRLowerable, Canonicalizable, PiPushable {
 
     public ReadNode(ValueNode object, ValueNode location, Stamp stamp) {
         super(object, location, stamp);
@@ -98,6 +98,21 @@
         return read;
     }
 
+    @Override
+    public boolean push(PiNode parent) {
+        Object locId = location().locationIdentity();
+        if (locId instanceof ResolvedJavaField) {
+            ResolvedJavaType fieldType = ((ResolvedJavaField) locId).getDeclaringClass();
+            ResolvedJavaType beforePiType = parent.object().objectStamp().type();
+
+            if (fieldType.isAssignableFrom(beforePiType)) {
+                replaceFirstInput(parent, parent.object());
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Reads a value from memory.
      * 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Sat Apr 06 16:30:23 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Sun Apr 07 12:45:27 2013 +0200
@@ -24,29 +24,20 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
 /**
  * The {@code UnsafeCastNode} produces the same value as its input, but with a different type.
  */
-public class UnsafeCastNode extends FloatingNode implements Canonicalizable, LIRLowerable {
-
-    @Input private ValueNode object;
-
-    public ValueNode object() {
-        return object;
-    }
+public class UnsafeCastNode extends PiNode implements Canonicalizable, LIRLowerable {
 
     public UnsafeCastNode(ValueNode object, Stamp stamp) {
-        super(stamp);
-        this.object = object;
+        super(object, stamp);
     }
 
     public UnsafeCastNode(ValueNode object, Stamp stamp, ValueNode anchor) {
-        super(stamp, anchor);
-        this.object = object;
+        super(object, stamp, anchor);
     }
 
     public UnsafeCastNode(ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) {
@@ -72,13 +63,13 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
-        if (kind() != object.kind()) {
+        if (kind() != object().kind()) {
             return this;
         }
 
         if (kind() == Kind.Object) {
             ObjectStamp my = objectStamp();
-            ObjectStamp other = object.objectStamp();
+            ObjectStamp other = object().objectStamp();
 
             if (my.type() == null || other.type() == null) {
                 return this;
@@ -93,21 +84,21 @@
                 return this;
             }
         }
-        return object;
+        return object();
     }
 
     @Override
     public void generate(LIRGeneratorTool generator) {
-        if (kind() != object.kind()) {
-            assert generator.target().sizeInBytes(kind()) == generator.target().sizeInBytes(object.kind()) : "unsafe cast cannot be used to change the size of a value";
+        if (kind() != object().kind()) {
+            assert generator.target().sizeInBytes(kind()) == generator.target().sizeInBytes(object().kind()) : "unsafe cast cannot be used to change the size of a value";
             Value result = generator.newVariable(kind());
-            generator.emitMove(result, generator.operand(object));
+            generator.emitMove(result, generator.operand(object()));
             generator.setResult(this, result);
         } else {
             // The LIR only cares about the kind of an operand, not the actual type of an object. So
             // we do not have to
             // introduce a new operand when the kind is the same.
-            generator.setResult(this, generator.operand(object));
+            generator.setResult(this, generator.operand(object()));
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/PiPushable.java	Sun Apr 07 12:45:27 2013 +0200
@@ -0,0 +1,38 @@
+/*
+ * 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.nodes.spi;
+
+import com.oracle.graal.nodes.*;
+
+/**
+ * This interface marks nodes, which are able to be pushed through a PiNode.
+ */
+public interface PiPushable {
+
+    /**
+     * 
+     * @param parent PiNode
+     * @return true if node was moved
+     */
+    boolean push(PiNode parent);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ReplacementsProvider.java	Sun Apr 07 12:45:27 2013 +0200
@@ -0,0 +1,31 @@
+/*
+ * 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.nodes.spi;
+
+/**
+ * Interface for service providers that register replacements with the compiler.
+ */
+public interface ReplacementsProvider {
+
+    void registerReplacements(Replacements replacements);
+}
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Sat Apr 06 16:30:23 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Sun Apr 07 12:45:27 2013 +0200
@@ -482,9 +482,9 @@
                     PiNode piNode;
                     if (isNull) {
                         ConstantNode nullObject = ConstantNode.forObject(null, metaAccessProvider, graph);
-                        piNode = graph.unique(new PiNode(nullObject, anchor, StampFactory.forConstant(nullObject.value, metaAccessProvider)));
+                        piNode = graph.unique(new PiNode(nullObject, StampFactory.forConstant(nullObject.value, metaAccessProvider), anchor));
                     } else {
-                        piNode = graph.unique(new PiNode(object, anchor, StampFactory.declared(type, nonNull)));
+                        piNode = graph.unique(new PiNode(object, StampFactory.declared(type, nonNull), anchor));
                     }
                     checkCast.replaceAtUsages(piNode);
                     graph.replaceFixedWithFixed(checkCast, anchor);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Sat Apr 06 16:30:23 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Sun Apr 07 12:45:27 2013 +0200
@@ -931,7 +931,7 @@
 
     private static PiNode createAnchoredReceiver(StructuredGraph graph, FixedNode anchor, ResolvedJavaType commonType, ValueNode receiver, boolean exact) {
         // to avoid that floating reads on receiver fields float above the type check
-        return graph.unique(new PiNode(receiver, anchor, exact ? StampFactory.exactNonNull(commonType) : StampFactory.declaredNonNull(commonType)));
+        return graph.unique(new PiNode(receiver, exact ? StampFactory.exactNonNull(commonType) : StampFactory.declaredNonNull(commonType), anchor));
     }
 
     private static boolean checkInvokeConditions(Invoke invoke) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/PushNodesThroughPi.java	Sun Apr 07 12:45:27 2013 +0200
@@ -0,0 +1,48 @@
+/*
+ * 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.phases.common;
+
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.*;
+
+public class PushNodesThroughPi extends Phase {
+
+    public static final DebugMetric PUSHED_NODES = Debug.metric("NodesPushedThroughPi");
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        for (PiNode pi : graph.getNodes(PiNode.class)) {
+            for (Node n : pi.usages().snapshot()) {
+                if (n instanceof PiPushable) {
+                    PiPushable pip = (PiPushable) n;
+                    if (pip.push(pi)) {
+                        PUSHED_NODES.add(1);
+                    }
+                }
+            }
+        }
+    }
+}
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Sat Apr 06 16:30:23 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Sun Apr 07 12:45:27 2013 +0200
@@ -203,6 +203,8 @@
     public static boolean OptEliminatePartiallyRedundantGuards = true;
     public static boolean OptFilterProfiledTypes             = true;
     public static boolean OptDevirtualizeInvokesOptimistically = true;
+    public static boolean OptPushThroughPi                   = true;
+
 
     // Intrinsification settings
     public static boolean IntrinsifyObjectClone              = ____;
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/TypeCheckTest.java	Sat Apr 06 16:30:23 2013 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/TypeCheckTest.java	Sun Apr 07 12:45:27 2013 +0200
@@ -25,6 +25,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType;
+import com.oracle.graal.api.meta.ProfilingInfo.TriState;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.nodes.*;
 
@@ -48,6 +49,10 @@
     }
 
     protected JavaTypeProfile profile(Class... types) {
+        return profile(TriState.UNKNOWN, types);
+    }
+
+    protected JavaTypeProfile profile(TriState nullSeen, Class... types) {
         if (types.length == 0) {
             return null;
         }
@@ -55,7 +60,7 @@
         for (int i = 0; i < types.length; i++) {
             ptypes[i] = new ProfiledType(runtime.lookupJavaType(types[i]), 1.0D / types.length);
         }
-        return new JavaTypeProfile(0.0D, ptypes);
+        return new JavaTypeProfile(nullSeen, 0.0D, ptypes);
     }
 
     protected void test(String name, JavaTypeProfile profile, Object... args) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsProvider.java	Sat Apr 06 16:30:23 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * 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.replacements;
-
-import com.oracle.graal.nodes.spi.*;
-
-/**
- * Interface for service providers that register replacements with the compiler.
- */
-public interface ReplacementsProvider {
-
-    void registerReplacements(Replacements replacements);
-}
--- a/mx/commands.py	Sat Apr 06 16:30:23 2013 +0200
+++ b/mx/commands.py	Sun Apr 07 12:45:27 2013 +0200
@@ -297,9 +297,9 @@
     """
     jdk = join(_graal_home, 'jdk' + str(mx.java().version), build)
     jdkContents = ['bin', 'include', 'jre', 'lib']
-    if (exists(join(jdk, 'db'))):
+    if exists(join(jdk, 'db')):
         jdkContents.append('db')
-    if mx.get_os() != 'windows':
+    if mx.get_os() != 'windows' and exists(join(jdk, 'man')):
         jdkContents.append('man')
     if create:
         if not exists(jdk):
@@ -320,6 +320,7 @@
                 mx.abort(jvmCfg + ' does not exist')
 
             defaultVM = None
+            jvmCfgLines = []
             with open(jvmCfg) as f:
                 for line in f:
                     if line.startswith('-') and defaultVM is None:
@@ -327,14 +328,19 @@
                         assert len(parts) == 2, parts
                         assert parts[1] == 'KNOWN', parts[1]
                         defaultVM = parts[0][1:]
+                        jvmCfgLines += ['-' + defaultVM + '0 KNOWN\n']
+                    else:
+                        jvmCfgLines += [line]
 
             assert defaultVM is not None, 'Could not find default VM in ' + jvmCfg
             if mx.get_os() != 'windows':
                 chmodRecursive(jdk, 0755)
-            shutil.copytree(join(_vmLibDirInJdk(jdk), defaultVM), join(_vmLibDirInJdk(jdk), defaultVM + '0'))
+            shutil.move(join(_vmLibDirInJdk(jdk), defaultVM), join(_vmLibDirInJdk(jdk), defaultVM + '0'))
+            
 
             with open(jvmCfg, 'w') as fp:
-                print >> fp, '-' + defaultVM + '0 KNOWN'
+                for line in jvmCfgLines:
+                    fp.write(line)
 
             # Install a copy of the disassembler library
             try:
@@ -530,11 +536,10 @@
     if vm is None:
         vm = _vm
 
-    if vm == 'server':
+    if vm == 'server' or vm == 'server0':
         buildSuffix = ''
     elif vm == 'client':
         buildSuffix = '1'
-    elif vm == 'server0':
         return
     else:
         assert vm == 'graal', vm
@@ -549,6 +554,9 @@
                 mx.log('[skipping build from IDE as IDE_BUILD_TARGET environment variable is ""]')
                 continue
 
+        if vm == 'server0':
+            assert build == 'product', 'can not "build" a non-product server0'
+
         jdk = _jdk(build, create=True)
 
         vmDir = join(_vmLibDirInJdk(jdk), vm)
@@ -564,7 +572,9 @@
 
         # Check if a build really needs to be done
         timestampFile = join(vmDir, '.build-timestamp')
-        if opts2.force or not exists(timestampFile):
+        if vm == 'server0':
+            mustBuild = False
+        elif opts2.force or not exists(timestampFile):
             mustBuild = True
         else:
             mustBuild = False