1 /*
   2  * Copyright (c) 2009, 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                     out.printf("\t%s %6.4f\n", phase.getName(), phase.getElapsedTime());
 130                     Double v = phaseTime.get(phase.getName());
 131                     if (v == null) {
 132                         v = Double.valueOf(0.0);
 133                     }
 134                     phaseTime.put(phase.getName(), Double.valueOf(v.doubleValue() + phase.getElapsedTime()));
 135 
 136                     Integer v2 = phaseNodes.get(phase.getName());
 137                     if (v2 == null) {
 138                         v2 = Integer.valueOf(0);
 139                     }
 140                     phaseNodes.put(phase.getName(), Integer.valueOf(v2.intValue() + phase.getNodes()));
 141                 }
 142             } else if (e instanceof MakeNotEntrantEvent) {
 143                 MakeNotEntrantEvent mne = (MakeNotEntrantEvent) e;
 144                 NMethod nm = mne.getNMethod();
 145                 if (mne.isZombie()) {
 146                     if (nm == null) {
 147                         System.err.println(mne.getId());
 148                     }
 149                     cacheSize -= nm.getSize();
 150                     nmethodsLive--;
 151                 }
 152             } else if (e instanceof NMethod) {
 153                 nmethodsLive++;
 154                 nmethodsCreated++;
 155                 NMethod nm = (NMethod) e;
 156                 cacheSize += nm.getSize();
 157                 maxCacheSize = Math.max(cacheSize, maxCacheSize);
 158             }
 159         }
 160         out.printf("NMethods: %d created %d live %d bytes (%d peak) in the code cache\n",
 161                           nmethodsCreated, nmethodsLive, cacheSize, maxCacheSize);
 162         out.println("Phase times:");
 163         for (String name : phaseTime.keySet()) {
 164             Double v = phaseTime.get(name);
 165             Integer v2 = phaseNodes.get(name);
 166             out.printf("%20s %6.4f %d\n", name, v.doubleValue(), v2.intValue());
 167         }
 168         out.printf("%20s %6.4f\n", "total", elapsed);
 169 
 170         if (maxattempts > 0) {
 171             out.println("Distribution of regalloc passes:");
 172             for (int i = 0; i <= maxattempts; i++) {
 173                 out.printf("%2d %8d\n", i, attempts[i]);
 174             }
 175         }
 176     }
 177 }