# HG changeset patch # User Christian Humer # Date 1365331527 -7200 # Node ID 31f1390766d9b3c2e8ffa07bed86d581947fe282 # Parent e2b471ba533a7bfc874357450c6f98158b692350# Parent d47b52b0ff68361921bb2d6ac82fcf8a25f2b2d2 Merge. diff -r e2b471ba533a -r 31f1390766d9 .hgignore --- 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/ diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java --- 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. * diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java --- 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()); } } diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java --- 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() { diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java --- /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; + } +} diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- 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); diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java --- 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) { diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- 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; diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotInstalledCodeIntrinsics.java --- 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 { diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- 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()); } diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java --- 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 diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java --- 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; + } } diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- 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. * diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java --- 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())); } } diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/PiPushable.java --- /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); +} diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ReplacementsProvider.java --- /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); +} diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java --- 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); diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- 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) { diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/PushNodesThroughPi.java --- /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); + } + } + } + } + } +} diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java --- 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 = ____; diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/TypeCheckTest.java --- 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) { diff -r e2b471ba533a -r 31f1390766d9 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsProvider.java --- 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); -} diff -r e2b471ba533a -r 31f1390766d9 mx/commands.py --- 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