Mercurial > hg > graal-compiler
changeset 6719:67f9855dec62
Automated merge with https://lafo.ssw.uni-linz.ac.at/hg/graalvm
author | Laurent Daynes <Laurent.Daynes@oracle.com> |
---|---|
date | Thu, 15 Nov 2012 10:26:00 +0100 |
parents | 5bbe9618118e (diff) cce59a7ee92c (current diff) |
children | b62581e29024 0fc0d52013b4 |
files | |
diffstat | 42 files changed, 759 insertions(+), 414 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java Thu Nov 15 10:26:00 2012 +0100 @@ -104,7 +104,16 @@ } } + /** + * Determines if a given type can have subtypes. This analysis is purely static; no + * assumptions are made. + * + * @return true if {@code type} has no subtype(s) + */ public static boolean isFinalClass(ResolvedJavaType type) { - return Modifier.isFinal(type.getModifiers()) || (type.isArrayClass() && Modifier.isFinal(type.getComponentType().getModifiers())); + if (type.isArrayClass()) { + return isFinalClass(type.getComponentType()); + } + return Modifier.isFinal(type.getModifiers()); } }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Thu Nov 15 10:26:00 2012 +0100 @@ -116,6 +116,15 @@ return getKind().isObject() && object == null; } + /** + * Checks whether this constant is the default value for its kind (null, 0, 0.0, false). + * + * @return {@code true} if this constant is the default value for its kind + */ + public boolean isDefaultForKind() { + return object == null && primitive == 0; + } + @Override public String toString() { return getKind().getJavaName() + "[" + getKind().format(asBoxedValue()) + (getKind() != Kind.Object ? "|0x" + Long.toHexString(primitive) : "") + "]";
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Thu Nov 15 10:26:00 2012 +0100 @@ -106,6 +106,7 @@ /** * Returns the Java language modifiers for this type, as an integer. The {@link Modifier} class should be used to * decode the modifiers. Only the flags specified in the JVM specification will be included in the returned mask. + * This method is identical to {@link Class#getModifiers()} in terms of the value return for this type. */ int getModifiers();
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java Thu Nov 15 10:26:00 2012 +0100 @@ -99,7 +99,7 @@ obj.y = null; return obj; } else { - ((TestObject2) obj.x).y = null; + ((TestObject2) obj.x).y = Integer.class; ((TestObject2) obj.x).x = null; return obj.x; }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Thu Nov 15 10:26:00 2012 +0100 @@ -218,7 +218,7 @@ public LIRFrameState state() { assert lastState != null : "must have state before instruction"; - return stateFor(lastState, -1); + return stateFor(lastState, StructuredGraph.INVALID_GRAPH_ID); } public LIRFrameState state(long leafGraphId) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java Thu Nov 15 10:26:00 2012 +0100 @@ -62,7 +62,7 @@ @Override public int getModifiers() { - return accessFlags; + return javaMirror.getModifiers(); } @Override @@ -84,7 +84,7 @@ @Override public ResolvedJavaType findUniqueConcreteSubtype() { if (isArrayClass()) { - return Modifier.isFinal(getComponentType().getModifiers()) ? this : null; + return getComponentType().findUniqueConcreteSubtype() != null ? this : null; } else { ResolvedJavaType subtype = (ResolvedJavaType) HotSpotGraalRuntime.getInstance().getCompilerToVM().getUniqueConcreteSubtype(this); assert subtype == null || !subtype.isInterface();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Nov 15 10:26:00 2012 +0100 @@ -511,9 +511,6 @@ assert load.kind() != Kind.Illegal; IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, load.loadKind(), load.displacement(), load.offset(), graph, false); ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp())); - if (load.object().kind().isObject()) { - memoryRead.dependencies().add(tool.createNullCheckGuard(load.object(), StructuredGraph.INVALID_GRAPH_ID)); - } graph.replaceFixedWithFixed(load, memoryRead); } else if (n instanceof UnsafeStoreNode) { UnsafeStoreNode store = (UnsafeStoreNode) n;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypePrimitive.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypePrimitive.java Thu Nov 15 10:26:00 2012 +0100 @@ -47,7 +47,7 @@ @Override public int getModifiers() { assert kind != null && kind.toJavaClass() != null; - return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC; + return Modifier.FINAL | Modifier.PUBLIC; } @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/MonitorSnippets.java Thu Nov 15 10:26:00 2012 +0100 @@ -74,9 +74,13 @@ public static final boolean CHECK_BALANCED_MONITORS = Boolean.getBoolean("graal.monitors.checkBalanced"); @Snippet - public static void monitorenter(@Parameter("object") Object object, @ConstantParameter("trace") boolean trace) { + public static void monitorenter(@Parameter("object") Object object, @ConstantParameter("checkNull") boolean checkNull, @ConstantParameter("trace") boolean trace) { verifyOop(object); + if (checkNull && object == null) { + DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException); + } + // Load the mark word - this includes a null-check on object final Word mark = loadWordFromObject(object, markOffset()); @@ -397,7 +401,7 @@ public Templates(CodeCacheProvider runtime, boolean useFastLocking) { super(runtime, MonitorSnippets.class); - monitorenter = snippet("monitorenter", Object.class, boolean.class); + monitorenter = snippet("monitorenter", Object.class, boolean.class, boolean.class); monitorexit = snippet("monitorexit", Object.class, boolean.class); monitorenterStub = snippet("monitorenterStub", Object.class, boolean.class, boolean.class); monitorexitStub = snippet("monitorexitStub", Object.class, boolean.class); @@ -418,7 +422,7 @@ ResolvedJavaMethod method = eliminated ? monitorenterEliminated : useFastLocking ? monitorenter : monitorenterStub; boolean checkNull = !monitorenterNode.object().stamp().nonNull(); Key key = new Key(method); - if (method == monitorenterStub) { + if (method != monitorenterEliminated) { key.add("checkNull", checkNull); } if (!eliminated) {
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Thu Nov 15 10:26:00 2012 +0100 @@ -255,10 +255,11 @@ merge.setNext(next); FrameState exitState = earlyExit.stateAfter(); - FrameState newExitState = newEarlyExit.stateAfter(); FrameState state = null; if (exitState != null) { - state = exitState.duplicateWithVirtualState(); + state = exitState; + exitState = exitState.duplicateWithVirtualState(); + earlyExit.setStateAfter(exitState); merge.setStateAfter(state); } @@ -291,7 +292,7 @@ if (!merge.isPhiAtMerge(usage)) { if (usage instanceof VirtualState) { VirtualState stateUsage = (VirtualState) usage; - if (exitState.isPartOfThisState(stateUsage) || newExitState.isPartOfThisState(stateUsage)) { + if (exitState.isPartOfThisState(stateUsage)) { continue; } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java Thu Nov 15 10:26:00 2012 +0100 @@ -25,13 +25,14 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.virtual.*; /** * 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 { +public class PiNode extends FloatingNode implements LIRLowerable, Virtualizable { @Input private ValueNode object; @Input(notDataflow = true) private final FixedNode anchor; @@ -64,4 +65,12 @@ } return updateStamp(stamp().join(object().stamp())); } + + @Override + public void virtualize(VirtualizerTool tool) { + VirtualObjectNode virtual = tool.getVirtualState(object()); + if (virtual != null) { + tool.replaceWithVirtual(virtual); + } + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java Thu Nov 15 10:26:00 2012 +0100 @@ -26,14 +26,16 @@ import com.oracle.graal.graph.Node.ValueNumberable; import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.virtual.*; /** * A value proxy that is inserted in the frame state of a loop exit for any value that is * created inside the loop (i.e. was not live on entry to the loop) and is (potentially) * used after the loop. */ -public class ValueProxyNode extends FloatingNode implements Node.IterableNodeType, ValueNumberable { +public class ValueProxyNode extends FloatingNode implements Node.IterableNodeType, ValueNumberable, Canonicalizable, Virtualizable { @Input(notDataflow = true) private BeginNode proxyPoint; @Input private ValueNode value; private final PhiType type; @@ -74,4 +76,20 @@ assert proxyPoint != null; return super.verify(); } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + if (value.isConstant()) { + return value; + } + return this; + } + + @Override + public void virtualize(VirtualizerTool tool) { + VirtualObjectNode virtual = tool.getVirtualState(value()); + if (virtual != null) { + tool.replaceWithVirtual(virtual); + } + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java Thu Nov 15 10:26:00 2012 +0100 @@ -30,7 +30,7 @@ /** * An IsNullNode will be true if the supplied value is null, and false if it is non-null. */ -public final class IsNullNode extends BooleanNode implements Canonicalizable, LIRLowerable { +public final class IsNullNode extends BooleanNode implements Canonicalizable, LIRLowerable, Virtualizable { @Input private ValueNode object; @@ -73,4 +73,11 @@ } return this; } + + @Override + public void virtualize(VirtualizerTool tool) { + if (tool.getVirtualState(object()) != null || tool.getMaterializedValue(object()) != null) { + tool.replaceWithValue(ConstantNode.forBoolean(false, graph())); + } + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Thu Nov 15 10:26:00 2012 +0100 @@ -26,9 +26,10 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.virtual.*; @NodeInfo(shortName = "==") -public final class ObjectEqualsNode extends CompareNode { +public final class ObjectEqualsNode extends CompareNode implements Virtualizable { /** * Constructs a new object equality comparison node. @@ -69,4 +70,20 @@ return super.canonical(tool); } + + @Override + public void virtualize(VirtualizerTool tool) { + VirtualObjectNode virtualX = tool.getVirtualState(x()); + VirtualObjectNode virtualY = tool.getVirtualState(y()); + boolean xVirtual = virtualX != null; + boolean yVirtual = virtualY != null; + + if (xVirtual ^ yVirtual) { + // one of them is virtual: they can never be the same objects + tool.replaceWithValue(ConstantNode.forBoolean(false, graph())); + } else if (xVirtual && yVirtual) { + // both are virtual: check if they refer to the same object + tool.replaceWithValue(ConstantNode.forBoolean(virtualX == virtualY, graph())); + } + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java Thu Nov 15 10:26:00 2012 +0100 @@ -27,11 +27,12 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.virtual.*; /** * Loads an object's {@linkplain Representation#ObjectHub hub}, null-checking the object first. */ -public final class LoadHubNode extends FixedWithNextNode implements Lowerable, Canonicalizable { +public final class LoadHubNode extends FixedWithNextNode implements Lowerable, Canonicalizable, Virtualizable { @Input private ValueNode object; public ValueNode object() { @@ -75,4 +76,12 @@ @NodeIntrinsic public static native Object loadHub(Object object); + + @Override + public void virtualize(VirtualizerTool tool) { + VirtualObjectNode virtual = tool.getVirtualState(object()); + if (virtual != null) { + tool.replaceWithValue(ConstantNode.forConstant(virtual.type().getEncoding(Representation.ObjectHub), tool.getMetaAccessProvider(), graph())); + } + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Thu Nov 15 10:26:00 2012 +0100 @@ -22,7 +22,6 @@ */ 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.*; @@ -32,7 +31,7 @@ /** * Reads an {@linkplain AccessNode accessed} value. */ -public final class ReadNode extends AccessNode implements Node.IterableNodeType, LIRLowerable, Simplifiable/*, Canonicalizable*/ { +public final class ReadNode extends AccessNode implements Node.IterableNodeType, LIRLowerable /*, Canonicalizable*/ { public ReadNode(ValueNode object, ValueNode location, Stamp stamp) { super(object, location, stamp); @@ -66,18 +65,6 @@ 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(); - } - } - } - private ReadNode(ValueNode object, ValueNode location) { this(object, location, StampFactory.forNodeIntrinsic()); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Thu Nov 15 10:26:00 2012 +0100 @@ -29,6 +29,7 @@ /** * Load of a value from a location specified as an offset relative to an object. + * No null check is performed before the load. */ public class UnsafeLoadNode extends FixedWithNextNode implements Lowerable {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Thu Nov 15 10:26:00 2012 +0100 @@ -29,6 +29,7 @@ /** * Store of a value at a location specified as an offset relative to an object. + * No null check is performed before the store. */ public class UnsafeStoreNode extends FixedWithNextNode implements StateSplit, Lowerable {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java Thu Nov 15 10:26:00 2012 +0100 @@ -28,13 +28,14 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; /** * The ValueAnchor instruction keeps non-CFG (floating) nodes above a certain point in the graph. */ -public final class ValueAnchorNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, Node.IterableNodeType { +public final class ValueAnchorNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, Node.IterableNodeType, Virtualizable { public ValueAnchorNode(ValueNode... values) { super(StampFactory.dependency(), values); @@ -84,4 +85,21 @@ } return this; } + + @Override + public void virtualize(VirtualizerTool tool) { + // don't process this node if it is anchoring the return value + if (next() instanceof MonitorExitNode) { + MonitorExitNode monitorExit = (MonitorExitNode) next(); + if (monitorExit.stateAfter() != null && monitorExit.stateAfter().bci == FrameState.AFTER_BCI && monitorExit.next() instanceof ReturnNode) { + return; + } + } + for (ValueNode node : dependencies().nonNull().and(isNotA(BeginNode.class))) { + if (tool.getVirtualState(node) == null) { + return; + } + } + tool.delete(); + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Thu Nov 15 10:26:00 2012 +0100 @@ -22,8 +22,6 @@ */ 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.*; @@ -32,7 +30,7 @@ /** * Writes a given {@linkplain #value() value} a {@linkplain AccessNode memory location}. */ -public final class WriteNode extends AccessNode implements StateSplit, LIRLowerable, Simplifiable { +public final class WriteNode extends AccessNode implements StateSplit, LIRLowerable { @Input private ValueNode value; @Input(notDataflow = true) private FrameState stateAfter; @@ -64,18 +62,6 @@ 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(); - } - } - } - @NodeIntrinsic public static native void writeMemory(Object object, Object value, Object location); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java Thu Nov 15 10:26:00 2012 +0100 @@ -23,9 +23,12 @@ package com.oracle.graal.nodes.java; import com.oracle.graal.api.code.*; +import com.oracle.graal.debug.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.virtual.*; /** * The {@code AccessMonitorNode} is the base class of both monitor acquisition and release. @@ -38,12 +41,9 @@ * locking hierarchy. * <br> * The Java bytecode specification allows non-balanced locking. Graal does not handle such cases and throws a - * {@link BailoutException} instead. Detecting non-balanced monitors during bytecode parsing is difficult, since the - * node flowing into the {@link MonitorExitNode} can be a phi function hiding the node that was flowing into the - * {@link MonitorEnterNode}. Optimization phases are free to throw {@link BailoutException} if they detect such cases. - * Otherwise, they are detected during LIR construction. + * {@link BailoutException} instead during graph building. */ -public abstract class AccessMonitorNode extends AbstractStateSplit implements StateSplit, MemoryCheckpoint { +public abstract class AccessMonitorNode extends AbstractStateSplit implements StateSplit, MemoryCheckpoint, Virtualizable { @Input private ValueNode object; private boolean eliminated; @@ -69,4 +69,21 @@ super(StampFactory.forVoid()); this.object = object; } + + @Override + public void virtualize(VirtualizerTool tool) { + VirtualObjectNode virtual = tool.getVirtualState(object()); + if (virtual != null) { + Debug.log("monitor operation %s on %s\n", this, virtual); + int newLockCount = tool.getVirtualLockCount(virtual) + (this instanceof MonitorEnterNode ? 1 : -1); + tool.setVirtualLockCount(virtual, newLockCount); + tool.replaceFirstInput(object(), virtual); + tool.customAction(new Runnable() { + @Override + public void run() { + eliminate(); + } + }); + } + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java Thu Nov 15 10:26:00 2012 +0100 @@ -26,11 +26,12 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.virtual.*; /** * The {@code ArrayLength} instruction gets the length of an array. */ -public final class ArrayLengthNode extends FixedWithNextNode implements Canonicalizable, Lowerable { +public final class ArrayLengthNode extends FixedWithNextNode implements Canonicalizable, Lowerable, Virtualizable { @Input private ValueNode array; @@ -67,4 +68,13 @@ @NodeIntrinsic public static native int arrayLength(Object array); + + @Override + public void virtualize(VirtualizerTool tool) { + VirtualObjectNode virtual = tool.getVirtualState(array()); + if (virtual != null) { + assert virtual instanceof VirtualArrayNode : virtual; + tool.replaceWithValue(ConstantNode.forInt(virtual.entryCount(), graph())); + } + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Thu Nov 15 10:26:00 2012 +0100 @@ -27,11 +27,12 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.virtual.*; /** * Implements a type check against a compile-time known type. */ -public final class CheckCastNode extends FixedWithNextNode implements Canonicalizable, Lowerable, Node.IterableNodeType { +public final class CheckCastNode extends FixedWithNextNode implements Canonicalizable, Lowerable, Node.IterableNodeType, Virtualizable { @Input private ValueNode object; private final ResolvedJavaType type; @@ -97,4 +98,12 @@ public JavaTypeProfile profile() { return profile; } + + @Override + public void virtualize(VirtualizerTool tool) { + VirtualObjectNode virtual = tool.getVirtualState(object()); + if (virtual != null && virtual.type().isSubtypeOf(type())) { + tool.replaceWithVirtual(virtual); + } + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java Thu Nov 15 10:26:00 2012 +0100 @@ -27,12 +27,13 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.virtual.*; /** * The {@code LoadFieldNode} represents a read of a static or instance field. */ @NodeInfo(nameTemplate = "LoadField#{p#field/s}") -public final class LoadFieldNode extends AccessFieldNode implements Canonicalizable, Node.IterableNodeType { +public final class LoadFieldNode extends AccessFieldNode implements Canonicalizable, Node.IterableNodeType, Virtualizable { /** * Creates a new LoadFieldNode instance. @@ -69,4 +70,21 @@ } return this; } + + @Override + public void virtualize(VirtualizerTool tool) { + VirtualObjectNode virtual = tool.getVirtualState(object()); + if (virtual != null) { + int fieldIndex = ((VirtualInstanceNode) virtual).fieldIndex(field()); + if (fieldIndex != -1) { + ValueNode result = tool.getVirtualEntry(virtual, fieldIndex); + VirtualObjectNode virtualResult = tool.getVirtualState(result); + if (virtualResult != null) { + tool.replaceWithVirtual(virtualResult); + } else { + tool.replaceWithValue(result); + } + } + } + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java Thu Nov 15 10:26:00 2012 +0100 @@ -29,11 +29,12 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.virtual.*; /** * The {@code LoadIndexedNode} represents a read from an element of an array. */ -public final class LoadIndexedNode extends AccessIndexedNode implements Canonicalizable, Node.IterableNodeType { +public final class LoadIndexedNode extends AccessIndexedNode implements Canonicalizable, Node.IterableNodeType, Virtualizable { /** * Creates a new LoadIndexedNode. @@ -70,4 +71,22 @@ } return this; } + + @Override + public void virtualize(VirtualizerTool tool) { + VirtualObjectNode virtualArray = tool.getVirtualState(array()); + if (virtualArray != null) { + ValueNode indexValue = tool.getReplacedValue(index()); + int index = indexValue.isConstant() ? indexValue.asConstant().asInt() : -1; + if (index >= 0 && index < virtualArray.entryCount()) { + ValueNode result = tool.getVirtualEntry(virtualArray, index); + VirtualObjectNode virtualResult = tool.getVirtualState(result); + if (virtualResult != null) { + tool.replaceWithVirtual(virtualResult); + } else { + tool.replaceWithValue(result); + } + } + } + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java Thu Nov 15 10:26:00 2012 +0100 @@ -25,13 +25,15 @@ 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.*; +import com.oracle.graal.nodes.virtual.*; /** * The {@code StoreFieldNode} represents a write to a static or instance field. */ @NodeInfo(nameTemplate = "StoreField#{p#field/s}") -public final class StoreFieldNode extends AccessFieldNode implements StateSplit { +public final class StoreFieldNode extends AccessFieldNode implements StateSplit, Virtualizable { @Input private ValueNode value; @Input(notDataflow = true) private FrameState stateAfter; @@ -64,4 +66,16 @@ super(StampFactory.forVoid(), object, field, leafGraphId); this.value = value; } + + @Override + public void virtualize(VirtualizerTool tool) { + VirtualObjectNode virtual = tool.getVirtualState(object()); + if (virtual != null) { + int fieldIndex = ((VirtualInstanceNode) virtual).fieldIndex(field()); + if (fieldIndex != -1) { + tool.setVirtualEntry(virtual, fieldIndex, value()); + tool.delete(); + } + } + } }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java Thu Nov 15 10:26:00 2012 +0100 @@ -26,11 +26,12 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.virtual.*; /** * The {@code StoreIndexedNode} represents a write to an array element. */ -public final class StoreIndexedNode extends AccessIndexedNode implements StateSplit, Lowerable { +public final class StoreIndexedNode extends AccessIndexedNode implements StateSplit, Lowerable, Virtualizable { @Input private ValueNode value; @Input(notDataflow = true) private FrameState stateAfter; @@ -64,4 +65,17 @@ super(StampFactory.forVoid(), array, index, elementKind, leafGraphId); this.value = value; } + + @Override + public void virtualize(VirtualizerTool tool) { + VirtualObjectNode virtualArray = tool.getVirtualState(array()); + if (virtualArray != null) { + ValueNode indexValue = tool.getReplacedValue(index()); + int index = indexValue.isConstant() ? indexValue.asConstant().asInt() : -1; + if (index >= 0 && index < virtualArray.entryCount()) { + tool.setVirtualEntry(virtualArray, index, value()); + tool.delete(); + } + } + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Virtualizable.java Thu Nov 15 10:26:00 2012 +0100 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 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.spi; + +/** + * This interface allows a node to convey information about what its effect would be if some of its inputs were + * virtualized. + */ +public interface Virtualizable { + + /** + * A node class can implement this method to convey information about what its effect would be if some of its inputs + * were virtualized. All modifications must be made through the supplied tool, and not directly on the node, because + * by the time this method is called the virtualized/non-virtualized state is still speculative and might not hold + * because of loops, etc. + * + * @param tool the tool used to describe the effects of this node + */ + void virtualize(VirtualizerTool tool); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java Thu Nov 15 10:26:00 2012 +0100 @@ -0,0 +1,145 @@ +/* + * Copyright (c) 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.spi; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.virtual.*; + +/** + * This tool can be used to query the current state (normal/virtualized/re-materialized) of values and to describe the + * actions that would be taken for this state. + * + * See also {@link Virtualizable}. + */ +public interface VirtualizerTool { + + /** + * @return the {@link MetaAccessProvider} associated with the current compilation, which might be required for + * creating constants, etc. + */ + MetaAccessProvider getMetaAccessProvider(); + + // methods working on virtualized/materialized objects + + /** + * Queries the current state of the given value: if it is virtualized (thread-local and the compiler knows all + * entries) or not. + * + * @param value the value whose state should be queried. + * @return the {@link VirtualObjectNode} representing the value if it is virtualized, null otherwise. + */ + VirtualObjectNode getVirtualState(ValueNode value); + + /** + * Retrieves the entry (field or array element) with the given index in the virtualized object. + * + * @param virtual the virtualized object + * @param index the index to be queried. + * @return the entry at the given index. + */ + ValueNode getVirtualEntry(VirtualObjectNode virtual, int index); + + /** + * Sets the entry (field or array element) with the given index in the virtualized object. + * + * @param virtual the virtualized object. + * @param index the index to be set. + * @param value the new value for the given index. + */ + void setVirtualEntry(VirtualObjectNode virtual, int index, ValueNode value); + + /** + * Retrieves the lock count of the given virtualized object. + * + * @param virtual the virtualized object. + * @return the number of locks. + */ + int getVirtualLockCount(VirtualObjectNode virtual); + + /** + * Sets the lock count of the given virtualized object. + * + * @param virtual the virtualized object. + * @param lockCount the new lock count. + */ + void setVirtualLockCount(VirtualObjectNode virtual, int lockCount); + + /** + * Queries the current state of the given value: if it was materialized or not. + * + * @param value the value whose state should be queried. + * @return the materialized value (usually a MaterializeObjectNode or a {@link PhiNode}) if it was materialized, + * null otherwise. + */ + ValueNode getMaterializedValue(ValueNode value); + + // scalar replacement + + /** + * Replacements via {@link #replaceWithValue(ValueNode)} are not immediately committed. This method can be used to + * determine if a value was replaced by another one (e.g., a load field by the loaded value). + * + * @param original the original input value. + * @return the replacement value, or the original value if there is no replacement. + */ + ValueNode getReplacedValue(ValueNode original); + + // operations on the current node + + /** + * Deletes the current node and replaces it with the given virtualized object. + * + * @param virtual the virtualized object that should replace the current node. + */ + void replaceWithVirtual(VirtualObjectNode virtual); + + /** + * Deletes the current node and replaces it with the given value. + * + * @param replacement the value that should replace the current node. + */ + void replaceWithValue(ValueNode replacement); + + /** + * Deletes the current node. + */ + void delete(); + + /** + * Replaces an input of the current node. + * + * @param oldInput the old input value. + * @param replacement the new input value. + */ + void replaceFirstInput(Node oldInput, Node replacement); + + /** + * Performs a custom action on the current node. This action will only be performed when, and if, the changes are + * committed. Custom actions must not modify inputs of nodes. + * + * @param action the custom action. + */ + void customAction(Runnable action); +}
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Thu Nov 15 10:26:00 2012 +0100 @@ -68,6 +68,7 @@ // escape analysis settings public static boolean PartialEscapeAnalysis = true; + public static boolean EscapeAnalysisHistogram = ____; public static int EscapeAnalysisIterations = 2; public static String EscapeAnalyzeOnly = null;
--- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/WordTypeRewriterPhase.java Thu Nov 15 10:26:00 2012 +0100 @@ -43,6 +43,8 @@ */ public class WordTypeRewriterPhase extends Phase { + private static final String WordClassName = MetaUtil.toInternalName(Word.class.getName()); + private final Kind wordKind; private final ResolvedJavaType wordType; @@ -294,7 +296,7 @@ } public static boolean isWord(ResolvedJavaType type) { - if (type != null && type.toJava() == Word.class) { + if (type != null && type.getName().equals(WordClassName)) { return true; } return false;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/CyclicMaterializeStoreNode.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/CyclicMaterializeStoreNode.java Thu Nov 15 10:26:00 2012 +0100 @@ -28,12 +28,13 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.virtual.*; /** * The {@code StoreFieldNode} represents a write to a static or instance field. */ @NodeInfo(nameTemplate = "MaterializeStore#{p#target/s}") -public final class CyclicMaterializeStoreNode extends FixedWithNextNode implements Lowerable { +public final class CyclicMaterializeStoreNode extends FixedWithNextNode implements Lowerable, Virtualizable { @Input private ValueNode object; @Input private ValueNode value; @@ -82,4 +83,17 @@ } graph.replaceFixedWithFixed(this, store); } + + @Override + public void virtualize(VirtualizerTool tool) { + VirtualObjectNode virtual = tool.getVirtualState(object()); + if (virtual != null) { + if (virtual instanceof VirtualArrayNode) { + tool.setVirtualEntry(virtual, targetIndex(), value()); + } else { + tool.setVirtualEntry(virtual, ((VirtualInstanceNode) virtual).fieldIndex(targetField()), value()); + } + tool.delete(); + } + } }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/MaterializedObjectState.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/MaterializedObjectState.java Thu Nov 15 10:26:00 2012 +0100 @@ -30,7 +30,7 @@ /** * This class encapsulated the materialized state of an escape analyzed object. */ -public final class MaterializedObjectState extends EscapeObjectState implements Node.IterableNodeType, LIRLowerable { +public final class MaterializedObjectState extends EscapeObjectState implements Node.IterableNodeType, LIRLowerable, Node.ValueNumberable { @Input private ValueNode materializedValue;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/VirtualObjectState.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/VirtualObjectState.java Thu Nov 15 10:26:00 2012 +0100 @@ -32,7 +32,7 @@ /** * This class encapsulated the virtual state of an escape analyzed object. */ -public final class VirtualObjectState extends EscapeObjectState implements Node.IterableNodeType, LIRLowerable { +public final class VirtualObjectState extends EscapeObjectState implements Node.IterableNodeType, LIRLowerable, Node.ValueNumberable { @Input private final NodeInputList<ValueNode> fieldValues;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/BlockState.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/BlockState.java Thu Nov 15 10:26:00 2012 +0100 @@ -30,6 +30,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.graph.ReentrantBlockIterator.MergeableBlockState; import com.oracle.graal.virtual.nodes.*; @@ -88,41 +89,71 @@ throw new BailoutException("array materialized with lock"); } - MaterializeObjectNode materialize = new MaterializeObjectNode(virtual, obj.getLockCount()); - ValueNode[] values = new ValueNode[obj.getEntries().length]; - materialize.setProbability(fixed.probability()); ValueNode[] fieldState = obj.getEntries(); - obj.setMaterializedValue(materialize); - deferred.add(virtual); + + // determine if all entries are default constants + boolean allDefault = true; for (int i = 0; i < fieldState.length; i++) { - ObjectState valueObj = getObjectState(fieldState[i]); - if (valueObj != null) { - if (valueObj.isVirtual()) { - materializeChangedBefore(fixed, valueObj.virtual, deferred, deferredStores, materializeEffects); - } - if (deferred.contains(valueObj.virtual)) { - Kind fieldKind; - CyclicMaterializeStoreNode store; - if (virtual instanceof VirtualArrayNode) { - store = new CyclicMaterializeStoreNode(materialize, valueObj.getMaterializedValue(), i); - fieldKind = ((VirtualArrayNode) virtual).componentType().getKind(); - } else { - VirtualInstanceNode instanceObject = (VirtualInstanceNode) virtual; - store = new CyclicMaterializeStoreNode(materialize, valueObj.getMaterializedValue(), instanceObject.field(i)); - fieldKind = instanceObject.field(i).getType().getKind(); - } - deferredStores.addFixedNodeBefore(store, fixed); - values[i] = ConstantNode.defaultForKind(fieldKind, fixed.graph()); - } else { - values[i] = valueObj.getMaterializedValue(); - } - } else { - values[i] = fieldState[i]; + if (!fieldState[i].isConstant() || !fieldState[i].asConstant().isDefaultForKind()) { + allDefault = false; + break; } } - deferred.remove(virtual); - materializeEffects.addMaterialization(materialize, fixed, values); + if (allDefault && obj.getLockCount() == 0) { + // create an ordinary NewInstance/NewArray node if all entries are default constants + FixedWithNextNode newObject; + if (virtual instanceof VirtualInstanceNode) { + newObject = new NewInstanceNode(virtual.type(), true, false); + } else { + assert virtual instanceof VirtualArrayNode; + ResolvedJavaType element = ((VirtualArrayNode) virtual).componentType(); + if (element.getKind() == Kind.Object) { + newObject = new NewObjectArrayNode(element, ConstantNode.forInt(virtual.entryCount(), fixed.graph()), true, false); + } else { + newObject = new NewPrimitiveArrayNode(element, ConstantNode.forInt(virtual.entryCount(), fixed.graph()), true, false); + } + } + newObject.setProbability(fixed.probability()); + obj.setMaterializedValue(newObject); + materializeEffects.addFixedNodeBefore(newObject, fixed); + } else { + // some entries are not default constants - do the materialization + MaterializeObjectNode materialize = new MaterializeObjectNode(virtual, obj.getLockCount()); + ValueNode[] values = new ValueNode[obj.getEntries().length]; + materialize.setProbability(fixed.probability()); + obj.setMaterializedValue(materialize); + deferred.add(virtual); + for (int i = 0; i < fieldState.length; i++) { + ObjectState valueObj = getObjectState(fieldState[i]); + if (valueObj != null) { + if (valueObj.isVirtual()) { + materializeChangedBefore(fixed, valueObj.virtual, deferred, deferredStores, materializeEffects); + } + if (deferred.contains(valueObj.virtual)) { + Kind fieldKind; + CyclicMaterializeStoreNode store; + if (virtual instanceof VirtualArrayNode) { + store = new CyclicMaterializeStoreNode(materialize, valueObj.getMaterializedValue(), i); + fieldKind = ((VirtualArrayNode) virtual).componentType().getKind(); + } else { + VirtualInstanceNode instanceObject = (VirtualInstanceNode) virtual; + store = new CyclicMaterializeStoreNode(materialize, valueObj.getMaterializedValue(), instanceObject.field(i)); + fieldKind = instanceObject.field(i).getType().getKind(); + } + deferredStores.addFixedNodeBefore(store, fixed); + values[i] = ConstantNode.defaultForKind(fieldKind, fixed.graph()); + } else { + values[i] = valueObj.getMaterializedValue(); + } + } else { + values[i] = fieldState[i]; + } + } + deferred.remove(virtual); + + materializeEffects.addMaterialization(materialize, fixed, values); + } } void addAndMarkAlias(VirtualObjectNode virtual, ValueNode node, NodeBitMap usages) {
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java Thu Nov 15 10:26:00 2012 +0100 @@ -27,8 +27,8 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.virtual.*; +import com.oracle.graal.phases.common.*; import com.oracle.graal.virtual.nodes.*; public class GraphEffectList extends EffectList { @@ -214,31 +214,13 @@ } /** - * Virtualizes a monitor access by calling its {@link AccessMonitorNode#eliminate()} method. - * - * @param node The monitor access that should be virtualized. - */ - public void eliminateMonitor(final AccessMonitorNode node) { - add(new Effect() { - - @Override - public String name() { - return "eliminateMonitor"; - } - - @Override - public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { - assert node.isAlive() && node.object().isAlive() && (node.object() instanceof VirtualObjectNode); - node.eliminate(); - } - }); - } - - /** - * Replaces the given node at its usages without deleting it. + * Replaces the given node at its usages without deleting it. If the current node is a fixed node it will be + * disconnected from the control flow, so that it will be deleted by a subsequent {@link DeadCodeEliminationPhase} * * @param node The node to be replaced. - * @param replacement The node that should replace the original value. + * @param replacement The node that should replace the original value. If the replacement is a non-connected + * {@link FixedWithNextNode} it will be added to the control flow. + * */ public void replaceAtUsages(final ValueNode node, final ValueNode replacement) { add(new Effect() { @@ -251,7 +233,17 @@ @Override public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { assert node.isAlive() && replacement.isAlive(); + if (replacement instanceof FixedWithNextNode && ((FixedWithNextNode) replacement).next() == null) { + assert node instanceof FixedNode; + graph.addBeforeFixed((FixedNode) node, (FixedWithNextNode) replacement); + } node.replaceAtUsages(replacement); + if (node instanceof FixedWithNextNode) { + FixedNode next = ((FixedWithNextNode) node).next(); + ((FixedWithNextNode) node).setNext(null); + node.replaceAtPredecessor(next); + obsoleteNodes.add(node); + } } }); } @@ -263,7 +255,7 @@ * @param oldInput The value to look for. * @param newInput The value to replace with. */ - public void replaceFirstInput(final Node node, final ValueNode oldInput, final ValueNode newInput) { + public void replaceFirstInput(final Node node, final Node oldInput, final Node newInput) { add(new Effect() { @Override @@ -283,4 +275,24 @@ } }); } + + /** + * Performs a custom action. + * + * @param action The action that should be performed when the effects are applied. + */ + public void customAction(final Runnable action) { + add(new Effect() { + + @Override + public String name() { + return "customAction"; + } + + @Override + public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) { + action.run(); + } + }); + } }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java Thu Nov 15 10:26:00 2012 +0100 @@ -100,12 +100,8 @@ return lockCount; } - public void incLockCount() { - lockCount++; - } - - public void decLockCount() { - lockCount--; + public void setLockCount(int lockCount) { + this.lockCount = lockCount; } @Override
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java Thu Nov 15 10:26:00 2012 +0100 @@ -157,10 +157,10 @@ boolean success = true; for (Node node : obsoleteNodes) { if (flood.isMarked(node)) { - trace("offending node path:"); + error("offending node path:"); Node current = node; while (current != null) { - trace(current.toString()); + error(current.toString()); current = path.get(current); if (current != null && current instanceof FixedNode && !obsoleteNodes.contains(current)) { break;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Thu Nov 15 10:25:46 2012 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Thu Nov 15 10:26:00 2012 +0100 @@ -25,20 +25,19 @@ import static com.oracle.graal.virtual.phases.ea.PartialEscapeAnalysisPhase.*; import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.meta.ResolvedJavaType.Representation; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.VirtualState.NodeClosure; -import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.cfg.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.virtual.*; +import com.oracle.graal.phases.*; import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure; import com.oracle.graal.phases.graph.ReentrantBlockIterator.LoopInfo; @@ -47,21 +46,36 @@ class PartialEscapeClosure extends BlockIteratorClosure<BlockState> { + public static final ConcurrentHashMap<Class<? extends Node>, AtomicLong> materializeReasons = new ConcurrentHashMap<>(); + + static { + if (GraalOptions.EscapeAnalysisHistogram) { + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + for (Map.Entry<Class<? extends Node>, AtomicLong> entry : materializeReasons.entrySet()) { + System.out.println(entry.getKey() + ": " + entry.getValue()); + } + } + }); + } + } private static final DebugMetric metricAllocationRemoved = Debug.metric("AllocationRemoved "); + private final NodeBitMap usages; + private final SchedulePhase schedule; + private final GraphEffectList effects = new GraphEffectList(); private final HashSet<VirtualObjectNode> reusedVirtualObjects = new HashSet<>(); private int virtualIds = 0; - private final NodeBitMap usages; - private final SchedulePhase schedule; - private final MetaAccessProvider runtime; + private final VirtualizerToolImpl tool; - public PartialEscapeClosure(NodeBitMap usages, SchedulePhase schedule, MetaAccessProvider runtime) { + public PartialEscapeClosure(NodeBitMap usages, SchedulePhase schedule, MetaAccessProvider metaAccess) { this.usages = usages; this.schedule = schedule; - this.runtime = runtime; + tool = new VirtualizerToolImpl(effects, usages, metaAccess); } public GraphEffectList getEffects() { @@ -118,265 +132,16 @@ trace(")\n end state: %s\n", state); } + private void processNode(final ValueNode node, FixedNode insertBefore, final BlockState state) { - boolean usageFound = false; - if (node instanceof PiNode || node instanceof ValueProxyNode) { - ValueNode value = node instanceof PiNode ? ((PiNode) node).object() : ((ValueProxyNode) node).value(); - ObjectState obj = state.getObjectState(value); - if (obj != null) { - if (obj.isVirtual()) { - state.addAndMarkAlias(obj.virtual, node, usages); - } else { - effects.replaceFirstInput(node, value, obj.getMaterializedValue()); - } - usageFound = true; - } - } else if (node instanceof CheckCastNode) { - CheckCastNode x = (CheckCastNode) node; - ObjectState obj = state.getObjectState(x.object()); - if (obj != null) { - if (obj.isVirtual()) { - if (obj.virtual.type().isSubtypeOf(x.type())) { - state.addAndMarkAlias(obj.virtual, x, usages); - effects.deleteFixedNode(x); - } else { - replaceWithMaterialized(x.object(), x, state, obj); - } - } else { - effects.replaceFirstInput(x, x.object(), obj.getMaterializedValue()); - } - usageFound = true; - } - } else if (node instanceof IsNullNode) { - IsNullNode x = (IsNullNode) node; - if (state.getObjectState(x.object()) != null) { - replaceAtUsages(state, x, ConstantNode.forBoolean(false, node.graph())); - usageFound = true; - } - } else if (node instanceof AccessMonitorNode) { - AccessMonitorNode x = (AccessMonitorNode) node; - ObjectState obj = state.getObjectState(x.object()); - if (obj != null) { - Debug.log("monitor operation %s on %s\n", x, obj.virtual); - if (node instanceof MonitorEnterNode) { - obj.incLockCount(); - } else { - assert node instanceof MonitorExitNode; - obj.decLockCount(); - } - if (obj.isVirtual()) { - effects.replaceFirstInput(node, x.object(), obj.virtual); - effects.eliminateMonitor(x); - } else { - effects.replaceFirstInput(node, x.object(), obj.getMaterializedValue()); - } - usageFound = true; - } - } else if (node instanceof CyclicMaterializeStoreNode) { - CyclicMaterializeStoreNode x = (CyclicMaterializeStoreNode) node; - ObjectState obj = state.getObjectState(x.object()); - if (obj != null) { - if (obj.virtual instanceof VirtualArrayNode) { - obj.setEntry(x.targetIndex(), x.value()); - } else { - VirtualInstanceNode instance = (VirtualInstanceNode) obj.virtual; - obj.setEntry(instance.fieldIndex(x.targetField()), x.value()); - } - effects.deleteFixedNode(x); - usageFound = true; - } - } else if (node instanceof LoadFieldNode) { - LoadFieldNode x = (LoadFieldNode) node; - ObjectState obj = state.getObjectState(x.object()); - if (obj != null) { - VirtualInstanceNode virtual = (VirtualInstanceNode) obj.virtual; - int fieldIndex = virtual.fieldIndex(x.field()); - if (fieldIndex == -1) { - // the field does not exist in the virtual object - ensureMaterialized(state, obj, x); - } - if (obj.isVirtual()) { - ValueNode result = obj.getEntry(fieldIndex); - ObjectState resultObj = state.getObjectState(result); - if (resultObj != null) { - state.addAndMarkAlias(resultObj.virtual, x, usages); - } else { - replaceAtUsages(state, x, result); - } - effects.deleteFixedNode(x); - } else { - effects.replaceFirstInput(x, x.object(), obj.getMaterializedValue()); - } - usageFound = true; - } - } else if (node instanceof StoreFieldNode) { - StoreFieldNode x = (StoreFieldNode) node; - ValueNode object = x.object(); - ValueNode value = x.value(); - ObjectState obj = state.getObjectState(object); - if (obj != null) { - VirtualInstanceNode virtual = (VirtualInstanceNode) obj.virtual; - int fieldIndex = virtual.fieldIndex(x.field()); - if (fieldIndex == -1) { - // the field does not exist in the virtual object - ensureMaterialized(state, obj, x); - } - if (obj.isVirtual()) { - obj.setEntry(fieldIndex, state.getScalarAlias(value)); - effects.deleteFixedNode(x); - } else { - effects.replaceFirstInput(x, object, obj.getMaterializedValue()); - ObjectState valueObj = state.getObjectState(value); - if (valueObj != null) { - replaceWithMaterialized(value, x, state, valueObj); - } - } - usageFound = true; - } else { - ObjectState valueObj = state.getObjectState(value); - if (valueObj != null) { - replaceWithMaterialized(value, x, state, valueObj); - usageFound = true; - } - } - } else if (node instanceof LoadIndexedNode) { - LoadIndexedNode x = (LoadIndexedNode) node; - ValueNode array = x.array(); - ObjectState arrayObj = state.getObjectState(array); - if (arrayObj != null) { - if (arrayObj.isVirtual()) { - ValueNode indexValue = state.getScalarAlias(x.index()); - int index = indexValue.isConstant() ? indexValue.asConstant().asInt() : -1; - if (index < 0 || index >= arrayObj.getEntries().length) { - // out of bounds or not constant - replaceWithMaterialized(array, x, state, arrayObj); - } else { - ValueNode result = arrayObj.getEntry(index); - ObjectState resultObj = state.getObjectState(result); - if (resultObj != null) { - state.addAndMarkAlias(resultObj.virtual, x, usages); - } else { - replaceAtUsages(state, x, result); - } - effects.deleteFixedNode(x); - } - } else { - effects.replaceFirstInput(x, array, arrayObj.getMaterializedValue()); - } - usageFound = true; - } - } else if (node instanceof StoreIndexedNode) { - StoreIndexedNode x = (StoreIndexedNode) node; - ValueNode array = x.array(); - ValueNode value = x.value(); - ObjectState arrayObj = state.getObjectState(array); - ObjectState valueObj = state.getObjectState(value); - - if (arrayObj != null) { - if (arrayObj.isVirtual()) { - ValueNode indexValue = state.getScalarAlias(x.index()); - int index = indexValue.isConstant() ? indexValue.asConstant().asInt() : -1; - if (index < 0 || index >= arrayObj.getEntries().length) { - // out of bounds or not constant - replaceWithMaterialized(array, x, state, arrayObj); - if (valueObj != null) { - replaceWithMaterialized(value, x, state, valueObj); - } - } else { - arrayObj.setEntry(index, state.getScalarAlias(value)); - effects.deleteFixedNode(x); - } - } else { - effects.replaceFirstInput(x, array, arrayObj.getMaterializedValue()); - if (valueObj != null) { - replaceWithMaterialized(value, x, state, valueObj); - } - } - usageFound = true; - } else { - if (valueObj != null) { - replaceWithMaterialized(value, x, state, valueObj); - usageFound = true; - } - } - } else if (node instanceof RegisterFinalizerNode) { - RegisterFinalizerNode x = (RegisterFinalizerNode) node; - ObjectState obj = state.getObjectState(x.object()); - if (obj != null) { - replaceWithMaterialized(x.object(), x, state, obj); - usageFound = true; - } - } else if (node instanceof ArrayLengthNode) { - ArrayLengthNode x = (ArrayLengthNode) node; - ObjectState obj = state.getObjectState(x.array()); - if (obj != null) { - replaceAtUsages(state, x, ConstantNode.forInt(((VirtualArrayNode) obj.virtual).entryCount(), node.graph())); - effects.deleteFixedNode(x); - usageFound = true; - } - } else if (node instanceof LoadHubNode) { - LoadHubNode x = (LoadHubNode) node; - ObjectState obj = state.getObjectState(x.object()); - if (obj != null) { - replaceAtUsages(state, x, ConstantNode.forConstant(obj.virtual.type().getEncoding(Representation.ObjectHub), runtime, node.graph())); - effects.deleteFixedNode(x); - usageFound = true; - } - } else if (node instanceof ReturnNode) { - ReturnNode x = (ReturnNode) node; - ObjectState obj = state.getObjectState(x.result()); - if (obj != null) { - replaceWithMaterialized(x.result(), x, state, obj); - usageFound = true; - } - } else if (node instanceof MethodCallTargetNode) { - for (ValueNode argument : ((MethodCallTargetNode) node).arguments()) { - ObjectState obj = state.getObjectState(argument); - if (obj != null) { - replaceWithMaterialized(argument, node, insertBefore, state, obj); - usageFound = true; - } - } - } else if (node instanceof ObjectEqualsNode) { - ObjectEqualsNode x = (ObjectEqualsNode) node; - ObjectState xObj = state.getObjectState(x.x()); - ObjectState yObj = state.getObjectState(x.y()); - boolean xVirtual = xObj != null && xObj.isVirtual(); - boolean yVirtual = yObj != null && yObj.isVirtual(); - - if (xVirtual ^ yVirtual) { - // one of them is virtual: they can never be the same objects - replaceAtUsages(state, x, ConstantNode.forBoolean(false, node.graph())); - usageFound = true; - } else if (xVirtual && yVirtual) { - // both are virtual: check if they refer to the same object - replaceAtUsages(state, x, ConstantNode.forBoolean(xObj == yObj, node.graph())); - usageFound = true; - } else { - if (xObj != null || yObj != null) { - if (xObj != null) { - assert !xObj.isVirtual(); - effects.replaceFirstInput(x, x.x(), xObj.getMaterializedValue()); - } - if (yObj != null) { - assert !yObj.isVirtual(); - effects.replaceFirstInput(x, x.y(), yObj.getMaterializedValue()); - } - usageFound = true; - } - } - } else if (node instanceof MergeNode) { - usageFound = true; - } else if (node instanceof UnsafeLoadNode || node instanceof UnsafeStoreNode || node instanceof CompareAndSwapNode || node instanceof SafeReadNode) { - for (ValueNode input : node.inputs().filter(ValueNode.class)) { - ObjectState obj = state.getObjectState(input); - if (obj != null) { - replaceWithMaterialized(input, node, insertBefore, state, obj); - usageFound = true; - } - } + tool.reset(state, node); + if (node instanceof Virtualizable) { + ((Virtualizable) node).virtualize(tool); } - if (node.isAlive() && node instanceof StateSplit) { + if (tool.isDeleted()) { + return; + } + if (node instanceof StateSplit) { StateSplit split = (StateSplit) node; FrameState stateAfter = split.stateAfter(); if (stateAfter != null) { @@ -449,25 +214,27 @@ effects.addVirtualMapping(stateAfter, v, reusedVirtualObjects); } } - usageFound = true; + } + if (tool.isCustomAction()) { + return; } - if (!usageFound) { - for (ValueNode input : node.inputs().filter(ValueNode.class)) { - ObjectState obj = state.getObjectState(input); - if (obj != null) { - replaceWithMaterialized(input, node, insertBefore, state, obj); - usageFound = true; + for (ValueNode input : node.inputs().filter(ValueNode.class)) { + ObjectState obj = state.getObjectState(input); + if (obj != null) { + trace("replacing input %s at %s: %s", input, node, obj); + if (GraalOptions.EscapeAnalysisHistogram && obj.isVirtual()) { + AtomicLong counter = materializeReasons.get(node.getClass()); + if (counter == null) { + counter = new AtomicLong(); + materializeReasons.put(node.getClass(), counter); + } + counter.incrementAndGet(); } + replaceWithMaterialized(input, node, insertBefore, state, obj); } - Debug.log("unexpected usage of %s: %s\n", node, node.inputs().snapshot()); } } - private void replaceAtUsages(final BlockState state, ValueNode x, ValueNode value) { - effects.replaceAtUsages(x, value); - state.addScalarAlias(x, value); - } - private void ensureMaterialized(BlockState state, ObjectState obj, FixedNode materializeBefore) { assert obj != null; if (obj.isVirtual()) { @@ -476,11 +243,6 @@ assert !obj.isVirtual(); } - private void replaceWithMaterialized(ValueNode value, FixedNode usage, BlockState state, ObjectState obj) { - ensureMaterialized(state, obj, usage); - effects.replaceFirstInput(usage, value, obj.getMaterializedValue()); - } - private void replaceWithMaterialized(ValueNode value, Node usage, FixedNode materializeBefore, BlockState state, ObjectState obj) { ensureMaterialized(state, obj, materializeBefore); effects.replaceFirstInput(usage, value, obj.getMaterializedValue());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java Thu Nov 15 10:26:00 2012 +0100 @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2011, 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.virtual.phases.ea; + +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.virtual.*; + +class VirtualizerToolImpl implements VirtualizerTool { + + private final GraphEffectList effects; + private final NodeBitMap usages; + private final MetaAccessProvider metaAccess; + + VirtualizerToolImpl(GraphEffectList effects, NodeBitMap usages, MetaAccessProvider metaAccess) { + this.effects = effects; + this.usages = usages; + this.metaAccess = metaAccess; + } + + private boolean deleted; + private boolean customAction; + private BlockState state; + private ValueNode current; + + @Override + public MetaAccessProvider getMetaAccessProvider() { + return metaAccess; + } + + public void reset(BlockState newState, ValueNode newCurrent) { + deleted = false; + customAction = false; + this.state = newState; + this.current = newCurrent; + } + + public boolean isDeleted() { + return deleted; + } + + public boolean isCustomAction() { + return customAction; + } + + @Override + public VirtualObjectNode getVirtualState(ValueNode value) { + ObjectState obj = state.getObjectState(value); + return obj != null && obj.isVirtual() ? obj.virtual : null; + } + + @Override + public ValueNode getVirtualEntry(VirtualObjectNode virtual, int index) { + ObjectState obj = state.getObjectState(virtual); + assert obj != null && obj.isVirtual() : "not virtual: " + obj; + ValueNode result = obj.getEntry(index); + ValueNode materialized = getMaterializedValue(result); + return materialized != null ? materialized : result; + } + + @Override + public void setVirtualEntry(VirtualObjectNode virtual, int index, ValueNode value) { + ObjectState obj = state.getObjectState(virtual); + assert obj != null && obj.isVirtual() : "not virtual: " + obj; + if (getVirtualState(value) == null) { + ValueNode materialized = getMaterializedValue(value); + if (materialized != null) { + obj.setEntry(index, materialized); + } else { + obj.setEntry(index, getReplacedValue(value)); + } + } else { + obj.setEntry(index, value); + } + } + + @Override + public int getVirtualLockCount(VirtualObjectNode virtual) { + ObjectState obj = state.getObjectState(virtual); + assert obj != null && obj.isVirtual() : "not virtual: " + obj; + return obj.getLockCount(); + } + + @Override + public void setVirtualLockCount(VirtualObjectNode virtual, int lockCount) { + ObjectState obj = state.getObjectState(virtual); + assert obj != null && obj.isVirtual() : "not virtual: " + obj; + obj.setLockCount(lockCount); + } + + @Override + public ValueNode getMaterializedValue(ValueNode value) { + ObjectState obj = state.getObjectState(value); + return obj != null && !obj.isVirtual() ? obj.getMaterializedValue() : null; + } + + @Override + public ValueNode getReplacedValue(ValueNode original) { + return state.getScalarAlias(original); + } + + @Override + public void replaceWithVirtual(VirtualObjectNode virtual) { + state.addAndMarkAlias(virtual, current, usages); + if (current instanceof FixedWithNextNode) { + effects.deleteFixedNode((FixedWithNextNode) current); + } + deleted = true; + } + + @Override + public void replaceWithValue(ValueNode replacement) { + effects.replaceAtUsages(current, state.getScalarAlias(replacement)); + state.addScalarAlias(current, replacement); + deleted = true; + } + + @Override + public void delete() { + assert current instanceof FixedWithNextNode; + effects.deleteFixedNode((FixedWithNextNode) current); + deleted = true; + } + + @Override + public void replaceFirstInput(Node oldInput, Node replacement) { + effects.replaceFirstInput(current, oldInput, replacement); + } + + @Override + public void customAction(Runnable action) { + effects.customAction(action); + customAction = true; + } +}
--- a/hotspot/.project Thu Nov 15 10:25:46 2012 +0100 +++ b/hotspot/.project Thu Nov 15 10:26:00 2012 +0100 @@ -106,11 +106,21 @@ <locationURI>WORKSPACE_LOC/make</locationURI> </link> <link> + <name>bsd</name> + <type>2</type> + <locationURI>PARENT-1-PROJECT_LOC/src/os/bsd/vm</locationURI> + </link> + <link> <name>linux</name> <type>2</type> <locationURI>PARENT-1-PROJECT_LOC/src/os/linux/vm</locationURI> </link> <link> + <name>bsd_x86</name> + <type>2</type> + <locationURI>PARENT-1-PROJECT_LOC/src/os_cpu/bsd_x86/vm</locationURI> + </link> + <link> <name>linux_x86</name> <type>2</type> <locationURI>PARENT-1-PROJECT_LOC/src/os_cpu/linux_x86/vm</locationURI>
--- a/src/share/vm/graal/graalCompilerToVM.cpp Thu Nov 15 10:25:46 2012 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Thu Nov 15 10:26:00 2012 +0100 @@ -752,8 +752,8 @@ set_long(env, config, "arithmeticCosStub", VmIds::addStub(CAST_FROM_FN_PTR(address, SharedRuntime::dcos))); set_long(env, config, "arithmeticTanStub", VmIds::addStub(CAST_FROM_FN_PTR(address, SharedRuntime::dtan))); set_long(env, config, "logPrimitiveStub", VmIds::addStub(Runtime1::entry_for(Runtime1::graal_log_primitive_id))); - set_long(env, config, "logObjectStub", VmIds::addStub(Runtime1::entry_for(Runtime1::graal_log_printf_id))); - set_long(env, config, "logPrintfStub", VmIds::addStub(Runtime1::entry_for(Runtime1::graal_log_object_id))); + set_long(env, config, "logObjectStub", VmIds::addStub(Runtime1::entry_for(Runtime1::graal_log_object_id))); + set_long(env, config, "logPrintfStub", VmIds::addStub(Runtime1::entry_for(Runtime1::graal_log_printf_id))); BarrierSet* bs = Universe::heap()->barrier_set();