001/* 002 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.truffle.debug; 024 025import static com.oracle.graal.truffle.TruffleCompilerOptions.*; 026 027import java.util.*; 028 029import jdk.internal.jvmci.code.*; 030 031import com.oracle.graal.nodes.*; 032import com.oracle.graal.truffle.*; 033import com.oracle.truffle.api.source.*; 034 035public final class TraceCompilationListener extends AbstractDebugCompilationListener { 036 037 private final ThreadLocal<LocalCompilation> currentCompilation = new ThreadLocal<>(); 038 039 private TraceCompilationListener() { 040 } 041 042 public static void install(GraalTruffleRuntime runtime) { 043 if (TraceTruffleCompilation.getValue() || TraceTruffleCompilationDetails.getValue()) { 044 runtime.addCompilationListener(new TraceCompilationListener()); 045 } 046 } 047 048 @Override 049 public void notifyCompilationQueued(OptimizedCallTarget target) { 050 if (TraceTruffleCompilationDetails.getValue()) { 051 log(target, 0, "opt queued", target.toString(), target.getDebugProperties()); 052 } 053 } 054 055 @Override 056 public void notifyCompilationDequeued(OptimizedCallTarget target, Object source, CharSequence reason) { 057 if (TraceTruffleCompilationDetails.getValue()) { 058 Map<String, Object> properties = new LinkedHashMap<>(); 059 addSourceInfo(properties, source); 060 properties.put("Reason", reason); 061 log(target, 0, "opt unqueued", target.toString(), properties); 062 } 063 } 064 065 @Override 066 public void notifyCompilationFailed(OptimizedCallTarget target, StructuredGraph graph, Throwable t) { 067 super.notifyCompilationFailed(target, graph, t); 068 if (!TraceCompilationFailureListener.isPermanentBailout(t)) { 069 notifyCompilationDequeued(target, null, "Non permanent bailout: " + t.toString()); 070 } 071 currentCompilation.set(null); 072 } 073 074 @Override 075 public void notifyCompilationStarted(OptimizedCallTarget target) { 076 if (TraceTruffleCompilationDetails.getValue()) { 077 log(target, 0, "opt start", target.toString(), target.getDebugProperties()); 078 } 079 LocalCompilation compilation = new LocalCompilation(); 080 compilation.timeCompilationStarted = System.nanoTime(); 081 currentCompilation.set(compilation); 082 } 083 084 @Override 085 public void notifyCompilationTruffleTierFinished(OptimizedCallTarget target, StructuredGraph graph) { 086 super.notifyCompilationTruffleTierFinished(target, graph); 087 LocalCompilation compilation = currentCompilation.get(); 088 compilation.timePartialEvaluationFinished = System.nanoTime(); 089 compilation.nodeCountPartialEval = graph.getNodeCount(); 090 } 091 092 @Override 093 public void notifyCompilationSuccess(OptimizedCallTarget target, StructuredGraph graph, CompilationResult result) { 094 long timeCompilationFinished = System.nanoTime(); 095 int nodeCountLowered = graph.getNodeCount(); 096 LocalCompilation compilation = currentCompilation.get(); 097 TruffleInlining inlining = target.getInlining(); 098 099 int calls; 100 int inlinedCalls; 101 if (inlining == null) { 102 calls = (int) target.nodeStream(false).filter(node -> (node instanceof OptimizedDirectCallNode)).count(); 103 inlinedCalls = 0; 104 } else { 105 calls = inlining.countCalls(); 106 inlinedCalls = inlining.countInlinedCalls(); 107 } 108 109 int dispatchedCalls = calls - inlinedCalls; 110 Map<String, Object> properties = new LinkedHashMap<>(); 111 addASTSizeProperty(target, properties); 112 properties.put("Time", String.format("%5.0f(%4.0f+%-4.0f)ms", // 113 (timeCompilationFinished - compilation.timeCompilationStarted) / 1e6, // 114 (compilation.timePartialEvaluationFinished - compilation.timeCompilationStarted) / 1e6, // 115 (timeCompilationFinished - compilation.timePartialEvaluationFinished) / 1e6)); 116 properties.put("DirectCallNodes", String.format("I %4d/D %4d", inlinedCalls, dispatchedCalls)); 117 properties.put("GraalNodes", String.format("%5d/%5d", compilation.nodeCountPartialEval, nodeCountLowered)); 118 properties.put("CodeSize", result.getTargetCodeSize()); 119 properties.put("Source", formatSourceSection(target.getRootNode().getSourceSection())); 120 121 log(target, 0, "opt done", target.toString(), properties); 122 super.notifyCompilationSuccess(target, graph, result); 123 currentCompilation.set(null); 124 } 125 126 private static String formatSourceSection(SourceSection sourceSection) { 127 return sourceSection != null ? sourceSection.getShortDescription() : "n/a"; 128 } 129 130 @Override 131 public void notifyCompilationInvalidated(OptimizedCallTarget target, Object source, CharSequence reason) { 132 Map<String, Object> properties = new LinkedHashMap<>(); 133 addSourceInfo(properties, source); 134 properties.put("Reason", reason); 135 log(target, 0, "opt invalidated", target.toString(), properties); 136 } 137 138 private static void addSourceInfo(Map<String, Object> properties, Object source) { 139 if (source != null) { 140 properties.put("SourceClass", source.getClass().getSimpleName()); 141 properties.put("Source", source); 142 } 143 } 144 145 private static final class LocalCompilation { 146 long timeCompilationStarted; 147 long timePartialEvaluationFinished; 148 long nodeCountPartialEval; 149 } 150 151}