# HG changeset patch # User Lukas Stadler # Date 1336744944 -7200 # Node ID 3f9895797ff41cbfb5a3adf28b5df9ca8712ab7d # Parent 5097f21f6c2b9649984b0db67b076e27cb63e211# Parent 8be0c73cf1184f4bac45b557150d6020b9a406b4 Merge diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Fri May 11 16:02:24 2012 +0200 @@ -173,9 +173,9 @@ new GlobalValueNumberingPhase().apply(graph); } - graph.mark(); - new LoweringPhase(runtime).apply(graph); - new CanonicalizerPhase(target, runtime, assumptions, true, null).apply(graph); + int mark = graph.getMark(); + new LoweringPhase(runtime, assumptions).apply(graph); + new CanonicalizerPhase(target, runtime, assumptions, mark, null).apply(graph); if (GraalOptions.CullFrameStates) { new CullFrameStatesPhase().apply(graph); diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java Fri May 11 16:02:24 2012 +0200 @@ -258,6 +258,13 @@ public static int InstanceOfMaxHints = 1; /** + * Use HIR lowering instead of LIR lowering for checkcast instructions. + * Only checkcasts in methods in a class whose name contains this option will be HIR lowered. + * TDOD (dnsimon) remove once HIR checkcast lowering works reliably + */ + public static String HIRLowerCheckcast; + + /** * The profiling info cache directory. */ public static String PICache = null; diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Fri May 11 16:02:24 2012 +0200 @@ -836,7 +836,7 @@ case Virtual: assert callTarget.receiver().kind() == CiKind.Object : callTarget + ": " + callTarget.targetMethod().toString(); receiver = toXirArgument(callTarget.receiver()); - snippet = xir.genInvokeVirtual(site(x.node(), callTarget.receiver()), receiver, targetMethod, x.megamorph()); + snippet = xir.genInvokeVirtual(site(x.node(), callTarget.receiver()), receiver, targetMethod, x.isMegamorphic()); break; case Interface: assert callTarget.receiver().kind() == CiKind.Object : callTarget; diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CanonicalizerPhase.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CanonicalizerPhase.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CanonicalizerPhase.java Fri May 11 16:02:24 2012 +0200 @@ -37,18 +37,22 @@ private static final DebugMetric METRIC_CANONICALIZATION_CONSIDERED_NODES = Debug.metric("CanonicalizationConsideredNodes"); private static final DebugMetric METRIC_SIMPLIFICATION_CONSIDERED_NODES = Debug.metric("SimplificationConsideredNodes"); - private boolean newNodes; + private int newNodesMark; private final CiTarget target; private final CiAssumptions assumptions; private final RiRuntime runtime; private final IsImmutablePredicate immutabilityPredicate; public CanonicalizerPhase(CiTarget target, RiRuntime runtime, CiAssumptions assumptions) { - this(target, runtime, assumptions, false, null); + this(target, runtime, assumptions, -1, null); } - public CanonicalizerPhase(CiTarget target, RiRuntime runtime, CiAssumptions assumptions, boolean newNodes, IsImmutablePredicate immutabilityPredicate) { - this.newNodes = newNodes; + /** + * @param newNodesMark if non-negative, then only the {@linkplain Graph#getNewNodes(int) new nodes} specified by + * this mark are processed otherwise all nodes in the graph are processed + */ + public CanonicalizerPhase(CiTarget target, RiRuntime runtime, CiAssumptions assumptions, int newNodesMark, IsImmutablePredicate immutabilityPredicate) { + this.newNodesMark = newNodesMark; this.target = target; this.assumptions = assumptions; this.runtime = runtime; @@ -57,9 +61,10 @@ @Override protected void run(StructuredGraph graph) { + boolean newNodes = newNodesMark >= 0; NodeWorkList nodeWorkList = graph.createNodeWorkList(!newNodes, MAX_ITERATION_PER_NODE); if (newNodes) { - nodeWorkList.addAll(graph.getNewNodes()); + nodeWorkList.addAll(graph.getNewNodes(newNodesMark)); } canonicalize(graph, nodeWorkList, runtime, target, assumptions, immutabilityPredicate); @@ -80,7 +85,7 @@ METRIC_PROCESSED_NODES.increment(); if (node instanceof Canonicalizable) { METRIC_CANONICALIZATION_CONSIDERED_NODES.increment(); - graph.mark(); + int mark = graph.getMark(); ValueNode canonical = ((Canonicalizable) node).canonical(tool); // cases: original node: // |Floating|Fixed-unconnected|Fixed-connected| @@ -132,7 +137,7 @@ } } } - nodeWorkList.addAll(graph.getNewNodes()); + nodeWorkList.addAll(graph.getNewNodes(mark)); } } else if (node instanceof Simplifiable) { Debug.log("Canonicalizer: simplifying %s", node); diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CheckCastEliminationPhase.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CheckCastEliminationPhase.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CheckCastEliminationPhase.java Fri May 11 16:02:24 2012 +0200 @@ -29,13 +29,11 @@ import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.PhiNode.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; -import com.oracle.max.cri.ci.*; import com.oracle.max.cri.ri.*; public class CheckCastEliminationPhase extends Phase { diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/InliningPhase.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/InliningPhase.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/InliningPhase.java Fri May 11 16:02:24 2012 +0200 @@ -84,10 +84,10 @@ graph.createNodeMap(); if (hints != null) { - scanInvokes((Iterable) Util.uncheckedCast(this.hints), -1, graph); + scanInvokes((Iterable) Util.uncheckedCast(this.hints), -1); } else { - scanInvokes(graph.getNodes(InvokeNode.class), 0, graph); - scanInvokes(graph.getNodes(InvokeWithExceptionNode.class), 0, graph); + scanInvokes(graph.getNodes(InvokeNode.class), 0); + scanInvokes(graph.getNodes(InvokeWithExceptionNode.class), 0); } while (!inlineCandidates.isEmpty() && graph.getNodeCount() < GraalOptions.MaximumDesiredSize) { @@ -101,14 +101,14 @@ }); if (inline) { + int mark = graph.getMark(); Iterable newNodes = null; try { info.inline(graph, runtime, this); Debug.dump(graph, "after %s", info); - // get the new nodes here, the canonicalizer phase will reset the mark - newNodes = graph.getNewNodes(); + newNodes = graph.getNewNodes(mark); if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase(target, runtime, assumptions, true, null).apply(graph); + new CanonicalizerPhase(target, runtime, assumptions, mark, null).apply(graph); } // if (GraalOptions.Intrinsify) { // new IntrinsificationPhase(runtime).apply(graph); @@ -126,7 +126,7 @@ } if (newNodes != null && info.level < GraalOptions.MaximumInlineLevel) { - scanInvokes(newNodes, info.level + 1, graph); + scanInvokes(newNodes, info.level + 1); } } } @@ -144,11 +144,10 @@ } } - private void scanInvokes(final Iterable newNodes, final int level, final StructuredGraph graph) { + private void scanInvokes(final Iterable nodes, final int level) { Debug.scope("InliningDecisions", new Runnable() { public void run() { - graph.mark(); - for (Node node : newNodes) { + for (Node node : nodes) { if (node != null) { if (node instanceof Invoke) { Invoke invoke = (Invoke) node; diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/InsertStateAfterPlaceholderPhase.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/InsertStateAfterPlaceholderPhase.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/InsertStateAfterPlaceholderPhase.java Fri May 11 16:02:24 2012 +0200 @@ -29,7 +29,7 @@ public class InsertStateAfterPlaceholderPhase extends Phase { - private static class PlaceholderNode extends FixedWithNextNode implements StateSplit, Node.IterableNodeType, LIRLowerable { + private static class PlaceholderNode extends AbstractStateSplit implements StateSplit, Node.IterableNodeType, LIRLowerable { public PlaceholderNode() { super(StampFactory.illegal()); } diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoweringPhase.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoweringPhase.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoweringPhase.java Fri May 11 16:02:24 2012 +0200 @@ -27,7 +27,9 @@ import com.oracle.graal.graph.*; import com.oracle.graal.lir.cfg.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.max.cri.ci.*; import com.oracle.max.cri.ri.*; /** @@ -36,9 +38,11 @@ public class LoweringPhase extends Phase { private final GraalRuntime runtime; + private final CiAssumptions assumptions; - public LoweringPhase(GraalRuntime runtime) { + public LoweringPhase(GraalRuntime runtime, CiAssumptions assumptions) { this.runtime = runtime; + this.assumptions = assumptions; } @Override @@ -67,10 +71,19 @@ // TODO (thomaswue): Document why this must not be called on floating nodes. throw new UnsupportedOperationException(); } + + @Override + public CiAssumptions assumptions() { + return assumptions; + } }; for (Node node : processed) { - if (node instanceof Lowerable) { - assert !(node instanceof FixedNode) || node.predecessor() == null; + if (node instanceof CheckCastNode) { + // This is a checkcast that was created while lowering some other node (e.g. StoreIndexed). + // This checkcast must now be LIR lowered. + // TODO (dnsimon) this is temp workaround that will be removed + } else if (node instanceof Lowerable) { + assert !(node instanceof FixedNode) || node.predecessor() == null : node; ((Lowerable) node).lower(loweringTool); } } @@ -135,6 +148,11 @@ activeGuards.mark(newGuard); return newGuard; } + + @Override + public CiAssumptions assumptions() { + return assumptions; + } }; // Lower the instructions of this block. diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java Fri May 11 16:02:24 2012 +0200 @@ -40,6 +40,7 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; +import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; import com.oracle.max.cri.ci.*; @@ -287,7 +288,7 @@ PhiNode exceptionObjectPhi = null; if (invoke instanceof InvokeWithExceptionNode) { InvokeWithExceptionNode invokeWithException = (InvokeWithExceptionNode) invoke; - BeginNode exceptionEdge = invokeWithException.exceptionEdge(); + DispatchBeginNode exceptionEdge = invokeWithException.exceptionEdge(); ExceptionObjectNode exceptionObject = (ExceptionObjectNode) exceptionEdge.next(); exceptionMerge = graph.add(new MergeNode()); @@ -634,7 +635,7 @@ return null; } } else { - invoke.setMegamorph(true); + invoke.setMegamorphic(true); if (optimisticOpts.inlinePolymorphicCalls() && notRecordedTypeProbability == 0 || optimisticOpts.inlineMegamorphicCalls() && notRecordedTypeProbability > 0) { // TODO (chaeubl) inlining of multiple methods should work differently // 1. check which methods can be inlined @@ -785,7 +786,7 @@ ArrayList nodes = new ArrayList<>(); ReturnNode returnNode = null; UnwindNode unwindNode = null; - BeginNode entryPointNode = inlineGraph.start(); + StartNode entryPointNode = inlineGraph.start(); FixedNode firstCFGNode = entryPointNode.next(); for (Node node : inlineGraph.getNodes()) { if (node == entryPointNode || node == entryPointNode.stateAfter()) { @@ -921,11 +922,12 @@ final StructuredGraph snippetGraph, final boolean explodeLoops, final IsImmutablePredicate immutabilityPredicate, + final CiLoweringTool tool, final Object... args) { Debug.scope("InliningSnippet", snippetGraph.method(), new Runnable() { @Override public void run() { - inlineSnippet0(runtime, replacee, anchor, snippetGraph, explodeLoops, immutabilityPredicate, args); + inlineSnippet0(runtime, replacee, anchor, snippetGraph, explodeLoops, immutabilityPredicate, tool, args); } }); } @@ -935,7 +937,10 @@ StructuredGraph snippetGraph, boolean explodeLoops, IsImmutablePredicate immutabilityPredicate, - Object... args) { + CiLoweringTool tool, Object... args) { + + Debug.dump(replacee.graph(), "Before lowering %s", replacee); + // Copy snippet graph, replacing parameters with given args in the process StructuredGraph snippetCopy = new StructuredGraph(snippetGraph.name, snippetGraph.method()); IdentityHashMap replacements = new IdentityHashMap<>(); @@ -957,7 +962,7 @@ assert localCount == args.length : "snippet argument count mismatch"; snippetCopy.addDuplicates(snippetGraph.getNodes(), replacements); if (!replacements.isEmpty()) { - new CanonicalizerPhase(null, runtime, null, false, immutabilityPredicate).apply(snippetCopy); + new CanonicalizerPhase(null, runtime, null, -1, immutabilityPredicate).apply(snippetCopy); } // Explode all loops in the snippet if requested @@ -967,19 +972,23 @@ LoopBeginNode loopBegin = loop.loopBegin(); SuperBlock wholeLoop = LoopTransformUtil.wholeLoop(loop); Debug.dump(snippetCopy, "Before exploding loop %s", loopBegin); + int peel = 0; while (!loopBegin.isDeleted()) { - snippetCopy.mark(); + int mark = snippetCopy.getMark(); LoopTransformUtil.peel(loop, wholeLoop); - new CanonicalizerPhase(null, runtime, null, true, immutabilityPredicate).apply(snippetCopy); + Debug.dump(snippetCopy, "After peel %d", peel); + new CanonicalizerPhase(null, runtime, null, mark, immutabilityPredicate).apply(snippetCopy); + peel++; } Debug.dump(snippetCopy, "After exploding loop %s", loopBegin); } + new DeadCodeEliminationPhase().apply(snippetCopy); } - // Gather the nodes in the snippets that are to be inlined + // Gather the nodes in the snippet that are to be inlined ArrayList nodes = new ArrayList<>(); ReturnNode returnNode = null; - BeginNode entryPointNode = snippetCopy.start(); + StartNode entryPointNode = snippetCopy.start(); FixedNode firstCFGNode = entryPointNode.next(); replacements.clear(); for (Node node : snippetCopy.getNodes()) { @@ -1003,21 +1012,39 @@ // Inline the gathered snippet nodes StructuredGraph graph = (StructuredGraph) replacee.graph(); + int mark = graph.getMark(); Map duplicates = graph.addDuplicates(nodes, replacements); + Debug.dump(graph, "After inlining snippet %s", snippetCopy.method()); // Remove all frame states from the inlined snippet graph. Snippets must be atomic (i.e. free // of side-effects that prevent deoptimizing to a point before the snippet). - for (Node node : duplicates.values()) { + if (tool != null) { + boolean innerLowering = false; + for (Node node : duplicates.values()) { + if (node instanceof Lowerable) { + innerLowering = true; + ((Lowerable) node).lower(tool); + + } + } + if (innerLowering) { + Debug.dump(graph, "After inner lowering"); + } + } + + for (Node node : graph.getNewNodes(mark)) { if (node instanceof StateSplit) { StateSplit stateSplit = (StateSplit) node; FrameState frameState = stateSplit.stateAfter(); - assert !stateSplit.hasSideEffect() : "snippets cannot contain side-effecting node " + node; + assert !stateSplit.hasSideEffect() : "snippets cannot contain side-effecting node " + node + "\n " + replacee.graph(); if (frameState != null) { stateSplit.setStateAfter(null); } } } + Debug.dump(graph, "After removing frame states"); + // Rewire the control flow graph around the replacee FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode); anchor.replaceAtPredecessors(firstCFGNodeDuplicate); diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Fri May 11 16:02:24 2012 +0200 @@ -45,7 +45,6 @@ private final ArrayList nodeCacheFirst; private final ArrayList nodeCacheLast; private int deletedNodeCount; - private int mark; private GraphEventLog eventLog; ArrayList usagesDropped = new ArrayList<>(); @@ -221,10 +220,10 @@ } /** - * @see #getNewNodes() + * Gets a mark that can be used with {@link #getNewNodes()}. */ - public void mark() { - this.mark = nodeIdCount(); + public int getMark() { + return nodeIdCount(); } private class NodeIterator implements Iterator { @@ -277,11 +276,10 @@ } /** - * Returns an {@link Iterable} providing all nodes added since the last {@link Graph#mark() mark}. - * @return an {@link Iterable} providing the new nodes + * Returns an {@link Iterable} providing all nodes added since the last {@link Graph#getMark() mark}. */ - public NodeIterable getNewNodes() { - final int index = this.mark; + public NodeIterable getNewNodes(int mark) { + final int index = mark; return new NodeIterable() { @Override public Iterator iterator() { diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodeIterable.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodeIterable.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodeIterable.java Fri May 11 16:02:24 2012 +0200 @@ -67,7 +67,7 @@ return count; } public boolean isEmpty() { - return count() == 0; + return !iterator().hasNext(); } public boolean isNotEmpty() { return iterator().hasNext(); diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugConfig.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugConfig.java Fri May 11 16:02:24 2012 +0200 @@ -148,8 +148,7 @@ return null; } Debug.setConfig(Debug.fixedConfig(true, true, false, false, dumpHandlers, output)); - // sync "Exception occured in scope: " with mx/sanitycheck.py::Test.__init__ - Debug.log(String.format("Exception occured in scope: %s", Debug.currentScope())); + Debug.log(String.format("Exception occurred in scope: %s", Debug.currentScope())); for (Object o : Debug.context()) { Debug.log("Context obj %s", o); if (o instanceof Graph) { diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Fri May 11 16:02:24 2012 +0200 @@ -53,7 +53,6 @@ private final Compiler compiler; private IntrinsifyArrayCopyPhase intrinsifyArrayCopy; - private LowerCheckCastPhase lowerCheckCastPhase; public final HotSpotTypePrimitive typeBoolean; public final HotSpotTypePrimitive typeChar; @@ -116,12 +115,8 @@ @Override public void run() { VMToCompilerImpl.this.intrinsifyArrayCopy = new IntrinsifyArrayCopyPhase(runtime); - VMToCompilerImpl.this.lowerCheckCastPhase = new LowerCheckCastPhase(runtime); GraalIntrinsics.installIntrinsics(runtime, runtime.getCompiler().getTarget()); - Snippets.install(runtime, runtime.getCompiler().getTarget(), new SystemSnippets()); - Snippets.install(runtime, runtime.getCompiler().getTarget(), new UnsafeSnippets()); - Snippets.install(runtime, runtime.getCompiler().getTarget(), new ArrayCopySnippets()); - Snippets.install(runtime, runtime.getCompiler().getTarget(), new CheckCastSnippets()); + runtime.installSnippets(); } }); @@ -499,7 +494,6 @@ if (GraalOptions.Intrinsify) { phasePlan.addPhase(PhasePosition.HIGH_LEVEL, intrinsifyArrayCopy); } - phasePlan.addPhase(PhasePosition.HIGH_LEVEL, lowerCheckCastPhase); return phasePlan; } diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java Fri May 11 16:02:24 2012 +0200 @@ -28,18 +28,24 @@ import java.util.*; import com.oracle.graal.compiler.*; +import com.oracle.graal.compiler.phases.*; +import com.oracle.graal.compiler.phases.CanonicalizerPhase.IsImmutablePredicate; import com.oracle.graal.compiler.target.*; +import com.oracle.graal.compiler.util.*; import com.oracle.graal.cri.*; +import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.Compiler; import com.oracle.graal.hotspot.nodes.*; +import com.oracle.graal.hotspot.snippets.*; import com.oracle.graal.hotspot.target.amd64.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.snippets.*; import com.oracle.max.cri.ci.*; import com.oracle.max.cri.ci.CiTargetMethod.Call; import com.oracle.max.cri.ci.CiTargetMethod.DataPatch; @@ -58,6 +64,7 @@ final HotSpotRegisterConfig regConfig; private final HotSpotRegisterConfig globalStubRegConfig; private final Compiler compiler; + private RiResolvedMethod checkcastSnippet; public HotSpotRuntime(HotSpotVMConfig config, Compiler compiler) { this.config = config; @@ -68,6 +75,19 @@ System.setProperty(Backend.BACKEND_CLASS_PROPERTY, HotSpotAMD64Backend.class.getName()); } + public void installSnippets() { + Snippets.install(this, compiler.getTarget(), new SystemSnippets()); + Snippets.install(this, compiler.getTarget(), new UnsafeSnippets()); + Snippets.install(this, compiler.getTarget(), new ArrayCopySnippets()); + Snippets.install(this, compiler.getTarget(), new CheckCastSnippets()); + try { + checkcastSnippet = getRiMethod(CheckCastSnippets.class.getDeclaredMethod("checkcast", Object.class, Object.class, Object[].class, boolean.class)); + } catch (NoSuchMethodException e) { + throw new GraalInternalError(e); + } + } + + @Override public int codeOffset() { return 0; @@ -330,6 +350,7 @@ CiKind elementKind = storeIndexed.elementKind(); LocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index()); ValueNode value = storeIndexed.value(); + CheckCastNode checkcast = null; ValueNode array = storeIndexed.array(); if (elementKind == CiKind.Object && !value.isNullConstant()) { // Store check! @@ -337,7 +358,7 @@ RiResolvedType elementType = array.exactType().componentType(); if (elementType.superType() != null) { ConstantNode type = ConstantNode.forCiConstant(elementType.getEncoding(Representation.ObjectHub), this, graph); - CheckCastNode checkcast = graph.add(new CheckCastNode(type, elementType, value)); + checkcast = graph.add(new CheckCastNode(type, elementType, value)); graph.addBeforeFixed(storeIndexed, checkcast); value = checkcast; } else { @@ -348,7 +369,7 @@ FloatingReadNode arrayClass = graph.unique(new FloatingReadNode(array, LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.hubOffset, graph), null, StampFactory.objectNonNull())); arrayClass.dependencies().add(guard); FloatingReadNode arrayElementKlass = graph.unique(new FloatingReadNode(arrayClass, LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.arrayClassElementOffset, graph), null, StampFactory.objectNonNull())); - CheckCastNode checkcast = graph.add(new CheckCastNode(arrayElementKlass, null, value)); + checkcast = graph.add(new CheckCastNode(arrayElementKlass, null, value)); graph.addBeforeFixed(storeIndexed, checkcast); value = checkcast; } @@ -362,6 +383,9 @@ if (elementKind == CiKind.Object && !value.isNullConstant()) { graph.addAfterFixed(memoryWrite, graph.add(new ArrayWriteBarrier(array, arrayLocation))); } + if (checkcast != null) { + checkcast.lower(tool); + } } else if (n instanceof UnsafeLoadNode) { UnsafeLoadNode load = (UnsafeLoadNode) n; assert load.kind() != CiKind.Illegal; @@ -387,6 +411,31 @@ ReadNode memoryRead = graph.add(new ReadNode(objectClassNode.object(), location, StampFactory.objectNonNull())); memoryRead.dependencies().add(tool.createGuard(graph.unique(new NullCheckNode(objectClassNode.object(), false)), RiDeoptReason.NullCheckException, RiDeoptAction.InvalidateReprofile, StructuredGraph.INVALID_GRAPH_ID)); graph.replaceFixed(objectClassNode, memoryRead); + } else if (n instanceof CheckCastNode) { + if (GraalOptions.HIRLowerCheckcast != null && graph.method() != null && graph.method().holder().name().contains(GraalOptions.HIRLowerCheckcast)) { + final Map hintHubsSet = new IdentityHashMap<>(); + IsImmutablePredicate immutabilityPredicate = new IsImmutablePredicate() { + public boolean apply(CiConstant constant) { + return hintHubsSet.containsKey(constant); + } + }; + CheckCastNode checkcast = (CheckCastNode) n; + ValueNode hub = checkcast.targetClassInstruction(); + ValueNode object = checkcast.object(); + TypeCheckHints hints = new TypeCheckHints(checkcast.targetClass(), checkcast.profile(), tool.assumptions(), GraalOptions.CheckcastMinHintHitProbability, GraalOptions.CheckcastMaxHints); + StructuredGraph snippetGraph = (StructuredGraph) checkcastSnippet.compilerStorage().get(Graph.class); + assert snippetGraph != null : CheckCastSnippets.class.getSimpleName() + " should be installed"; + HotSpotKlassOop[] hintHubs = new HotSpotKlassOop[hints.types.length]; + for (int i = 0; i < hintHubs.length; i++) { + hintHubs[i] = ((HotSpotType) hints.types[i]).klassOop(); + } + final CiConstant hintHubsConst = CiConstant.forObject(hintHubs); + hintHubsSet.put(hintHubsConst, hintHubsConst); + Debug.log("Lowering checkcast in %s: node=%s, hintsHubs=%s, exact=%b", graph, checkcast, Arrays.toString(hints.types), hints.exact); + + InliningUtil.inlineSnippet(this, checkcast, checkcast, snippetGraph, true, immutabilityPredicate, tool, hub, object, hintHubsConst, CiConstant.forBoolean(hints.exact)); + new DeadCodeEliminationPhase().apply(graph); + } } else { assert false : "Node implementing Lowerable not handled: " + n; } diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/LowerCheckCastPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/LowerCheckCastPhase.java Fri May 11 16:00:00 2012 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -/* - * 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.hotspot.snippets; - -import java.util.*; - -import com.oracle.graal.compiler.*; -import com.oracle.graal.compiler.phases.*; -import com.oracle.graal.compiler.phases.CanonicalizerPhase.IsImmutablePredicate; -import com.oracle.graal.compiler.util.*; -import com.oracle.graal.cri.*; -import com.oracle.graal.debug.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.hotspot.ri.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.java.*; -import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ri.*; -import com.oracle.max.criutils.*; - -/** - * Lowers a {@link CheckCastNode} by replacing it with the graph of a {@linkplain CheckCastSnippets checkcast snippet}. - */ -public class LowerCheckCastPhase extends Phase { - private final GraalRuntime runtime; - private final RiResolvedMethod checkcast; - - public LowerCheckCastPhase(GraalRuntime runtime) { - this.runtime = runtime; - try { - checkcast = runtime.getRiMethod(CheckCastSnippets.class.getDeclaredMethod("checkcast", Object.class, Object.class, Object[].class, boolean.class)); - } catch (NoSuchMethodException e) { - throw new GraalInternalError(e); - } - } - - @Override - protected void run(StructuredGraph graph) { - final Map hintHubsSet = new IdentityHashMap<>(); - IsImmutablePredicate immutabilityPredicate = new IsImmutablePredicate() { - public boolean apply(CiConstant constant) { - return hintHubsSet.containsKey(constant); - } - }; - for (CheckCastNode node : graph.getNodes(CheckCastNode.class)) { - ValueNode hub = node.targetClassInstruction(); - ValueNode object = node.object(); - CiAssumptions assumptions = null; - TypeCheckHints hints = new TypeCheckHints(node.targetClass(), node.profile(), assumptions, GraalOptions.CheckcastMinHintHitProbability, GraalOptions.CheckcastMaxHints); - StructuredGraph snippetGraph = (StructuredGraph) checkcast.compilerStorage().get(Graph.class); - assert snippetGraph != null : CheckCastSnippets.class.getSimpleName() + " should be installed"; - HotSpotKlassOop[] hintHubs = new HotSpotKlassOop[hints.types.length]; - for (int i = 0; i < hintHubs.length; i++) { - hintHubs[i] = ((HotSpotType) hints.types[i]).klassOop(); - } - final CiConstant hintHubsConst = CiConstant.forObject(hintHubs); - hintHubsSet.put(hintHubsConst, hintHubsConst); - Debug.log("Lowering checkcast in %s: node=%s, hintsHubs=%s, exact=%b", graph, node, Arrays.toString(hints.types), hints.exact); - - InliningUtil.inlineSnippet(runtime, node, node, snippetGraph, true, immutabilityPredicate, hub, object, hintHubsConst, CiConstant.forBoolean(hints.exact)); - } - if (!hintHubsSet.isEmpty()) { - Debug.log("Lowered %d checkcasts in %s ", hintHubsSet.size(), graph); - new DeadCodeEliminationPhase().apply(graph); - new CanonicalizerPhase(null, runtime, null, false, immutabilityPredicate).apply(graph); - } - } -} diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri May 11 16:02:24 2012 +0200 @@ -165,7 +165,7 @@ frameState.clearNonLiveLocals(blockMap.startBlock.localsLiveIn); // finish the start block - lastInstr.setStateAfter(frameState.create(0)); + ((StateSplit) lastInstr).setStateAfter(frameState.create(0)); if (blockMap.startBlock.isLoopHeader) { appendGoto(createTarget(blockMap.startBlock, frameState)); } else { @@ -241,7 +241,7 @@ return handler.catchTypeCPI() == 0; } - private BeginNode handleException(ValueNode exceptionObject, int bci) { + private DispatchBeginNode handleException(ValueNode exceptionObject, int bci) { assert bci == FrameState.BEFORE_BCI || bci == bci() : "invalid bci"; Debug.log("Creating exception dispatch edges at %d, exception object=%s, exception seen=%s", bci, exceptionObject, profilingInfo.getExceptionSeen(bci)); @@ -255,7 +255,7 @@ FrameStateBuilder dispatchState = frameState.copy(); dispatchState.clearStack(); - BeginNode dispatchBegin = currentGraph.add(new DispatchBeginNode()); + DispatchBeginNode dispatchBegin = currentGraph.add(new DispatchBeginNode()); dispatchBegin.setStateAfter(dispatchState.create(bci)); if (exceptionObject == null) { @@ -948,7 +948,7 @@ frameState.pushReturn(resultType, result); } else { - BeginNode exceptionEdge = handleException(null, bci()); + DispatchBeginNode exceptionEdge = handleException(null, bci()); InvokeWithExceptionNode invoke = currentGraph.add(new InvokeWithExceptionNode(callTarget, exceptionEdge, bci(), graphId)); ValueNode result = append(invoke); frameState.pushReturn(resultType, result); @@ -1469,9 +1469,13 @@ frameState.clearNonLiveLocals(currentBlock.localsLiveOut); } if (lastInstr instanceof StateSplit) { - StateSplit stateSplit = (StateSplit) lastInstr; - if (stateSplit.stateAfter() == null) { - stateSplit.setStateAfter(frameState.create(bci)); + if (lastInstr.getClass() == BeginNode.class) { + // BeginNodes do not need a frame state + } else { + StateSplit stateSplit = (StateSplit) lastInstr; + if (stateSplit.stateAfter() == null) { + stateSplit.setStateAfter(frameState.create(bci)); + } } } if (bci < endBCI) { diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/cri/CiLoweringTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/cri/CiLoweringTool.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/cri/CiLoweringTool.java Fri May 11 16:02:24 2012 +0200 @@ -23,11 +23,13 @@ package com.oracle.graal.cri; import com.oracle.graal.graph.*; +import com.oracle.max.cri.ci.*; import com.oracle.max.cri.ri.*; public interface CiLoweringTool { GraalRuntime getRuntime(); Node getGuardAnchor(); Node createGuard(Node condition, RiDeoptReason deoptReason, RiDeoptAction action, long leafGraphId); + CiAssumptions assumptions(); } diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractStateSplit.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractStateSplit.java Fri May 11 16:02:24 2012 +0200 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 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; + +import com.oracle.graal.nodes.type.*; + +/** + * Provides an implementation of {@link StateSplit}. + */ +public abstract class AbstractStateSplit extends FixedWithNextNode implements StateSplit { + + @Input(notDataflow = true) private FrameState stateAfter; + + public FrameState stateAfter() { + return stateAfter; + } + + public void setStateAfter(FrameState x) { + assert x == null || x.isAlive() : "frame state must be in a graph"; + updateUsages(stateAfter, x); + stateAfter = x; + } + + public boolean hasSideEffect() { + return true; + } + + public AbstractStateSplit(Stamp stamp) { + super(stamp); + } +} diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginNode.java Fri May 11 16:02:24 2012 +0200 @@ -31,7 +31,23 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; -public class BeginNode extends FixedWithNextNode implements LIRLowerable, Simplifiable, Node.IterableNodeType { +public class BeginNode extends FixedWithNextNode implements StateSplit, LIRLowerable, Simplifiable, Node.IterableNodeType { + @Input(notDataflow = true) private FrameState stateAfter; + + public FrameState stateAfter() { + return stateAfter; + } + + public void setStateAfter(FrameState x) { + assert x == null || x.isAlive() : "frame state must be in a graph"; + updateUsages(stateAfter, x); + stateAfter = x; + } + + public boolean hasSideEffect() { + return false; + } + public BeginNode() { super(StampFactory.illegal()); } diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginStateSplitNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginStateSplitNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BeginStateSplitNode.java Fri May 11 16:02:24 2012 +0200 @@ -24,6 +24,8 @@ /** * Base class for {@link BeginNode}s that are associated with a frame state. + * TODO (dnsimon) this not needed until {@link BeginNode} no longer implements {@link StateSplit} + * which is not possible until loop peeling works without requiring begin nodes to have frames states */ public abstract class BeginStateSplitNode extends BeginNode implements StateSplit { diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedWithNextNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedWithNextNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedWithNextNode.java Fri May 11 16:02:24 2012 +0200 @@ -22,43 +22,13 @@ */ package com.oracle.graal.nodes; -import java.util.*; - import com.oracle.graal.nodes.type.*; /** * Base class of all nodes that are fixed within the control flow graph and have an immediate successor. - * This class also provides an implementation of {@link StateSplit} without being a {@link StateSplit} itself. */ public abstract class FixedWithNextNode extends FixedNode { - @Input(notDataflow = true) private FrameState stateAfter; - - public FrameState stateAfter() { - return stateAfter; - } - - public void setStateAfter(FrameState x) { - assert x == null || x.isAlive() : "frame state must be in a graph"; - assert this instanceof StateSplit : getClass() + " does not implement " + StateSplit.class; - updateUsages(stateAfter, x); - stateAfter = x; - } - - // Subclasses that implement StateSplit but do not represent side-effecting instructions must override this. - public boolean hasSideEffect() { - return true; - } - - @Override - public Map getDebugProperties() { - Map debugProperties = super.getDebugProperties(); - if (stateAfter() != null) { - debugProperties.put("stateAfter", stateAfter().toString(Verbosity.Debugger)); - } - return debugProperties; - } - public FixedNode next() { assert scheduledNext() == null || scheduledNext() instanceof FixedNode : "next() cannot be used while the graph is scheduled"; return (FixedNode) scheduledNext(); diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/Invoke.java Fri May 11 16:02:24 2012 +0200 @@ -55,9 +55,12 @@ void setUseForInlining(boolean value); - boolean megamorph(); + /** + * True if this invocation is almost certainly megamorphic, false when in doubt. + */ + boolean isMegamorphic(); - void setMegamorph(boolean megamorph); + void setMegamorphic(boolean value); long leafGraphId(); } diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java Fri May 11 16:02:24 2012 +0200 @@ -34,12 +34,11 @@ /** * The {@code InvokeNode} represents all kinds of method calls. */ -public final class InvokeNode extends FixedWithNextNode implements StateSplit, Node.IterableNodeType, Invoke, LIRLowerable, MemoryCheckpoint { +public final class InvokeNode extends AbstractStateSplit implements StateSplit, Node.IterableNodeType, Invoke, LIRLowerable, MemoryCheckpoint { @Input private final MethodCallTargetNode callTarget; private final int bci; - // megamorph should only be true when the compiler is sure that the call site is megamorph, and false when in doubt - private boolean megamorph; + private boolean megamorphic; private boolean useForInlining; private final long leafGraphId; @@ -56,7 +55,7 @@ this.callTarget = callTarget; this.bci = bci; this.leafGraphId = leafGraphId; - this.megamorph = false; + this.megamorphic = false; this.useForInlining = true; } @@ -65,13 +64,13 @@ } @Override - public boolean megamorph() { - return megamorph; + public boolean isMegamorphic() { + return megamorphic; } @Override - public void setMegamorph(boolean megamorph) { - this.megamorph = megamorph; + public void setMegamorphic(boolean value) { + this.megamorphic = value; } public boolean useForInlining() { diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Fri May 11 16:02:24 2012 +0200 @@ -39,7 +39,7 @@ @Input private FrameState stateAfter; private final int bci; // megamorph should only be true when the compiler is sure that the call site is megamorph, and false when in doubt - private boolean megamorph; + private boolean megamorphic; private boolean useForInlining; private final long leafGraphId; @@ -48,17 +48,17 @@ * @param blockSuccessors * @param branchProbability */ - public InvokeWithExceptionNode(MethodCallTargetNode callTarget, BeginNode exceptionEdge, int bci, long leafGraphId) { + public InvokeWithExceptionNode(MethodCallTargetNode callTarget, DispatchBeginNode exceptionEdge, int bci, long leafGraphId) { super(callTarget.returnStamp(), new BeginNode[]{null, exceptionEdge}, new double[]{1.0, 0.0}); this.bci = bci; this.callTarget = callTarget; this.leafGraphId = leafGraphId; - this.megamorph = true; + this.megamorphic = true; this.useForInlining = true; } - public BeginNode exceptionEdge() { - return blockSuccessor(EXCEPTION_EDGE); + public DispatchBeginNode exceptionEdge() { + return (DispatchBeginNode) blockSuccessor(EXCEPTION_EDGE); } public void setExceptionEdge(BeginNode x) { @@ -78,13 +78,13 @@ } @Override - public boolean megamorph() { - return megamorph; + public boolean isMegamorphic() { + return megamorphic; } @Override - public void setMegamorph(boolean megamorph) { - this.megamorph = megamorph; + public void setMegamorphic(boolean value) { + this.megamorphic = value; } @Override diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ScheduledNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ScheduledNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ScheduledNode.java Fri May 11 16:02:24 2012 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes; +import java.util.*; + import com.oracle.graal.graph.*; public class ScheduledNode extends Node { @@ -36,4 +38,17 @@ updatePredecessors(scheduledNext, x); scheduledNext = x; } + + @Override + public Map getDebugProperties() { + Map debugProperties = super.getDebugProperties(); + if (this instanceof StateSplit) { + StateSplit stateSplit = (StateSplit) this; + if (stateSplit.stateAfter() != null) { + debugProperties.put("stateAfter", stateSplit.stateAfter().toString(Verbosity.Debugger)); + } + } + return debugProperties; + } + } diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Fri May 11 16:02:24 2012 +0200 @@ -40,7 +40,7 @@ public static final long INVALID_GRAPH_ID = -1; private static final AtomicLong uniqueGraphIds = new AtomicLong(); - private final BeginNode start; + private final StartNode start; private final RiResolvedMethod method; private final long graphId; @@ -94,7 +94,7 @@ return buf.toString(); } - public BeginNode start() { + public StartNode start() { return start; } diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java Fri May 11 16:02:24 2012 +0200 @@ -27,8 +27,11 @@ import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.calc.*; - - +/** + * 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 { @Input(notDataflow = true) private BeginNode proxyPoint; @Input private ValueNode value; diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractCallNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractCallNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractCallNode.java Fri May 11 16:02:24 2012 +0200 @@ -26,7 +26,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.type.*; -public abstract class AbstractCallNode extends FixedWithNextNode implements StateSplit, MemoryCheckpoint { +public abstract class AbstractCallNode extends AbstractStateSplit implements StateSplit, MemoryCheckpoint { @Input protected final NodeInputList arguments; diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java Fri May 11 16:02:24 2012 +0200 @@ -22,16 +22,16 @@ */ package com.oracle.graal.nodes.extended; -import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ri.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.java.MethodCallTargetNode.*; +import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.nodes.type.*; +import com.oracle.max.cri.ci.*; +import com.oracle.max.cri.ri.*; -public final class BoxNode extends FixedWithNextNode implements StateSplit, Node.IterableNodeType { +public final class BoxNode extends AbstractStateSplit implements StateSplit, Node.IterableNodeType { @Input private ValueNode source; private int bci; diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java Fri May 11 16:02:24 2012 +0200 @@ -30,7 +30,7 @@ /** * Creates a memory barrier. */ -public class MembarNode extends FixedWithNextNode implements StateSplit, LIRLowerable, MemoryCheckpoint { +public class MembarNode extends AbstractStateSplit implements StateSplit, LIRLowerable, MemoryCheckpoint { private final int barriers; diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeWriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeWriteNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeWriteNode.java Fri May 11 16:02:24 2012 +0200 @@ -27,14 +27,29 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; import com.oracle.max.cri.ci.*; -import com.oracle.graal.nodes.type.*; import com.oracle.max.cri.ri.*; public class SafeWriteNode extends SafeAccessNode implements StateSplit, Lowerable{ @Input private ValueNode value; + @Input(notDataflow = true) private FrameState stateAfter; + + public FrameState stateAfter() { + return stateAfter; + } + + public void setStateAfter(FrameState x) { + assert x == null || x.isAlive() : "frame state must be in a graph"; + updateUsages(stateAfter, x); + stateAfter = x; + } + + public boolean hasSideEffect() { + return true; + } public SafeWriteNode(ValueNode object, ValueNode value, LocationNode location, long leafGraphId) { super(object, location, StampFactory.forKind(CiKind.Void), leafGraphId); diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Fri May 11 16:02:24 2012 +0200 @@ -38,6 +38,21 @@ @Input private ValueNode value; private final int displacement; private final CiKind storeKind; + @Input(notDataflow = true) private FrameState stateAfter; + + public FrameState stateAfter() { + return stateAfter; + } + + public void setStateAfter(FrameState x) { + assert x == null || x.isAlive() : "frame state must be in a graph"; + updateUsages(stateAfter, x); + stateAfter = x; + } + + public boolean hasSideEffect() { + return true; + } public UnsafeStoreNode(ValueNode object, int displacement, ValueNode offset, ValueNode value, CiKind kind) { super(StampFactory.illegal()); diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteMemoryCheckpointNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteMemoryCheckpointNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteMemoryCheckpointNode.java Fri May 11 16:02:24 2012 +0200 @@ -27,7 +27,7 @@ import com.oracle.graal.nodes.type.*; -public final class WriteMemoryCheckpointNode extends FixedWithNextNode implements StateSplit, LIRLowerable, MemoryCheckpoint { +public final class WriteMemoryCheckpointNode extends AbstractStateSplit implements StateSplit, LIRLowerable, MemoryCheckpoint { public WriteMemoryCheckpointNode() { this(StampFactory.illegal()); diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Fri May 11 16:02:24 2012 +0200 @@ -22,14 +22,29 @@ */ package com.oracle.graal.nodes.extended; -import com.oracle.max.cri.ci.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.max.cri.ci.*; public final class WriteNode extends AccessNode implements StateSplit, LIRLowerable { @Input private ValueNode value; + @Input(notDataflow = true) private FrameState stateAfter; + + public FrameState stateAfter() { + return stateAfter; + } + + public void setStateAfter(FrameState x) { + assert x == null || x.isAlive() : "frame state must be in a graph"; + updateUsages(stateAfter, x); + stateAfter = x; + } + + public boolean hasSideEffect() { + return true; + } public ValueNode value() { return value; diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java Fri May 11 16:02:24 2012 +0200 @@ -43,7 +43,7 @@ * {@link MonitorEnterNode}. Optimization phases are free to throw {@link CiBailout} if they detect such cases. * Otherwise, they are detected during LIR construction. */ -public abstract class AccessMonitorNode extends FixedWithNextNode implements StateSplit, MemoryCheckpoint { +public abstract class AccessMonitorNode extends AbstractStateSplit implements StateSplit, MemoryCheckpoint { @Input private ValueNode object; private boolean eliminated; diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java Fri May 11 16:02:24 2012 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.java; +import com.oracle.graal.cri.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; @@ -34,7 +35,7 @@ /** * Implements a type check that results in a {@link ClassCastException} if it fails. */ -public final class CheckCastNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, Node.IterableNodeType, TypeFeedbackProvider, TypeCanonicalizable { +public final class CheckCastNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, Lowerable, Node.IterableNodeType, TypeFeedbackProvider, TypeCanonicalizable { @Input private ValueNode object; @Input private ValueNode targetClassInstruction; @@ -60,6 +61,11 @@ } @Override + public void lower(CiLoweringTool tool) { + tool.getRuntime().lower(this, tool); + } + + @Override public void generate(LIRGeneratorTool gen) { gen.visitCheckCast(this); } diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Fri May 11 16:02:24 2012 +0200 @@ -33,7 +33,7 @@ * Represents an atomic compare-and-swap operation * The result is a boolean that contains whether the value matched the expected value. */ -public class CompareAndSwapNode extends FixedWithNextNode implements StateSplit, LIRLowerable, Lowerable, MemoryCheckpoint { +public class CompareAndSwapNode extends AbstractStateSplit implements StateSplit, LIRLowerable, Lowerable, MemoryCheckpoint { @Input private ValueNode object; @Input private ValueNode offset; diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Fri May 11 16:02:24 2012 +0200 @@ -31,7 +31,7 @@ /** * The {@code ExceptionObject} instruction represents the incoming exception object to an exception handler. */ -public class ExceptionObjectNode extends FixedWithNextNode implements StateSplit, LIRLowerable, MemoryCheckpoint { +public class ExceptionObjectNode extends AbstractStateSplit implements StateSplit, LIRLowerable, MemoryCheckpoint { /** * Constructs a new ExceptionObject instruction. diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java Fri May 11 16:02:24 2012 +0200 @@ -31,7 +31,7 @@ /** * This node is used to perform the finalizer registration at the end of the java.lang.Object constructor. */ -public final class RegisterFinalizerNode extends FixedWithNextNode implements StateSplit, Canonicalizable, LIRLowerable { +public final class RegisterFinalizerNode extends AbstractStateSplit implements StateSplit, Canonicalizable, LIRLowerable { @Input private ValueNode object; diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreFieldNode.java Fri May 11 16:02:24 2012 +0200 @@ -32,6 +32,21 @@ public final class StoreFieldNode extends AccessFieldNode implements StateSplit { @Input private ValueNode value; + @Input(notDataflow = true) private FrameState stateAfter; + + public FrameState stateAfter() { + return stateAfter; + } + + public void setStateAfter(FrameState x) { + assert x == null || x.isAlive() : "frame state must be in a graph"; + updateUsages(stateAfter, x); + stateAfter = x; + } + + public boolean hasSideEffect() { + return true; + } public ValueNode value() { return value; diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/StoreIndexedNode.java Fri May 11 16:02:24 2012 +0200 @@ -22,11 +22,11 @@ */ package com.oracle.graal.nodes.java; -import com.oracle.max.cri.ci.*; import com.oracle.graal.cri.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.max.cri.ci.*; /** * The {@code StoreIndexedNode} represents a write to an array element. @@ -34,6 +34,21 @@ public final class StoreIndexedNode extends AccessIndexedNode implements StateSplit, Lowerable { @Input private ValueNode value; + @Input(notDataflow = true) private FrameState stateAfter; + + public FrameState stateAfter() { + return stateAfter; + } + + public void setStateAfter(FrameState x) { + assert x == null || x.isAlive() : "frame state must be in a graph"; + updateUsages(stateAfter, x); + stateAfter = x; + } + + public boolean hasSideEffect() { + return true; + } public ValueNode value() { return value; diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippets.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippets.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippets.java Fri May 11 16:02:24 2012 +0200 @@ -108,7 +108,7 @@ MethodCallTargetNode callTarget = invoke.callTarget(); RiResolvedMethod targetMethod = callTarget.targetMethod(); RiResolvedType holder = targetMethod.holder(); - if (holder.isSubtypeOf(runtime.getType(SnippetsInterface.class))) { + if (enclosedInSnippetsClass(holder)) { StructuredGraph targetGraph = (StructuredGraph) targetMethod.compilerStorage().get(Graph.class); if (targetGraph == null) { targetGraph = buildSnippetGraph(targetMethod, runtime, target, pool); @@ -140,6 +140,17 @@ return graph; } + + private boolean enclosedInSnippetsClass(RiResolvedType holder) { + Class enclosingClass = holder.toJava(); + while (enclosingClass != null) { + if (SnippetsInterface.class.isAssignableFrom(enclosingClass)) { + return true; + } + enclosingClass = enclosingClass.getEnclosingClass(); + } + return false; + } }); } diff -r 5097f21f6c2b -r 3f9895797ff4 graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/FloatingReadTest.java --- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/FloatingReadTest.java Fri May 11 16:00:00 2012 +0200 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/FloatingReadTest.java Fri May 11 16:02:24 2012 +0200 @@ -52,7 +52,7 @@ private void test(String snippet) { StructuredGraph graph = parse(snippet); - new LoweringPhase(runtime()).apply(graph); + new LoweringPhase(runtime(), null).apply(graph); new FloatingReadPhase().apply(graph); ReturnNode returnNode = null; diff -r 5097f21f6c2b -r 3f9895797ff4 mxtool/mx.py --- a/mxtool/mx.py Fri May 11 16:00:00 2012 +0200 +++ b/mxtool/mx.py Fri May 11 16:02:24 2012 +0200 @@ -1685,6 +1685,9 @@ if suite is None: suite = _mainSuite + def println(out, obj): + out.write(str(obj) + '\n') + updated = False for p in projects(): if p.native: @@ -1898,60 +1901,94 @@ parser.add_argument('--projects', action='store', help='comma separated projects to process (omit to process all projects)') parser.add_argument('--argfile', action='store', help='name of file containing extra javadoc options') parser.add_argument('-m', '--memory', action='store', help='-Xmx value to pass to underlying JVM') - + parser.add_argument('--wiki', action='store_true', help='generate Confluence Wiki format for package-info.java files') + parser.add_argument('--packages', action='store', help='comma separated packages to process (omit to process all packages)') + args = parser.parse_args(args) - + # build list of projects to be processed candidates = sorted_deps() if args.projects is not None: candidates = [project(name) for name in args.projects.split(',')] - + + # optionally restrict packages within a project (most useful for wiki) + packages = [] + if args.packages is not None: + packages = [name for name in args.packages.split(',')] + + # the WikiDoclet cannot see the -classpath argument passed to javadoc so we pass the + # full list of projects as an explicit argument, thereby enabling it to map classes + # to projects, which is needed to generate Wiki links to the source code. + # There is no virtue in running the doclet on dependent projects as there are + # no generated links between Wiki pages + docletArgs = [] + if args.wiki: + docDir = 'wikidoc' + toolsDir = project('com.oracle.max.tools').output_dir() + baseDir = project('com.oracle.max.base').output_dir() + dp = os.pathsep.join([toolsDir, baseDir]) + project_list = ','.join(p.name for p in sorted_deps()) + docletArgs = ['-docletpath', dp, '-doclet', 'com.oracle.max.tools.javadoc.wiki.WikiDoclet', '-projects', project_list] + else: + docDir = 'javadoc' + + def check_package_list(p): + if args.wiki: + return True + else: + return not exists(join(p.dir, docDir, 'package-list')) + def assess_candidate(p, projects): if p in projects: return False - if args.force or args.unified or not exists(join(p.dir, 'javadoc', 'package-list')): + if args.force or args.unified or check_package_list(p): projects.append(p) return True return False - + projects = [] for p in candidates: if not p.native: - deps = p.all_deps([], includeLibs=False, includeSelf=False) - for d in deps: - assess_candidate(d, projects) + if not args.wiki: + deps = p.all_deps([], includeLibs=False, includeSelf=False) + for d in deps: + assess_candidate(d, projects) if not assess_candidate(p, projects): log('[package-list file exists - skipping {0}]'.format(p.name)) - + def find_packages(sourceDirs, pkgs=set()): for sourceDir in sourceDirs: for root, _, files in os.walk(sourceDir): if len([name for name in files if name.endswith('.java')]) != 0: - pkgs.add(root[len(sourceDir) + 1:].replace('/','.')) + pkg = root[len(sourceDir) + 1:].replace('/','.') + if (len(packages) == 0) | (pkg in packages): + pkgs.add(pkg) return pkgs extraArgs = [] if args.argfile is not None: extraArgs += ['@' + args.argfile] + memory = '2g' if args.memory is not None: - extraArgs.append('-J-Xmx' + args.memory) + memory = args.memory + memory = '-J-Xmx' + memory if not args.unified: for p in projects: pkgs = find_packages(p.source_dirs(), set()) deps = p.all_deps([], includeLibs=False, includeSelf=False) - links = ['-link', 'http://docs.oracle.com/javase/6/docs/api/'] - out = join(p.dir, 'javadoc') + links = ['-link', 'http://docs.oracle.com/javase/' + str(p.javaCompliance.value) + '/docs/api/'] + out = join(p.dir, docDir) for d in deps: - depOut = join(d.dir, 'javadoc') + depOut = join(d.dir, docDir) links.append('-link') links.append(os.path.relpath(depOut, out)) cp = classpath(p.name, includeSelf=True) sp = os.pathsep.join(p.source_dirs()) - log('Generating javadoc for {0} in {1}'.format(p.name, out)) - run([java().javadoc, '-J-Xmx2g', '-classpath', cp, '-quiet', '-d', out, '-sourcepath', sp] + links + extraArgs + list(pkgs)) - log('Generated javadoc for {0} in {1}'.format(p.name, out)) + log('Generating {2} for {0} in {1}'.format(p.name, out, docDir)) + run([java().javadoc, memory, '-classpath', cp, '-quiet', '-d', out, '-sourcepath', sp] + docletArgs + links + extraArgs + list(pkgs)) + log('Generated {2} for {0} in {1}'.format(p.name, out, docDir)) else: pkgs = set() sp = [] @@ -1960,14 +1997,14 @@ find_packages(p.source_dirs(), pkgs) sp += p.source_dirs() names.append(p.name) - - links = ['-link', 'http://docs.oracle.com/javase/6/docs/api/'] - out = join(_mainSuite.dir, 'javadoc') + + links = ['-link', 'http://docs.oracle.com/javase/' + str(_java.javaCompliance.value) + '/docs/api/'] + out = join(_mainSuite.dir, docDir) cp = classpath() sp = os.pathsep.join(sp) - log('Generating javadoc for {0} in {1}'.format(', '.join(names), out)) - run([java().javadoc, '-classpath', cp, '-quiet', '-d', out, '-sourcepath', sp] + links + extraArgs + list(pkgs)) - log('Generated javadoc for {0} in {1}'.format(', '.join(names), out)) + log('Generating {2} for {0} in {1}'.format(', '.join(names), out, docDir)) + run([java().javadoc, memory, '-classpath', cp, '-quiet', '-d', out, '-sourcepath', sp] + docletArgs + links + extraArgs + list(pkgs)) + log('Generated {2} for {0} in {1}'.format(', '.join(names), out, docDir)) def javap(args): """launch javap with a -classpath option denoting all available classes