1 /* 2 * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 /** 26 * The main command line driver of a parser for LogCompilation output. 27 * @author never 28 */ 29 30 package com.sun.hotspot.tools.compiler; 31 32 import java.io.PrintStream; 33 import java.util.*; 34 import org.xml.sax.*; 35 import org.xml.sax.helpers.*; 36 37 public class LogCompilation extends DefaultHandler implements ErrorHandler, Constants { 38 39 public static void usage(int exitcode) { 40 System.out.println("Usage: LogCompilation [ -v ] [ -c ] [ -s ] [ -e | -n ] file1 ..."); 41 System.out.println(" -c: clean up malformed 1.5 xml"); 42 System.out.println(" -i: print inlining decisions"); 43 System.out.println(" -S: print compilation statistics"); 44 System.out.println(" -s: sort events by start time"); 45 System.out.println(" -e: sort events by elapsed time"); 46 System.out.println(" -n: sort events by name and start"); 47 System.exit(exitcode); 48 } 49 50 public static void main(String[] args) throws Exception { 51 Comparator<LogEvent> defaultSort = LogParser.sortByStart; 52 boolean statistics = false; 53 boolean printInlining = false; 54 boolean cleanup = false; 55 int index = 0; 56 57 while (args.length > index) { 58 if (args[index].equals("-e")) { 59 defaultSort = LogParser.sortByElapsed; 60 index++; 61 } else if (args[index].equals("-n")) { 62 defaultSort = LogParser.sortByNameAndStart; 63 index++; 64 } else if (args[index].equals("-s")) { 65 defaultSort = LogParser.sortByStart; 66 index++; 67 } else if (args[index].equals("-c")) { 68 cleanup = true; 69 index++; 70 } else if (args[index].equals("-S")) { 71 statistics = true; 72 index++; 73 } else if (args[index].equals("-h")) { 74 usage(0); 75 } else if (args[index].equals("-i")) { 76 printInlining = true; 77 index++; 78 } else { 79 break; 80 } 81 } 82 83 if (index >= args.length) { 84 usage(1); 85 } 86 87 while (index < args.length) { 88 ArrayList<LogEvent> events = LogParser.parse(args[index], cleanup); 89 90 if (statistics) { 91 printStatistics(events, System.out); 92 } else { 93 Collections.sort(events, defaultSort); 94 for (LogEvent c : events) { 95 if (printInlining && c instanceof Compilation) { 96 Compilation comp = (Compilation)c; 97 comp.print(System.out, true); 98 } else { 99 c.print(System.out); 100 } 101 } 102 } 103 index++; 104 } 105 } 106 107 public static void printStatistics(ArrayList<LogEvent> events, PrintStream out) { 108 long cacheSize = 0; 109 long maxCacheSize = 0; 110 int nmethodsCreated = 0; 111 int nmethodsLive = 0; 112 int[] attempts = new int[32]; 113 double regallocTime = 0; 114 int maxattempts = 0; 115 116 LinkedHashMap<String, Double> phaseTime = new LinkedHashMap<String, Double>(7); 117 LinkedHashMap<String, Integer> phaseNodes = new LinkedHashMap<String, Integer>(7); 118 double elapsed = 0; 119 120 for (LogEvent e : events) { 121 if (e instanceof Compilation) { 122 Compilation c = (Compilation) e; 123 c.printShort(out); 124 out.printf(" %6.4f\n", c.getElapsedTime()); 125 attempts[c.getAttempts()]++; 126 maxattempts = Math.max(maxattempts,c.getAttempts()); 127 elapsed += c.getElapsedTime(); 128 for (Phase phase : c.getPhases()) { 129 Double v = phaseTime.get(phase.getName()); 130 if (v == null) { 131 v = Double.valueOf(0.0); 132 } 133 phaseTime.put(phase.getName(), Double.valueOf(v.doubleValue() + phase.getElapsedTime())); 134 135 Integer v2 = phaseNodes.get(phase.getName()); 136 if (v2 == null) { 137 v2 = Integer.valueOf(0); 138 } 139 phaseNodes.put(phase.getName(), Integer.valueOf(v2.intValue() + phase.getNodes())); 140 /* Print phase name, elapsed time, nodes at the start of the phase, 141 nodes created in the phase, live nodes at the start of the phase, 142 live nodes added in the phase. 143 */ 144 out.printf("\t%s %6.4f %d %d %d %d\n", phase.getName(), phase.getElapsedTime(), phase.getStartNodes(), phase.getNodes(), phase.getStartLiveNodes(), phase.getLiveNodes()); 145 } 146 } else if (e instanceof MakeNotEntrantEvent) { 147 MakeNotEntrantEvent mne = (MakeNotEntrantEvent) e; 148 NMethod nm = mne.getNMethod(); 149 if (mne.isZombie()) { 150 if (nm == null) { 151 System.err.println(mne.getId()); 152 } 153 cacheSize -= nm.getSize(); 154 nmethodsLive--; 155 } 156 } else if (e instanceof NMethod) { 157 nmethodsLive++; 158 nmethodsCreated++; 159 NMethod nm = (NMethod) e; 160 cacheSize += nm.getSize(); 161 maxCacheSize = Math.max(cacheSize, maxCacheSize); 162 } 163 } 164 out.printf("NMethods: %d created %d live %d bytes (%d peak) in the code cache\n", 165 nmethodsCreated, nmethodsLive, cacheSize, maxCacheSize); 166 out.println("Phase times:"); 167 for (String name : phaseTime.keySet()) { 168 Double v = phaseTime.get(name); 169 Integer v2 = phaseNodes.get(name); 170 out.printf("%20s %6.4f %d\n", name, v.doubleValue(), v2.intValue()); 171 } 172 out.printf("%20s %6.4f\n", "total", elapsed); 173 174 if (maxattempts > 0) { 175 out.println("Distribution of regalloc passes:"); 176 for (int i = 0; i <= maxattempts; i++) { 177 out.printf("%2d %8d\n", i, attempts[i]); 178 } 179 } 180 } 181 }