Mercurial > hg > graal-compiler
changeset 6295:904517c1cd06
Merge.
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Tue, 28 Aug 2012 14:17:22 +0200 |
parents | 01d274503562 (diff) b0fc02623974 (current diff) |
children | 6a51bc216306 |
files | |
diffstat | 22 files changed, 368 insertions(+), 100 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Tue Aug 28 13:55:11 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Tue Aug 28 14:17:22 2012 +0200 @@ -43,25 +43,30 @@ private HashMap<VirtualObjectNode, VirtualObject> virtualObjects = new HashMap<>(); + private IdentityHashMap<VirtualObjectNode, EscapeObjectState> objectStates = new IdentityHashMap<>(); public LIRFrameState build(FrameState topState, LockScope locks, List<StackSlot> pointerSlots, LabelRef exceptionEdge, long leafGraphId) { assert virtualObjects.size() == 0; + assert objectStates.size() == 0; + + // collect all VirtualObjectField instances: + FrameState current = topState; + do { + for (EscapeObjectState state : current.virtualObjectMappings()) { + if (objectStates == null) { + objectStates = new IdentityHashMap<>(); + } + if (!objectStates.containsKey(state.object())) { + objectStates.put(state.object(), state); + } + } + current = current.outerFrameState(); + } while (current != null); + BytecodeFrame frame = computeFrameForState(topState, locks, leafGraphId); VirtualObject[] virtualObjectsArray = null; if (virtualObjects.size() != 0) { - // collect all VirtualObjectField instances: - IdentityHashMap<VirtualObjectNode, VirtualObjectState> objectStates = new IdentityHashMap<>(); - FrameState current = topState; - do { - for (VirtualObjectState state : current.virtualObjectMappings()) { - // null states occur for objects with 0 fields - if (!objectStates.containsKey(state.object())) { - objectStates.put(state.object(), state); - } - } - current = current.outerFrameState(); - } while (current != null); // fill in the VirtualObject values: // during this process new VirtualObjects might be discovered, so repeat until no more changes occur. boolean changed; @@ -79,7 +84,7 @@ entry.getValue().setValues(values); if (values.length > 0) { changed = true; - VirtualObjectState currentField = objectStates.get(vobj); + VirtualObjectState currentField = (VirtualObjectState) objectStates.get(vobj); assert currentField != null; for (int i = 0; i < vobj.fieldsCount(); i++) { values[i] = toValue(currentField.fieldValues().get(i)); @@ -93,6 +98,7 @@ virtualObjectsArray = virtualObjects.values().toArray(new VirtualObject[virtualObjects.size()]); virtualObjects.clear(); } + objectStates.clear(); return new LIRFrameState(frame, virtualObjectsArray, pointerSlots, exceptionEdge); } @@ -138,14 +144,23 @@ private Value toValue(ValueNode value) { if (value instanceof VirtualObjectNode) { VirtualObjectNode obj = (VirtualObjectNode) value; - VirtualObject ciObj = virtualObjects.get(value); - if (ciObj == null) { - ciObj = VirtualObject.get(obj.type(), null, virtualObjects.size()); - virtualObjects.put(obj, ciObj); + EscapeObjectState state = objectStates.get(obj); + if (state == null && obj.fieldsCount() > 0) { + // null states occur for objects with 0 fields + throw new GraalInternalError("no mapping found for virtual object %s", obj); } - Debug.metric("StateVirtualObjects").increment(); - return ciObj; - + if (state instanceof MaterializedObjectState) { + return toValue(((MaterializedObjectState) state).materializedValue()); + } else { + assert obj.fieldsCount() == 0 || state instanceof VirtualObjectState; + VirtualObject ciObj = virtualObjects.get(value); + if (ciObj == null) { + ciObj = VirtualObject.get(obj.type(), null, virtualObjects.size()); + virtualObjects.put(obj, ciObj); + } + Debug.metric("StateVirtualObjects").increment(); + return ciObj; + } } else if (value instanceof ConstantNode) { Debug.metric("StateConstants").increment(); return ((ConstantNode) value).value;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/BoxingEliminationPhase.java Tue Aug 28 13:55:11 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/BoxingEliminationPhase.java Tue Aug 28 14:17:22 2012 +0200 @@ -36,6 +36,8 @@ public class BoxingEliminationPhase extends Phase { + private int virtualIds = Integer.MIN_VALUE; + @Override protected void run(StructuredGraph graph) { if (graph.getNodes(UnboxNode.class).isNotEmpty()) { @@ -105,7 +107,7 @@ } } - private static void tryEliminate(BoxNode boxNode) { + private void tryEliminate(BoxNode boxNode) { assert boxNode.objectStamp().isExactType(); virtualizeUsages(boxNode, boxNode.source(), boxNode.objectStamp().type()); @@ -122,12 +124,12 @@ ((StructuredGraph) boxNode.graph()).removeFixed(boxNode); } - private static void virtualizeUsages(ValueNode boxNode, ValueNode replacement, ResolvedJavaType exactType) { + private void virtualizeUsages(ValueNode boxNode, ValueNode replacement, ResolvedJavaType exactType) { ValueNode virtualValueNode = null; VirtualObjectNode virtualObjectNode = null; for (Node n : boxNode.usages().filter(NodePredicates.isA(VirtualState.class)).snapshot()) { if (virtualValueNode == null) { - virtualObjectNode = n.graph().unique(new BoxedVirtualObjectNode(exactType, replacement)); + virtualObjectNode = n.graph().unique(new BoxedVirtualObjectNode(virtualIds++, exactType, replacement)); } n.replaceFirstInput(boxNode, virtualObjectNode); }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CanonicalizerPhase.java Tue Aug 28 13:55:11 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CanonicalizerPhase.java Tue Aug 28 14:17:22 2012 +0200 @@ -180,6 +180,7 @@ public static boolean tryCanonicalize(final Node node, final StructuredGraph graph, final SimplifierTool tool) { if (node instanceof Canonicalizable) { + assert !(node instanceof Simplifiable); METRIC_CANONICALIZATION_CONSIDERED_NODES.increment(); return Debug.scope("CanonicalizeNode", node, new Callable<Boolean>(){ public Boolean call() {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EscapeAnalysisPhase.java Tue Aug 28 13:55:11 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EscapeAnalysisPhase.java Tue Aug 28 14:17:22 2012 +0200 @@ -38,13 +38,13 @@ import com.oracle.graal.nodes.virtual.*; import com.oracle.max.criutils.*; - public class EscapeAnalysisPhase extends Phase { /** * Encapsulates the state of the virtual object, which is updated while traversing the control flow graph. */ - public static class BlockExitState implements MergeableState<BlockExitState> { + private static class BlockExitState implements MergeableState<BlockExitState> { + public final ValueNode[] fieldState; public final VirtualObjectNode virtualObject; public final Graph graph; @@ -115,16 +115,17 @@ } } - - public static class EscapementFixup { + private static class EscapementFixup { private final Map<Object, Integer> fields = new HashMap<>(); private final EscapeOp op; private final StructuredGraph graph; private final FixedWithNextNode node; private EscapeField[] escapeFields; + private final int id; - public EscapementFixup(EscapeOp op, StructuredGraph graph, FixedWithNextNode node) { + public EscapementFixup(int id, EscapeOp op, StructuredGraph graph, FixedWithNextNode node) { + this.id = id; this.op = op; this.graph = graph; this.node = node; @@ -151,7 +152,7 @@ fields.put(escapeFields[i].representation(), i); } assert node.objectStamp().isExactType(); - final VirtualObjectNode virtual = graph.add(new VirtualObjectNode(node.objectStamp().type(), escapeFields)); + final VirtualObjectNode virtual = graph.add(new VirtualObjectNode(id, node.objectStamp().type(), escapeFields.length)); if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) { TTY.println("new virtual object: " + virtual); } @@ -170,6 +171,7 @@ if (virtual.fieldsCount() > 0) { final BlockExitState startState = new BlockExitState(escapeFields, virtual); new PostOrderNodeIterator<BlockExitState>(next, startState) { + @Override protected void node(FixedNode curNode) { op.updateState(virtual, curNode, fields, state.fieldState); @@ -188,6 +190,10 @@ } } + + private int virtualIds = 0; + + private final TargetDescription target; private final GraalCodeCacheProvider runtime; private final Assumptions assumptions; @@ -204,7 +210,7 @@ this.optimisticOpts = optimisticOpts; } - public static class EscapeRecord { + private static class EscapeRecord { public final Node node; public final ArrayList<Node> escapesThrough = new ArrayList<>(); @@ -380,7 +386,7 @@ } protected void removeAllocation(StructuredGraph graph, FixedWithNextNode node, EscapeOp op) { - new EscapementFixup(op, graph, node).apply(); + new EscapementFixup(virtualIds++, op, graph, node).apply(); for (PhiNode phi : node.graph().getNodes(PhiNode.class)) { ValueNode simpleValue = phi;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java Tue Aug 28 13:55:11 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java Tue Aug 28 14:17:22 2012 +0200 @@ -196,7 +196,7 @@ ValueAnchorNode anchor = graph.add(new ValueAnchorNode()); assert invoke.predecessor() != null; - ValueNode anchoredReceiver = createAnchoredReceiver(graph, anchor, type, receiver); + ValueNode anchoredReceiver = createAnchoredReceiver(graph, anchor, type, receiver, true); invoke.callTarget().replaceFirstInput(receiver, anchoredReceiver); graph.addBeforeFixed(invoke.node(), objectClass); @@ -352,7 +352,8 @@ ResolvedJavaType commonType = getLeastCommonType(i); ValueNode receiver = invokeForInlining.callTarget().receiver(); - PiNode anchoredReceiver = createAnchoredReceiver(graph, node, commonType, receiver); + boolean exact = getTypeCount(i) == 1; + PiNode anchoredReceiver = createAnchoredReceiver(graph, node, commonType, receiver, exact); invokeForInlining.callTarget().replaceFirstInput(receiver, anchoredReceiver); ResolvedJavaMethod concrete = concretes.get(i); @@ -388,6 +389,16 @@ } } + private int getTypeCount(int concreteMethodIndex) { + int count = 0; + for (int i = 0; i < typesToConcretes.length; i++) { + if (typesToConcretes[i] == concreteMethodIndex) { + count++; + } + } + return count; + } + private ResolvedJavaType getLeastCommonType(int concreteMethodIndex) { ResolvedJavaType commonType = null; for (int i = 0; i < typesToConcretes.length; i++) { @@ -709,9 +720,9 @@ } } - private static PiNode createAnchoredReceiver(StructuredGraph graph, FixedNode anchor, ResolvedJavaType commonType, ValueNode receiver) { + 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, StampFactory.declaredNonNull(commonType))); + return graph.unique(new PiNode(receiver, anchor, exact ? StampFactory.exactNonNull(commonType) : StampFactory.declaredNonNull(commonType))); } private static boolean checkInvokeConditions(Invoke invoke) {
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeMap.java Tue Aug 28 13:55:11 2012 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeMap.java Tue Aug 28 14:17:22 2012 +0200 @@ -23,8 +23,7 @@ package com.oracle.graal.graph; import java.util.AbstractMap.SimpleEntry; -import java.util.Arrays; -import java.util.Iterator; +import java.util.*; import java.util.Map.Entry;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Tue Aug 28 13:55:11 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Tue Aug 28 14:17:22 2012 +0200 @@ -100,7 +100,7 @@ @Input private final NodeInputList<ValueNode> values; - @Input private final NodeInputList<VirtualObjectState> virtualObjectMappings; + @Input private final NodeInputList<EscapeObjectState> virtualObjectMappings; /** * The bytecode index to which this frame state applies. @@ -117,7 +117,7 @@ * @param stackSize size of the stack * @param rethrowException if true the VM should re-throw the exception on top of the stack when deopt'ing using this framestate */ - public FrameState(ResolvedJavaMethod method, int bci, List<ValueNode> values, int stackSize, boolean rethrowException, boolean duringCall, InliningIdentifier inliningIdentifier, List<VirtualObjectState> virtualObjectMappings) { + public FrameState(ResolvedJavaMethod method, int bci, List<ValueNode> values, int stackSize, boolean rethrowException, boolean duringCall, InliningIdentifier inliningIdentifier, List<EscapeObjectState> virtualObjectMappings) { assert stackSize >= 0; assert (bci >= 0 && method != null) || (bci < 0 && method == null && values.isEmpty()); this.method = method; @@ -137,7 +137,7 @@ * @param bci marker bci, needs to be < 0 */ public FrameState(int bci) { - this(null, bci, Collections.<ValueNode>emptyList(), 0, false, false, null, Collections.<VirtualObjectState>emptyList()); + this(null, bci, Collections.<ValueNode>emptyList(), 0, false, false, null, Collections.<EscapeObjectState>emptyList()); } public FrameState(ResolvedJavaMethod method, int bci, ValueNode[] locals, ValueNode[] stack, int stackSize, boolean rethrowException, boolean duringCall, InliningIdentifier inliningIdentifier) { @@ -199,7 +199,7 @@ return method; } - public void addVirtualObjectMapping(VirtualObjectState virtualObject) { + public void addVirtualObjectMapping(EscapeObjectState virtualObject) { virtualObjectMappings.add(virtualObject); } @@ -211,7 +211,7 @@ return virtualObjectMappings.get(i); } - public NodeInputList<VirtualObjectState> virtualObjectMappings() { + public NodeInputList<EscapeObjectState> virtualObjectMappings() { return virtualObjectMappings; } @@ -241,8 +241,8 @@ if (newOuterFrameState != null) { newOuterFrameState = newOuterFrameState.duplicateWithVirtualState(); } - ArrayList<VirtualObjectState> newVirtualMappings = new ArrayList<>(virtualObjectMappings.size()); - for (VirtualObjectState state : virtualObjectMappings) { + ArrayList<EscapeObjectState> newVirtualMappings = new ArrayList<>(virtualObjectMappings.size()); + for (EscapeObjectState state : virtualObjectMappings) { newVirtualMappings.add(state.duplicateWithVirtualState()); } FrameState other = graph().add(new FrameState(method, bci, values, stackSize, rethrowException, duringCall, inliningIdentifier, newVirtualMappings)); @@ -380,7 +380,7 @@ for (ValueNode value : values.nonNull()) { closure.apply(this, value); } - for (VirtualObjectState state : virtualObjectMappings) { + for (EscapeObjectState state : virtualObjectMappings) { state.applyToNonVirtual(closure); } if (outerFrameState() != null) { @@ -391,7 +391,7 @@ @Override public void applyToVirtual(VirtualClosure closure) { closure.apply(this); - for (VirtualObjectState state : virtualObjectMappings) { + for (EscapeObjectState state : virtualObjectMappings) { state.applyToVirtual(closure); } if (outerFrameState() != null) { @@ -407,7 +407,7 @@ if (outerFrameState() != null && outerFrameState().isPartOfThisState(state)) { return true; } - for (VirtualObjectState objectState : virtualObjectMappings) { + for (EscapeObjectState objectState : virtualObjectMappings) { if (objectState.isPartOfThisState(state)) { return true; }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Tue Aug 28 13:55:11 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Tue Aug 28 14:17:22 2012 +0200 @@ -53,6 +53,11 @@ @Override public boolean inferStamp() { + if (object().objectStamp().alwaysNull() && objectStamp().nonNull()) { + // a null value flowing into a nonNull PiNode can happen should be guarded by a type/isNull guard, but the + // compiler might see this situation before the branch is deleted + return false; + } return updateStamp(stamp().join(object().stamp())); } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Tue Aug 28 13:55:11 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Tue Aug 28 14:17:22 2012 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.extended; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -31,7 +32,7 @@ /** * Reads an {@linkplain AccessNode accessed} value. */ -public final class ReadNode extends AccessNode implements Node.IterableNodeType, LIRLowerable/*, Canonicalizable*/ { +public final class ReadNode extends AccessNode implements Node.IterableNodeType, LIRLowerable, Simplifiable/*, Canonicalizable*/ { public ReadNode(ValueNode object, LocationNode location, Stamp stamp) { super(object, location, stamp); @@ -42,7 +43,7 @@ gen.setResult(this, gen.emitLoad(gen.makeAddress(location(), object()), getNullCheck())); } - // Canonicalization disabled untill we have a solution for non-Object oops in Hotspot + // Canonicalization disabled until we have a solution for non-Object oops in Hotspot /*@Override public ValueNode canonical(CanonicalizerTool tool) { return canonicalizeRead(this, tool); @@ -64,4 +65,16 @@ } return (ValueNode) read; } + + @Override + public void simplify(SimplifierTool tool) { + if (object().isConstant() && object().asConstant().isNull()) { + FixedNode successor = next(); + tool.deleteBranch(successor); + if (isAlive()) { + replaceAtPredecessor(graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException))); + safeDelete(); + } + } + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Tue Aug 28 13:55:11 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Tue Aug 28 14:17:22 2012 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes.extended; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -30,7 +32,7 @@ /** * Writes a given {@linkplain #value() value} a {@linkplain AccessNode memory location}. */ -public final class WriteNode extends AccessNode implements StateSplit, LIRLowerable { +public final class WriteNode extends AccessNode implements StateSplit, LIRLowerable, Simplifiable { @Input private ValueNode value; @Input(notDataflow = true) private FrameState stateAfter; @@ -61,4 +63,16 @@ public void generate(LIRGeneratorTool gen) { gen.emitStore(gen.makeAddress(location(), object()), gen.operand(value()), getNullCheck()); } + + @Override + public void simplify(SimplifierTool tool) { + if (object().isConstant() && object().asConstant().isNull()) { + FixedNode successor = next(); + tool.deleteBranch(successor); + if (isAlive()) { + replaceAtPredecessor(graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException))); + safeDelete(); + } + } + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java Tue Aug 28 13:55:11 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java Tue Aug 28 14:17:22 2012 +0200 @@ -24,13 +24,14 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; /** * The {@code AccessIndexedNode} class is the base class of instructions that read or write * elements of an array. */ -public abstract class AccessIndexedNode extends AccessArrayNode { +public abstract class AccessIndexedNode extends AccessArrayNode implements Lowerable { @Input private ValueNode index; private final Kind elementType; @@ -65,4 +66,9 @@ public long leafGraphId() { return leafGraphId; } + + @Override + public void lower(LoweringTool tool) { + tool.getRuntime().lower(this, tool); + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java Tue Aug 28 13:55:11 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java Tue Aug 28 14:17:22 2012 +0200 @@ -33,7 +33,7 @@ /** * The {@code LoadIndexedNode} represents a read from an element of an array. */ -public final class LoadIndexedNode extends AccessIndexedNode implements Canonicalizable, Lowerable, Node.IterableNodeType { +public final class LoadIndexedNode extends AccessIndexedNode implements Canonicalizable, Node.IterableNodeType { /** * Creates a new LoadIndexedNode. @@ -54,11 +54,6 @@ } @Override - public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); - } - - @Override public ValueNode canonical(CanonicalizerTool tool) { MetaAccessProvider runtime = tool.runtime(); if (runtime != null && index().isConstant() && array().isConstant() && !array().isNullConstant()) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MaterializeObjectNode.java Tue Aug 28 14:17:22 2012 +0200 @@ -0,0 +1,94 @@ +/* + * 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.java; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +@NodeInfo(nameTemplate = "Materialize {p#type/s}") +public final class MaterializeObjectNode extends FixedWithNextNode implements Lowerable, Node.IterableNodeType { + + @Input private final NodeInputList<ValueNode> values; + private final ResolvedJavaType type; + private final EscapeField[] fields; + + public MaterializeObjectNode(ResolvedJavaType type, EscapeField[] fields, ValueNode[] values) { + super(StampFactory.exactNonNull(type)); + this.type = type; + this.fields = fields; + this.values = new NodeInputList<>(this, values); + } + + public ResolvedJavaType type() { + return type; + } + + public EscapeField[] getFields() { + return fields; + } + + public NodeInputList<ValueNode> getValues() { + return values; + } + + @Override + public void lower(LoweringTool tool) { + StructuredGraph graph = (StructuredGraph) graph(); + if (type.isArrayClass()) { + ResolvedJavaType element = type.componentType(); + NewArrayNode newArray; + if (element.kind() == Kind.Object) { + newArray = graph.add(new NewObjectArrayNode(element, ConstantNode.forInt(fields.length, graph))); + } else { + newArray = graph.add(new NewPrimitiveArrayNode(element, ConstantNode.forInt(fields.length, graph))); + } + this.replaceAtUsages(newArray); + graph.addAfterFixed(this, newArray); + + FixedWithNextNode position = newArray; + for (int i = 0; i < fields.length; i++) { + StoreIndexedNode store = graph.add(new StoreIndexedNode(newArray, ConstantNode.forInt(i, graph), element.kind(), values.get(i), -1)); + graph.addAfterFixed(position, store); + position = store; + } + + graph.removeFixed(this); + } else { + NewInstanceNode newInstance = graph.add(new NewInstanceNode(type)); + this.replaceAtUsages(newInstance); + graph.addAfterFixed(this, newInstance); + + FixedWithNextNode position = newInstance; + for (int i = 0; i < fields.length; i++) { + StoreFieldNode store = graph.add(new StoreFieldNode(newInstance, (ResolvedJavaField) fields[i].representation(), values.get(i), -1)); + graph.addAfterFixed(position, store); + position = store; + } + + graph.removeFixed(this); + } + } +}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java Tue Aug 28 13:55:11 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewArrayNode.java Tue Aug 28 14:17:22 2012 +0200 @@ -80,7 +80,12 @@ } public EscapeOp getEscapeOp() { - return ESCAPE; + Constant constantLength = length().asConstant(); + if (constantLength != null && constantLength.asInt() >= 0 && constantLength.asInt() < MaximumEscapeAnalysisArrayLength) { + return ESCAPE; + } else { + return null; + } } @Override @@ -110,6 +115,12 @@ } @Override + public ResolvedJavaType type(Node node) { + NewArrayNode x = (NewArrayNode) node; + return x.elementType.arrayOf(); + } + + @Override public void beforeUpdate(Node node, Node usage) { if (usage instanceof ArrayLengthNode) { ArrayLengthNode x = (ArrayLengthNode) usage;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Tue Aug 28 13:55:11 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Tue Aug 28 14:17:22 2012 +0200 @@ -67,7 +67,7 @@ } public EscapeOp getEscapeOp() { - return ESCAPE; + return instanceClass == null ? null : ESCAPE; } private static final EscapeOp ESCAPE = new EscapeOp() { @@ -89,6 +89,12 @@ } @Override + public ResolvedJavaType type(Node node) { + NewInstanceNode x = (NewInstanceNode) node; + return x.instanceClass(); + } + + @Override public EscapeField[] fields(Node node) { NewInstanceNode x = (NewInstanceNode) node; List<EscapeField> escapeFields = new ArrayList<>();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java Tue Aug 28 13:55:11 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java Tue Aug 28 14:17:22 2012 +0200 @@ -64,9 +64,4 @@ super(StampFactory.forVoid(), array, index, elementKind, leafGraphId); this.value = value; } - - @Override - public void lower(LoweringTool tool) { - tool.getRuntime().lower(this, tool); - } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/EscapeOp.java Tue Aug 28 13:55:11 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/EscapeOp.java Tue Aug 28 14:17:22 2012 +0200 @@ -101,6 +101,8 @@ public abstract EscapeField[] fields(Node node); + public abstract ResolvedJavaType type(Node node); + public void beforeUpdate(Node node, Node usage) { // IsNonNullNode and IsTypeNode should have been eliminated by the CanonicalizerPhase, but we can't rely on this if (usage instanceof IsNullNode) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/BoxedVirtualObjectNode.java Tue Aug 28 13:55:11 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/BoxedVirtualObjectNode.java Tue Aug 28 14:17:22 2012 +0200 @@ -32,8 +32,8 @@ @Input ValueNode unboxedValue; - public BoxedVirtualObjectNode(ResolvedJavaType type, ValueNode unboxedValue) { - super(type, 1); + public BoxedVirtualObjectNode(int id, ResolvedJavaType type, ValueNode unboxedValue) { + super(id, type, 1); this.unboxedValue = unboxedValue; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/EscapeObjectState.java Tue Aug 28 14:17:22 2012 +0200 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes.virtual; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; + +public abstract class EscapeObjectState extends VirtualState implements Node.IterableNodeType, LIRLowerable { + + @Input private VirtualObjectNode object; + + public VirtualObjectNode object() { + return object; + } + + public EscapeObjectState(VirtualObjectNode object) { + this.object = object; + } + + @Override + public void generate(LIRGeneratorTool generator) { + // Nothing to do, virtual object states are processed as part of the handling of StateSplit nodes. + } + + @Override + public abstract EscapeObjectState duplicateWithVirtualState(); + + @Override + public boolean isPartOfThisState(VirtualState state) { + return this == state; + } + + @Override + public void applyToVirtual(VirtualClosure closure) { + closure.apply(this); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/MaterializedObjectState.java Tue Aug 28 14:17:22 2012 +0200 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.nodes.virtual; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; + +/** + * This class encapsulated the materialized state of an escape analyzed object. + */ +public final class MaterializedObjectState extends EscapeObjectState implements Node.IterableNodeType, LIRLowerable { + + @Input private ValueNode materializedValue; + + public ValueNode materializedValue() { + return materializedValue; + } + + public MaterializedObjectState(VirtualObjectNode object, ValueNode materializedValue) { + super(object); + this.materializedValue = materializedValue; + } + + @Override + public void generate(LIRGeneratorTool generator) { + // Nothing to do, virtual object states are processed as part of the handling of StateSplit nodes. + } + + @Override + public MaterializedObjectState duplicateWithVirtualState() { + return graph().add(new MaterializedObjectState(object(), materializedValue)); + } + + @Override + public void applyToNonVirtual(NodeClosure< ? super ValueNode> closure) { + closure.apply(this, materializedValue); + } +}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java Tue Aug 28 13:55:11 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java Tue Aug 28 14:17:22 2012 +0200 @@ -30,19 +30,14 @@ @NodeInfo(nameTemplate = "VirtualObject {p#type}") public class VirtualObjectNode extends FloatingNode implements LIRLowerable { - private ResolvedJavaType type; - private EscapeField[] fields; - private int fieldsCount; + @SuppressWarnings("unused") + private final int id; + private final ResolvedJavaType type; + private final int fieldsCount; - public VirtualObjectNode(ResolvedJavaType type, EscapeField[] fields) { + public VirtualObjectNode(int id, ResolvedJavaType type, int fieldCount) { super(StampFactory.virtual()); - this.type = type; - this.fields = fields; - this.fieldsCount = fields.length; - } - - public VirtualObjectNode(ResolvedJavaType type, int fieldCount) { - super(StampFactory.virtual()); + this.id = id; this.type = type; this.fieldsCount = fieldCount; } @@ -51,10 +46,6 @@ return type; } - public EscapeField[] fields() { - return fields; - } - @Override public void generate(LIRGeneratorTool gen) { // nothing to do...
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectState.java Tue Aug 28 13:55:11 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectState.java Tue Aug 28 14:17:22 2012 +0200 @@ -31,28 +31,23 @@ /** * This class encapsulated the virtual state of an escape analyzed object. */ -public final class VirtualObjectState extends VirtualState implements Node.IterableNodeType, LIRLowerable { +public final class VirtualObjectState extends EscapeObjectState implements Node.IterableNodeType, LIRLowerable { - @Input private VirtualObjectNode object; @Input private NodeInputList<ValueNode> fieldValues; - public VirtualObjectNode object() { - return object; - } - public NodeInputList<ValueNode> fieldValues() { return fieldValues; } public VirtualObjectState(VirtualObjectNode object, ValueNode[] fieldValues) { + super(object); assert object.fieldsCount() == fieldValues.length; - this.object = object; this.fieldValues = new NodeInputList<>(this, fieldValues); } private VirtualObjectState(VirtualObjectNode object, List<ValueNode> fieldValues) { + super(object); assert object.fieldsCount() == fieldValues.size(); - this.object = object; this.fieldValues = new NodeInputList<>(this, fieldValues); } @@ -63,7 +58,7 @@ @Override public VirtualObjectState duplicateWithVirtualState() { - return graph().add(new VirtualObjectState(object, fieldValues)); + return graph().add(new VirtualObjectState(object(), fieldValues)); } @Override @@ -72,14 +67,4 @@ closure.apply(this, value); } } - - @Override - public boolean isPartOfThisState(VirtualState state) { - return this == state; - } - - @Override - public void applyToVirtual(VirtualClosure closure) { - closure.apply(this); - } }