# HG changeset patch # User Christian Humer # Date 1414429425 -3600 # Node ID 881aa0ed39041104d1827fc5777d4891ffae4394 # Parent 35639ec046d7eea7e438d905d79a36f2071e14ba Truffle: refactor TraceTruffleSplitting into separate class. diff -r 35639ec046d7 -r 881aa0ed3904 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultTruffleSplittingStrategyNew.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultTruffleSplittingStrategyNew.java Mon Oct 27 17:37:45 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/DefaultTruffleSplittingStrategyNew.java Mon Oct 27 18:03:45 2014 +0100 @@ -26,10 +26,8 @@ import com.oracle.truffle.api.*; import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.NodeUtil.NodeCountFilter; public class DefaultTruffleSplittingStrategyNew implements TruffleSplittingStrategy { - private static int splitChangeCount; private final int splitStart; private final OptimizedDirectCallNode call; @@ -113,7 +111,6 @@ Map profiles = target.getSplitVersions(); OptimizedCallTarget newTarget = currentTarget; - boolean split = false; if (!currentTarget.getArgumentStamp().equals(newProfile)) { if (target.getArgumentStamp().equals(newProfile)) { // the original target is compatible again. @@ -133,47 +130,16 @@ // in case no compatible target was found we need to split newTarget = target.cloneUninitialized(); profiles.put(newProfile, newTarget); - split = true; } } } call.installSplitCallTarget(newTarget); - if (split && TruffleCompilerOptions.TraceTruffleSplitting.getValue()) { - traceSplit(currentTarget.getSourceCallTarget() != null ? oldProfile : currentTarget.getArgumentStamp(), newProfile); - } - cleanup(currentTarget); return newTarget; } - private void traceSplit(TruffleStamp oldStamp, TruffleStamp newStamp) { - OptimizedCallTarget callTarget = call.getCallTarget(); - Map splitTargets = callTarget.getSplitVersions(); - String label = String.format("split %3s-%-4s-%-4s ", splitChangeCount++, call.getCurrentCallTarget().getCloneIndex(), call.getCallCount()); - OptimizedCallTargetLog.log(0, label, callTarget.toString(), callTarget.getDebugProperties()); - logProfile(callTarget.getArgumentStamp(), callTarget, oldStamp, newStamp); - for (TruffleStamp profile : splitTargets.keySet()) { - logProfile(profile, splitTargets.get(profile), oldStamp, newStamp); - } - } - - private static void logProfile(TruffleStamp stamp, OptimizedCallTarget target, TruffleStamp oldStamp, TruffleStamp newStamp) { - String id = String.format("@%8h %s", target.hashCode(), target.getSourceCallTarget() == null ? "orig." : "split"); - String plusMinus = stamp.equals(newStamp) ? "+ " : (stamp.equals(oldStamp) ? "- " : ""); - System.out.printf("%16s%-20sCallers: %3d, Nodes:%10s %s%n", plusMinus, id, target.getKnownCallSiteCount(), // - String.format("%d (%d/%d)", count(target, NodeCost.MONOMORPHIC), count(target, NodeCost.POLYMORPHIC), count(target, NodeCost.MEGAMORPHIC)), stamp); - } - - private static int count(OptimizedCallTarget target, final NodeCost otherCost) { - return NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() { - public boolean isCounted(Node node) { - return node.getCost() == otherCost; - } - }); - } - private static void cleanup(OptimizedCallTarget currentTarget) { if (currentTarget.getKnownCallSiteCount() == 0 && currentTarget.getSourceCallTarget() != null) { OptimizedCallTarget removed = currentTarget.getSourceCallTarget().getSplitVersions().remove(currentTarget.getArgumentStamp()); diff -r 35639ec046d7 -r 881aa0ed3904 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleCompilationListener.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleCompilationListener.java Mon Oct 27 17:37:45 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleCompilationListener.java Mon Oct 27 18:03:45 2014 +0100 @@ -12,6 +12,8 @@ void notifyCompilationFailed(OptimizedCallTarget target, StructuredGraph graph, Throwable t); + void notifyCompilationSplit(OptimizedDirectCallNode callNode); + void notifyCompilationStarted(OptimizedCallTarget target); void notifyCompilationTruffleTierFinished(OptimizedCallTarget target, StructuredGraph graph); diff -r 35639ec046d7 -r 881aa0ed3904 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Mon Oct 27 17:37:45 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java Mon Oct 27 18:03:45 2014 +0100 @@ -63,6 +63,7 @@ TraceCompilationCallTreeListener.install(this); TracePerformanceWarningsListener.install(this); TraceInliningListener.install(this); + TraceSplittingListener.install(this); PrintCallTargetProfiling.install(this); } @@ -83,7 +84,7 @@ @Override public DirectCallNode createDirectCallNode(CallTarget target) { if (target instanceof OptimizedCallTarget) { - return new OptimizedDirectCallNode((OptimizedCallTarget) target); + return new OptimizedDirectCallNode(this, (OptimizedCallTarget) target); } else { throw new IllegalStateException(String.format("Unexpected call target class %s!", target.getClass())); } @@ -255,6 +256,10 @@ compilationListeners.forEach(l -> l.notifyCompilationFailed(target, graph, t)); } + public void notifyCompilationSplit(OptimizedDirectCallNode callNode) { + compilationListeners.forEach(l -> l.notifyCompilationSplit(callNode)); + } + public void notifyCompilationSuccess(OptimizedCallTarget target, StructuredGraph graph, CompilationResult result) { compilationListeners.forEach(l -> l.notifyCompilationSuccess(target, graph, result)); } diff -r 35639ec046d7 -r 881aa0ed3904 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetLog.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetLog.java Mon Oct 27 17:37:45 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2013, 2014, 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.truffle; - -import static com.oracle.graal.truffle.TruffleCompilerOptions.*; - -import java.io.*; -import java.util.*; - -import com.oracle.graal.debug.*; - -public final class OptimizedCallTargetLog { - - protected static final PrintStream OUT = TTY.out().out(); - - private OptimizedCallTargetLog() { - } - - private static int splitCount = 0; - - static void logSplit(OptimizedDirectCallNode callNode, OptimizedCallTarget target, OptimizedCallTarget newTarget) { - if (TraceTruffleSplitting.getValue()) { - Map properties = new LinkedHashMap<>(); - addASTSizeProperty(target, properties); - properties.put("Split#", ++splitCount); - properties.put("Source", callNode.getEncapsulatingSourceSection()); - log(0, "split", newTarget.toString(), properties); - } - } - - public static void addASTSizeProperty(OptimizedCallTarget target, Map properties) { - int nodeCount = target.countNonTrivialNodes(false); - int deepNodeCount = nodeCount; - TruffleInlining inlining = target.getInlining(); - if (inlining != null) { - deepNodeCount += inlining.getInlinedNodeCount(); - } - properties.put("ASTSize", String.format("%5d/%5d", nodeCount, deepNodeCount)); - - } - - static void log(int indent, String msg, String details, Map properties) { - StringBuilder sb = new StringBuilder(); - sb.append(String.format("[truffle] %-16s ", msg)); - for (int i = 0; i < indent; i++) { - sb.append(' '); - } - sb.append(String.format("%-" + (60 - indent) + "s", details)); - if (properties != null) { - for (String property : properties.keySet()) { - Object value = properties.get(property); - if (value == null) { - continue; - } - sb.append('|'); - sb.append(property); - - StringBuilder propertyBuilder = new StringBuilder(); - if (value instanceof Integer) { - propertyBuilder.append(String.format("%6d", value)); - } else if (value instanceof Double) { - propertyBuilder.append(String.format("%8.2f", value)); - } else { - propertyBuilder.append(value); - } - - int length = Math.max(1, 20 - property.length()); - sb.append(String.format(" %" + length + "s ", propertyBuilder.toString())); - } - } - OUT.println(sb.toString()); - } -} diff -r 35639ec046d7 -r 881aa0ed3904 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedDirectCallNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedDirectCallNode.java Mon Oct 27 17:37:45 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedDirectCallNode.java Mon Oct 27 18:03:45 2014 +0100 @@ -41,9 +41,11 @@ @CompilationFinal private FrameAccess outsideFrameAccess = FrameAccess.NONE; private final TruffleSplittingStrategy splittingStrategy; + private final GraalTruffleRuntime runtime; - public OptimizedDirectCallNode(OptimizedCallTarget target) { + public OptimizedDirectCallNode(GraalTruffleRuntime runtime, OptimizedCallTarget target) { super(target); + this.runtime = runtime; if (TruffleCompilerOptions.TruffleSplittingNew.getValue()) { this.splittingStrategy = new DefaultTruffleSplittingStrategyNew(this); } else { @@ -157,12 +159,12 @@ // dummy replace to report the split replace(this, "Split call " + newTarget.toString()); - if (newTarget.getSourceCallTarget() == null) { splitCallTarget = null; } else { splitCallTarget = newTarget; } + runtime.getCompilationNotify().notifyCompilationSplit(this); } @Override diff -r 35639ec046d7 -r 881aa0ed3904 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/AbstractDebugCompilationListener.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/AbstractDebugCompilationListener.java Mon Oct 27 17:37:45 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/AbstractDebugCompilationListener.java Mon Oct 27 18:03:45 2014 +0100 @@ -28,6 +28,9 @@ public void notifyCompilationTruffleTierFinished(OptimizedCallTarget target, StructuredGraph graph) { } + public void notifyCompilationSplit(OptimizedDirectCallNode callNode) { + } + public void notifyCompilationSuccess(OptimizedCallTarget target, StructuredGraph graph, CompilationResult result) { } diff -r 35639ec046d7 -r 881aa0ed3904 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/TraceSplittingListener.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/TraceSplittingListener.java Mon Oct 27 18:03:45 2014 +0100 @@ -0,0 +1,53 @@ +package com.oracle.graal.truffle.debug; + +import static com.oracle.graal.truffle.TruffleCompilerOptions.*; + +import java.util.*; + +import com.oracle.graal.truffle.*; +import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.api.nodes.NodeUtil.*; + +public class TraceSplittingListener extends AbstractDebugCompilationListener { + + private TraceSplittingListener() { + } + + public static void install(GraalTruffleRuntime runtime) { + if (TraceTruffleSplitting.getValue()) { + runtime.addCompilationListener(new TraceSplittingListener()); + } + } + + private int splitCount; + + @Override + public void notifyCompilationSplit(OptimizedDirectCallNode callNode) { + OptimizedCallTarget callTarget = callNode.getCallTarget(); + String label = String.format("split %3s-%-4s-%-4s ", splitCount++, callNode.getCurrentCallTarget().getCloneIndex(), callNode.getCallCount()); + AbstractDebugCompilationListener.log(0, label, callTarget.toString(), callTarget.getDebugProperties()); + + if (TruffleSplittingNew.getValue()) { + Map splitTargets = callTarget.getSplitVersions(); + logProfile(callTarget.getArgumentStamp(), callTarget); + for (TruffleStamp profile : splitTargets.keySet()) { + logProfile(profile, splitTargets.get(profile)); + } + } + } + + private static void logProfile(TruffleStamp stamp, OptimizedCallTarget target) { + String id = String.format("@%8h %s", target.hashCode(), target.getSourceCallTarget() == null ? "orig." : "split"); + OUT.printf("%16s%-20sCallers: %3d, Nodes:%10s %s%n", "", id, target.getKnownCallSiteCount(), // + String.format("%d (%d/%d)", count(target, NodeCost.MONOMORPHIC), count(target, NodeCost.POLYMORPHIC), count(target, NodeCost.MEGAMORPHIC)), stamp); + } + + private static int count(OptimizedCallTarget target, final NodeCost otherCost) { + return NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() { + public boolean isCounted(Node node) { + return node.getCost() == otherCost; + } + }); + } + +}