# HG changeset patch # User Doug Simon # Date 1367701765 -7200 # Node ID 325b394bc5358337e428db3908f40a52bb112ed2 # Parent 99ef9bcb3f329aa9d3127b0ef3353a4be0165bc1# Parent 9e77e858b6eba64f3246c736ea335b42bc39a2a4 Merge. diff -r 99ef9bcb3f32 -r 325b394bc535 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java Sat May 04 23:05:46 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java Sat May 04 23:09:25 2013 +0200 @@ -26,7 +26,7 @@ import junit.framework.Assert; -import org.junit.*; +import org.junit.Test; import com.oracle.graal.api.code.*; import com.oracle.graal.debug.*; @@ -91,6 +91,22 @@ compileSnippet("test4Snippet", 2, 2); } + public static long test5Snippet(A1 a1) { + long sum = 0; + A2 a2 = (A2) a1; + A3 a3 = (A3) a2; + sum += a2.x2; + return sum + a3.x3; + } + + @Test + public void test5() { + StructuredGraph graph = compileSnippet("test5Snippet", 2, 1); + for (LoadFieldNode lfn : graph.getNodes().filter(LoadFieldNode.class)) { + Assert.assertTrue(lfn.object() instanceof CheckCastNode); + } + } + private StructuredGraph compileSnippet(final String snippet, final int checkcasts, final int afterCanon) { return Debug.scope(snippet, new Callable() { diff -r 99ef9bcb3f32 -r 325b394bc535 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Sat May 04 23:05:46 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Sat May 04 23:09:25 2013 +0200 @@ -31,9 +31,9 @@ import com.oracle.graal.debug.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.Lowerable.LoweringType; +import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; @@ -66,17 +66,24 @@ public void run() { StructuredGraph graph = compileTestSnippet(snippet); + int counter = 0; for (ReadNode rn : graph.getNodes().filter(ReadNode.class)) { - LocationIdentity locId = rn.location().getLocationIdentity(); - 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); + if (rn.location() instanceof ConstantLocationNode && rn.object().stamp() instanceof ObjectStamp) { + long disp = ((ConstantLocationNode) rn.location()).getDisplacement(); + ResolvedJavaType receiverType = rn.object().objectStamp().type(); + ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(disp); + + if (field != null) { + if (field.getName().equals("x")) { + Assert.assertTrue(rn.object() instanceof LocalNode); + } else { + Assert.assertTrue(rn.object() instanceof UnsafeCastNode); + } + counter++; } } } + Assert.assertEquals(2, counter); Assert.assertTrue(graph.getNodes().filter(IsNullNode.class).count() == 1); } diff -r 99ef9bcb3f32 -r 325b394bc535 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 May 04 23:05:46 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Sat May 04 23:09:25 2013 +0200 @@ -90,6 +90,8 @@ */ public abstract class HotSpotRuntime implements GraalCodeCacheProvider, DisassemblerProvider, BytecodeDisassemblerProvider { + public static final Descriptor OSR_MIGRATION_END = new Descriptor("OSR_migration_end", true, void.class, long.class); + public final HotSpotVMConfig config; protected final RegisterConfig regConfig; @@ -868,6 +870,30 @@ graph.removeFixed(commit); } else if (n instanceof CheckCastNode) { checkcastSnippets.lower((CheckCastNode) n, tool); + } else if (n instanceof OSRStartNode) { + OSRStartNode osrStart = (OSRStartNode) n; + StartNode newStart = graph.add(new StartNode()); + LocalNode buffer = graph.unique(new LocalNode(0, StampFactory.forKind(wordKind()))); + RuntimeCallNode migrationEnd = graph.add(new RuntimeCallNode(OSR_MIGRATION_END, buffer)); + migrationEnd.setStateAfter(osrStart.stateAfter()); + + newStart.setNext(migrationEnd); + FixedNode next = osrStart.next(); + osrStart.setNext(null); + migrationEnd.setNext(next); + graph.setStart(newStart); + + // mirroring the calculations in c1_GraphBuilder.cpp (setup_osr_entry_block) + int localsOffset = (graph.method().getMaxLocals() - 1) * 8; + for (OSRLocalNode osrLocal : graph.getNodes(OSRLocalNode.class)) { + int size = FrameStateBuilder.stackSlots(osrLocal.kind()); + int offset = localsOffset - (osrLocal.index() + size - 1) * 8; + UnsafeLoadNode load = graph.add(new UnsafeLoadNode(buffer, offset, ConstantNode.forInt(0, graph), osrLocal.kind())); + osrLocal.replaceAndDelete(load); + graph.addBeforeFixed(migrationEnd, load); + } + osrStart.replaceAtUsages(newStart); + osrStart.safeDelete(); } else if (n instanceof CheckCastDynamicNode) { checkcastSnippets.lower((CheckCastDynamicNode) n); } else if (n instanceof InstanceOfNode) { diff -r 99ef9bcb3f32 -r 325b394bc535 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java Sat May 04 23:05:46 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java Sat May 04 23:09:25 2013 +0200 @@ -22,20 +22,14 @@ */ package com.oracle.graal.hotspot.phases; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; - import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.RuntimeCallTarget.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; -import com.oracle.graal.graph.Node.*; +import com.oracle.graal.graph.Node.Verbosity; import com.oracle.graal.graph.iterators.*; -import com.oracle.graal.java.*; import com.oracle.graal.loop.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; @@ -43,29 +37,6 @@ public class OnStackReplacementPhase extends Phase { - public static final Descriptor OSR_MIGRATION_END = new Descriptor("OSR_migration_end", true, void.class, long.class); - - public class OSREntryProxyNode extends FloatingNode implements LIRLowerable { - - @Input private ValueNode object; - @Input(notDataflow = true) private final RuntimeCallNode anchor; - - public OSREntryProxyNode(ValueNode object, RuntimeCallNode anchor) { - super(object.stamp()); - this.object = object; - this.anchor = anchor; - } - - public RuntimeCallNode getAnchor() { - return anchor; - } - - @Override - public void generate(LIRGeneratorTool generator) { - generator.setResult(this, generator.operand(object)); - } - } - @Override protected void run(StructuredGraph graph) { if (graph.getEntryBCI() == StructuredGraph.INVOCATION_ENTRY_BCI) { @@ -114,39 +85,29 @@ Debug.dump(graph, "OnStackReplacement loop peeling result"); } while (true); - LocalNode buffer = graph.unique(new LocalNode(0, StampFactory.forKind(wordKind()))); - RuntimeCallNode migrationEnd = graph.add(new RuntimeCallNode(OSR_MIGRATION_END, buffer)); FrameState osrState = osr.stateAfter(); - migrationEnd.setStateAfter(osrState); osr.setStateAfter(null); - + OSRStartNode osrStart = graph.add(new OSRStartNode()); StartNode start = graph.start(); - FixedNode rest = start.next(); - start.setNext(migrationEnd); FixedNode next = osr.next(); osr.setNext(null); - migrationEnd.setNext(next); + osrStart.setNext(next); + graph.setStart(osrStart); + osrStart.setStateAfter(osrState); - FrameState oldStartState = start.stateAfter(); - start.setStateAfter(null); - GraphUtil.killWithUnusedFloatingInputs(oldStartState); - - // mirroring the calculations in c1_GraphBuilder.cpp (setup_osr_entry_block) - int localsOffset = (graph.method().getMaxLocals() - 1) * 8; for (int i = 0; i < osrState.localsSize(); i++) { ValueNode value = osrState.localAt(i); if (value != null) { ProxyNode proxy = (ProxyNode) value; - int size = FrameStateBuilder.stackSlots(value.kind()); - int offset = localsOffset - (i + size - 1) * 8; - UnsafeLoadNode load = graph.add(new UnsafeLoadNode(buffer, offset, ConstantNode.forInt(0, graph), value.kind())); - OSREntryProxyNode newProxy = graph.add(new OSREntryProxyNode(load, migrationEnd)); - proxy.replaceAndDelete(newProxy); - graph.addBeforeFixed(migrationEnd, load); + /* + * we need to drop the stamp and go back to the kind since the types we see during + * OSR may be too precise (if a branch was not parsed for example). + */ + proxy.replaceAndDelete(graph.unique(new OSRLocalNode(i, StampFactory.forKind(proxy.kind())))); } } - GraphUtil.killCFG(rest); + GraphUtil.killCFG(start); Debug.dump(graph, "OnStackReplacement result"); new DeadCodeEliminationPhase().apply(graph); diff -r 99ef9bcb3f32 -r 325b394bc535 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java Sat May 04 23:05:46 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java Sat May 04 23:09:25 2013 +0200 @@ -101,7 +101,7 @@ if (memory.notEqual(0)) { log(log, "newArray: allocated new array at %p\n", memory); formatArray(hub, sizeInBytes, length, headerSize, memory, Word.unsigned(arrayPrototypeMarkWord()), true); - return verifyOop(memory.toObject()); + return memory.toObject(); } } log(log, "newArray: calling new_array_c\n", 0L); @@ -113,7 +113,7 @@ getAndClearObjectResult(thread()); DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint); } - return verifyOop(getAndClearObjectResult(thread())); + return getAndClearObjectResult(thread()); } public static final Descriptor NEW_ARRAY_C = descriptorFor(NewArrayStub.class, "newArrayC", false); diff -r 99ef9bcb3f32 -r 325b394bc535 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java Sat May 04 23:05:46 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java Sat May 04 23:09:25 2013 +0200 @@ -94,7 +94,7 @@ for (int offset = 2 * wordSize(); offset < sizeInBytes; offset += wordSize()) { memory.writeWord(offset, Word.zero(), ANY_LOCATION); } - return verifyOop(memory.toObject()); + return memory.toObject(); } } } @@ -108,7 +108,7 @@ getAndClearObjectResult(thread()); DeoptimizeCallerNode.deopt(InvalidateReprofile, RuntimeConstraint); } - return verifyOop(getAndClearObjectResult(thread())); + return getAndClearObjectResult(thread()); } /** diff -r 99ef9bcb3f32 -r 325b394bc535 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewMultiArrayStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewMultiArrayStub.java Sat May 04 23:05:46 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewMultiArrayStub.java Sat May 04 23:09:25 2013 +0200 @@ -48,7 +48,7 @@ private static Object newMultiArray(Word hub, int rank, Word dims) { newMultiArrayC(NEW_MULTI_ARRAY_C, thread(), hub, rank, dims); handlePendingException(true); - return verifyOop(getAndClearObjectResult(thread())); + return getAndClearObjectResult(thread()); } public static final Descriptor NEW_MULTI_ARRAY_C = descriptorFor(NewMultiArrayStub.class, "newMultiArrayC", false); diff -r 99ef9bcb3f32 -r 325b394bc535 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 May 04 23:05:46 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Sat May 04 23:09:25 2013 +0200 @@ -679,7 +679,7 @@ } private void genGoto() { - appendGoto(createTarget(1, currentBlock.successors.get(0), frameState)); + appendGoto(createTarget(currentBlock.successors.get(0), frameState)); assert currentBlock.numNormalSuccessors() == 1; } diff -r 99ef9bcb3f32 -r 325b394bc535 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractLocalNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractLocalNode.java Sat May 04 23:09:25 2013 +0200 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2009, 2011, 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; + +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.type.*; + +public abstract class AbstractLocalNode extends FloatingNode { + + private final int index; + + public AbstractLocalNode(int index, Stamp stamp) { + super(stamp); + this.index = index; + } + + /** + * Gets the index of this local in the array of parameters. This is NOT the JVM local index. + * + * @return the index + */ + public int index() { + return index; + } + + @Override + public String toString(Verbosity verbosity) { + if (verbosity == Verbosity.Name) { + return super.toString(Verbosity.Name) + "(" + index + ")"; + } else { + return super.toString(verbosity); + } + } +} diff -r 99ef9bcb3f32 -r 325b394bc535 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LocalNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LocalNode.java Sat May 04 23:05:46 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LocalNode.java Sat May 04 23:09:25 2013 +0200 @@ -23,37 +23,15 @@ package com.oracle.graal.nodes; import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.type.*; /** * The {@code Local} instruction is a placeholder for an incoming argument to a function call. */ @NodeInfo(nameTemplate = "Local({p#index})") -public final class LocalNode extends FloatingNode implements Node.IterableNodeType { - - private final int index; +public final class LocalNode extends AbstractLocalNode implements Node.IterableNodeType { public LocalNode(int index, Stamp stamp) { - super(stamp); - this.index = index; - } - - /** - * Gets the index of this local in the array of parameters. This is NOT the JVM local index. - * - * @return the index - */ - public int index() { - return index; - } - - @Override - public String toString(Verbosity verbosity) { - if (verbosity == Verbosity.Name) { - return super.toString(Verbosity.Name) + "(" + index + ")"; - } else { - return super.toString(verbosity); - } + super(index, stamp); } } diff -r 99ef9bcb3f32 -r 325b394bc535 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Sat May 04 23:05:46 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Sat May 04 23:09:25 2013 +0200 @@ -44,20 +44,22 @@ private final Set leafGraphIds = new HashSet<>(4); - private final StartNode start; + private StartNode start; private final ResolvedJavaMethod method; private final long graphId; private final int entryBCI; /** - * Creates a new Graph containing a single {@link AbstractBeginNode} as the {@link #start() start} node. + * Creates a new Graph containing a single {@link AbstractBeginNode} as the {@link #start() + * start} node. */ public StructuredGraph() { this(null, null); } /** - * Creates a new Graph containing a single {@link AbstractBeginNode} as the {@link #start() start} node. + * Creates a new Graph containing a single {@link AbstractBeginNode} as the {@link #start() + * start} node. */ public StructuredGraph(String name, ResolvedJavaMethod method) { this(name, method, uniqueGraphIds.incrementAndGet(), INVOCATION_ENTRY_BCI); @@ -73,7 +75,7 @@ private StructuredGraph(String name, ResolvedJavaMethod method, long graphId, int entryBCI) { super(name); - this.start = add(new StartNode()); + this.setStart(add(new StartNode())); this.method = method; this.graphId = graphId; this.entryBCI = entryBCI; @@ -116,6 +118,10 @@ return graphId; } + public void setStart(StartNode start) { + this.start = start; + } + /** * @return the {@link Set} that contains the {@link #graphId()} of all graphs that were * incorporated into this one (e.g. by inlining). diff -r 99ef9bcb3f32 -r 325b394bc535 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java Sat May 04 23:05:46 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java Sat May 04 23:09:25 2013 +0200 @@ -41,7 +41,7 @@ I2B(Int, Byte, false), I2C(Int, Char, false), I2S(Int, Short, false), - F2D(Float, Double, false), + F2D(Float, Double, true), D2F(Double, Float, false), I2F(Int, Float, false), I2D(Int, Double, true), diff -r 99ef9bcb3f32 -r 325b394bc535 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRLocalNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRLocalNode.java Sat May 04 23:09:25 2013 +0200 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2009, 2011, 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.extended; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.type.*; + +@NodeInfo(nameTemplate = "OSRLocal({p#index})") +public class OSRLocalNode extends AbstractLocalNode implements Node.IterableNodeType { + + public OSRLocalNode(int index, Stamp stamp) { + super(index, stamp); + } + +} diff -r 99ef9bcb3f32 -r 325b394bc535 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java Sat May 04 23:09:25 2013 +0200 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013, 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.extended; + +import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; + +public class OSRStartNode extends StartNode implements Lowerable { + + @Override + public void lower(LoweringTool tool, LoweringType loweringType) { + if (loweringType == LoweringType.AFTER_GUARDS) { + tool.getRuntime().lower(this, tool); + } + } + + public NodeIterable getOSRLocals() { + return usages().filter(OSRLocalNode.class); + } +} diff -r 99ef9bcb3f32 -r 325b394bc535 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 May 04 23:05:46 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Sat May 04 23:09:25 2013 +0200 @@ -102,19 +102,27 @@ @Override public boolean push(PiNode parent) { - LocationIdentity locId = location().getLocationIdentity(); - if (locId instanceof ResolvedJavaField) { - ResolvedJavaType fieldType = ((ResolvedJavaField) locId).getDeclaringClass(); - ValueNode piValueStamp = parent.object(); - ResolvedJavaType beforePiType = piValueStamp.objectStamp().type(); + if (location() instanceof ConstantLocationNode) { + long displacement = ((ConstantLocationNode) location()).getDisplacement(); + if (parent.stamp() instanceof ObjectStamp) { + ObjectStamp piStamp = parent.objectStamp(); + ResolvedJavaType receiverType = piStamp.type(); + if (receiverType != null) { + ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement); - if (beforePiType != null && fieldType.isAssignableFrom(beforePiType)) { - ObjectStamp piStamp = parent.objectStamp(); - if (piStamp.nonNull() == piValueStamp.objectStamp().nonNull() && piStamp.alwaysNull() == piValueStamp.objectStamp().alwaysNull()) { - replaceFirstInput(parent, piValueStamp); - return true; + if (field != null) { + ResolvedJavaType declaringClass = field.getDeclaringClass(); + if (declaringClass.isAssignableFrom(receiverType) && declaringClass != receiverType) { + ObjectStamp piValueStamp = parent.object().objectStamp(); + if (piStamp.nonNull() == piValueStamp.nonNull() && piStamp.alwaysNull() == piValueStamp.alwaysNull()) { + replaceFirstInput(parent, parent.object()); + return true; + } + } + } } } + } return false; } diff -r 99ef9bcb3f32 -r 325b394bc535 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SnippetLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SnippetLocationNode.java Sat May 04 23:05:46 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SnippetLocationNode.java Sat May 04 23:09:25 2013 +0200 @@ -98,8 +98,8 @@ } @NodeIntrinsic - public static native Location constantLocation(Object identity, Kind kind, long displacement); + public static native Location constantLocation(LocationIdentity identity, Kind kind, long displacement); @NodeIntrinsic - public static native Location indexedLocation(Object identity, Kind kind, long displacement, int index, int indexScaling); + public static native Location indexedLocation(LocationIdentity identity, Kind kind, long displacement, int index, int indexScaling); } diff -r 99ef9bcb3f32 -r 325b394bc535 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Sat May 04 23:05:46 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Sat May 04 23:09:25 2013 +0200 @@ -25,6 +25,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.LocationNode.Location; import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -91,7 +92,7 @@ } @NodeIntrinsic - public static native void writeMemory(Object object, Object value, Object location, @ConstantNodeParameter WriteBarrierType barrierType); + public static native void writeMemory(Object object, Object value, Location location, @ConstantNodeParameter WriteBarrierType barrierType); @Override public LocationIdentity[] getLocationIdentities() { diff -r 99ef9bcb3f32 -r 325b394bc535 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Sat May 04 23:05:46 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Sat May 04 23:09:25 2013 +0200 @@ -85,11 +85,15 @@ // checkcast. return object(); } + // remove checkcast if next node is a more specific checkcast - if (next() instanceof CheckCastNode) { - CheckCastNode ccn = (CheckCastNode) next(); - if (ccn != null && ccn.type() != null && this == ccn.object() && type.isAssignableFrom(ccn.type())) { - return object(); + if (predecessor() instanceof CheckCastNode) { + CheckCastNode ccn = (CheckCastNode) predecessor(); + if (ccn != null && ccn.type != null && ccn == object && ccn.forStoreCheck == forStoreCheck && ccn.type.isAssignableFrom(type)) { + StructuredGraph graph = (StructuredGraph) ccn.graph(); + CheckCastNode newccn = graph.add(new CheckCastNode(type, ccn.object, ccn.profile, ccn.forStoreCheck)); + graph.replaceFixedWithFixed(ccn, newccn); + return newccn; } } diff -r 99ef9bcb3f32 -r 325b394bc535 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java Sat May 04 23:05:46 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java Sat May 04 23:09:25 2013 +0200 @@ -35,7 +35,7 @@ @Input private final NodeInputList virtualObjects = new NodeInputList<>(this); @Input private final NodeInputList values = new NodeInputList<>(this); - private final List locks = new ArrayList<>(); + private List locks = new ArrayList<>(); public CommitAllocationNode() { super(StampFactory.forVoid()); @@ -72,6 +72,13 @@ } @Override + public Node clone(Graph into) { + CommitAllocationNode clone = (CommitAllocationNode) super.clone(into); + clone.locks = new ArrayList<>(locks); + return clone; + } + + @Override public void virtualize(VirtualizerTool tool) { int pos = 0; for (int i = 0; i < virtualObjects.size(); i++) { diff -r 99ef9bcb3f32 -r 325b394bc535 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 May 04 23:05:46 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Sat May 04 23:09:25 2013 +0200 @@ -34,7 +34,10 @@ private static final boolean ____ = false; // Checkstyle: resume - public static int Threads = 4; + public static int Threads; + static { + Threads = Runtime.getRuntime().availableProcessors(); + } public static String CompilerConfiguration = "basic"; public static String GraalRuntime = "basic"; diff -r 99ef9bcb3f32 -r 325b394bc535 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java Sat May 04 23:05:46 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java Sat May 04 23:09:25 2013 +0200 @@ -334,7 +334,7 @@ // default handler createElementForNode(node); - List children = NodeUtil.findNodeChildren(node); + List children = NodeUtil.findNodeChildren((Node) node); for (Object child : children) { if (child == null) { continue; diff -r 99ef9bcb3f32 -r 325b394bc535 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Sat May 04 23:05:46 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Sat May 04 23:09:25 2013 +0200 @@ -29,6 +29,9 @@ import sun.misc.*; +import com.oracle.truffle.api.nodes.Node.Child; +import com.oracle.truffle.api.nodes.Node.Children; + /** * Utility class that manages the special access methods for node instances. */ @@ -73,15 +76,13 @@ } // Node fields - if (Node.class.isAssignableFrom(field.getType())) { - if (!field.getName().equals("parent")) { - nodeFieldOffsetsList.add(unsafe.objectFieldOffset(field)); - nodeFieldClassesList.add(field.getType()); - } else { - parentOffsetTemp = unsafe.objectFieldOffset(field); - parentClassTmp = field.getType(); - } - } else if (field.getType().getComponentType() != null && Node.class.isAssignableFrom(field.getType().getComponentType())) { + if (Node.class.isAssignableFrom(field.getType()) && field.getName().equals("parent")) { + parentOffsetTemp = unsafe.objectFieldOffset(field); + parentClassTmp = field.getType(); + } else if (Node.class.isAssignableFrom(field.getType()) && field.getAnnotation(Child.class) != null) { + nodeFieldOffsetsList.add(unsafe.objectFieldOffset(field)); + nodeFieldClassesList.add(field.getType()); + } else if (field.getType().getComponentType() != null && Node.class.isAssignableFrom(field.getType().getComponentType()) && field.getAnnotation(Children.class) != null) { nodeArrayFieldOffsetsList.add(unsafe.objectFieldOffset(field)); nodeArrayFieldClassesList.add(field.getType()); } else { @@ -251,18 +252,18 @@ return (T) clone; } - public static List findNodeChildren(Object node) { - List nodes = new ArrayList<>(); + public static List findNodeChildren(Node node) { + List nodes = new ArrayList<>(); NodeClass nodeClass = NodeClass.get(node.getClass()); for (long fieldOffset : nodeClass.nodeFieldOffsets) { Object child = unsafe.getObject(node, fieldOffset); if (child != null) { - nodes.add(child); + nodes.add((Node) child); } } for (long fieldOffset : nodeClass.nodeArrayFieldOffsets) { - Object[] children = (Object[]) unsafe.getObject(node, fieldOffset); + Node[] children = (Node[]) unsafe.getObject(node, fieldOffset); if (children != null) { nodes.addAll(Arrays.asList(children)); } @@ -386,10 +387,8 @@ } @SuppressWarnings("unchecked") - public static T findFirstNodeInstance(Object root, Class clazz) { - List childNodes = findNodeChildren(root); - - for (Object childNode : childNodes) { + public static T findFirstNodeInstance(Node root, Class clazz) { + for (Node childNode : findNodeChildren(root)) { if (clazz.isInstance(childNode)) { return (T) childNode; } else { @@ -474,8 +473,16 @@ } public static String printTreeToString(Node node) { + return printTreeToString(node, false); + } + + private static String printTreeToString(Node node, boolean compact) { ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); - printTree(new PrintStream(byteOut), node); + if (compact) { + printCompactTree(new PrintStream(byteOut), node); + } else { + printTree(new PrintStream(byteOut), node); + } try { byteOut.flush(); } catch (IOException e) { @@ -494,6 +501,61 @@ printTree(p, node, new NodeTreeResolver()); } + public static String printCompactTreeToString(Node node) { + return printTreeToString(node, true); + } + + public static void printCompactTree(PrintStream p, Node node) { + printCompactTree(p, null, node, 1); + } + + private static void printCompactTree(PrintStream p, Node parent, Node node, int level) { + if (node == null) { + return; + } + for (int i = 0; i < level; i++) { + p.print(" "); + } + if (parent == null) { + p.println(node.getClass().getSimpleName()); + } else { + String fieldName = null; + Field[] fields = NodeUtil.getAllFields(parent.getClass()); + try { + for (Field field : fields) { + field.setAccessible(true); + Object value = field.get(parent); + if (value == node) { + fieldName = field.getName(); + break; + } else if (value instanceof Node[]) { + int index = 0; + for (Node arrayNode : (Node[]) value) { + if (arrayNode == node) { + fieldName = field.getName() + "[" + index + "]"; + break; + } + index++; + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + if (fieldName == null) { + fieldName = "unknownField"; + } + p.print(fieldName); + p.print(" = "); + p.println(node.getClass().getSimpleName()); + } + + for (Node child : node.getChildren()) { + printCompactTree(p, node, child, level + 1); + } + } + /** * Prints a human readable form of a tree to the given {@link PrintStream}. The * {@link TreeResolver} interface needs to be implemented to specify how the method can read the @@ -639,12 +701,12 @@ @Override public boolean isChildObject(Field f) { - return Node.class.isAssignableFrom(f.getType()); + return Node.class.isAssignableFrom(f.getType()) && f.getAnnotation(Child.class) != null; } @Override public boolean isChildArrayObject(Field f) { - return f.getType().getComponentType() != null && Node.class.isAssignableFrom(f.getType().getComponentType()); + return f.getType().getComponentType() != null && Node.class.isAssignableFrom(f.getType().getComponentType()) && f.getAnnotation(Children.class) != null; } @Override diff -r 99ef9bcb3f32 -r 325b394bc535 graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Sat May 04 23:05:46 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Sat May 04 23:09:25 2013 +0200 @@ -1460,8 +1460,7 @@ List executeParameters = new ArrayList<>(); for (ActualParameter sourceParameter : executable.getParameters()) { - NodeChildData field = specialization.getNode().findChild(sourceParameter.getSpecification().getName()); - if (field == null) { + if (!sourceParameter.getSpecification().isSignature()) { continue; } @@ -1645,21 +1644,24 @@ for (ActualParameter targetParameter : targetParameters) { NodeChildData field = sourceNode.findChild(targetParameter.getSpecification().getName()); - if (field == null) { + if (!targetParameter.getSpecification().isSignature()) { continue; } + TypeData targetType = targetParameter.getTypeSystemType(); - - ExecutableTypeData targetExecutable = field.findExecutableType(getContext(), targetType); + ExecutableTypeData targetExecutable = null; + if (field != null) { + targetExecutable = field.findExecutableType(getContext(), targetType); + } ActualParameter sourceParameter = sourceExecutable.findParameter(targetParameter.getLocalName()); String targetVariableName = valueName(targetParameter); CodeTree executionExpression = null; - if (cast || sourceParameter != null) { + if ((sourceParameter != null && cast) || sourceParameter != null) { TypeData sourceType = sourceParameter.getTypeSystemType(); - if (!sourceType.needsCastTo(getContext(), targetType)) { - if (field.isShortCircuit() && sourceParameter != null) { + if (targetExecutable == null || !sourceType.needsCastTo(getContext(), targetType)) { + if (field != null && field.isShortCircuit() && sourceParameter != null) { builder.tree(createShortCircuitValue(builder, specialization, field, targetParameter.getPreviousParameter(), unexpectedParameter)); } builder.startStatement(); @@ -1667,8 +1669,10 @@ builder.string(valueName(targetParameter)).string(" = "); builder.tree(CodeTreeBuilder.singleString(valueNameEvaluated(targetParameter))); builder.end(); + continue; } else { - executionExpression = createExpectExecutableType(sourceNode, sourceType, targetExecutable, CodeTreeBuilder.singleString(valueNameEvaluated(targetParameter))); + CodeTree valueTree = CodeTreeBuilder.singleString(valueNameEvaluated(targetParameter)); + executionExpression = createExpectExecutableType(sourceNode, sourceType, targetExecutable, valueTree); } } else if (sourceParameter == null) { executionExpression = createExecuteChildExpression(builder, field, targetParameter, unexpectedParameter);