< prev index next >

src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java

Print this page


   1 /*
   2  * Copyright (c) 2009, 2013, 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  * A SAX based parser of LogCompilation output from HotSpot.  It takes a complete
  27  * @author never
  28  */
  29 
  30 package com.sun.hotspot.tools.compiler;
  31 
  32 import java.io.FileReader;

  33 import java.io.Reader;
  34 import java.util.ArrayDeque;
  35 import java.util.ArrayList;
  36 import java.util.Collections;
  37 import java.util.Comparator;
  38 import java.util.HashMap;
  39 import java.util.LinkedHashMap;
  40 import java.util.Stack;
  41 import javax.xml.parsers.SAXParser;
  42 import javax.xml.parsers.SAXParserFactory;
  43 import org.xml.sax.Attributes;
  44 import org.xml.sax.ErrorHandler;
  45 import org.xml.sax.InputSource;
  46 import org.xml.sax.helpers.DefaultHandler;
  47 
  48 public class LogParser extends DefaultHandler implements ErrorHandler, Constants {
  49 
  50     static final HashMap<String, String> typeMap;
  51     static {
  52         typeMap = new HashMap<String, String>();


 117             if (difference < 0) {
 118                 return -1;
 119             }
 120             if (difference > 0) {
 121                 return 1;
 122             }
 123             return 0;
 124         }
 125 
 126         @Override
 127         public boolean equals(Object other) {
 128             return false;
 129         }
 130 
 131         @Override
 132         public int hashCode() {
 133             return 7;
 134         }
 135     };
 136 






































 137     private ArrayList<LogEvent> events = new ArrayList<LogEvent>();
 138 
 139     private HashMap<String, String> types = new HashMap<String, String>();
 140     private HashMap<String, Method> methods = new HashMap<String, Method>();
 141     private LinkedHashMap<String, NMethod> nmethods = new LinkedHashMap<String, NMethod>();
 142     private HashMap<String, Compilation> compiles = new HashMap<String, Compilation>();
 143     private String failureReason;
 144     private int bci;
 145     private Stack<CallSite> scopes = new Stack<CallSite>();
 146     private Compilation compile;
 147     private CallSite site;
 148     private CallSite methodHandleSite;
 149     private Stack<Phase> phaseStack = new Stack<Phase>();

 150     private UncommonTrapEvent currentTrap;
 151     private Stack<CallSite> lateInlineScope;
 152     private boolean lateInlining;
 153 
 154 
 155     long parseLong(String l) {
 156         try {
 157             return Long.decode(l).longValue();
 158         } catch (NumberFormatException nfe) {
 159             int split = l.length() - 8;
 160             String s1 = "0x" + l.substring(split);
 161             String s2 = l.substring(0, split);
 162             long v1 = Long.decode(s1).longValue() & 0xffffffffL;
 163             long v2 = (Long.decode(s2).longValue() & 0xffffffffL) << 32;
 164             if (!l.equals("0x" + Long.toHexString(v1 + v2))) {
 165                 System.out.println(l);
 166                 System.out.println(s1);
 167                 System.out.println(s2);
 168                 System.out.println(v1);
 169                 System.out.println(v2);


 175     }
 176 
 177     public static ArrayList<LogEvent> parse(String file, boolean cleanup) throws Exception {
 178         return parse(new FileReader(file), cleanup);
 179     }
 180 
 181     public static ArrayList<LogEvent> parse(Reader reader, boolean cleanup) throws Exception {
 182         // Create the XML input factory
 183         SAXParserFactory factory = SAXParserFactory.newInstance();
 184 
 185         // Create the XML LogEvent reader
 186         SAXParser p = factory.newSAXParser();
 187 
 188         if (cleanup) {
 189             // some versions of the log have slightly malformed XML, so clean it
 190             // up before passing it to SAX
 191             reader = new LogCleanupReader(reader);
 192         }
 193 
 194         LogParser log = new LogParser();

 195         p.parse(new InputSource(reader), log);




 196 
 197         // Associate compilations with their NMethods
 198         for (NMethod nm : log.nmethods.values()) {
 199             Compilation c = log.compiles.get(nm.getId());
 200             nm.setCompilation(c);
 201             // Native wrappers for methods don't have a compilation
 202             if (c != null) {
 203                 c.setNMethod(nm);
 204             }
 205         }
 206 
 207         // Initially we want the LogEvent log sorted by timestamp
 208         Collections.sort(log.events, sortByStart);
 209 
 210         return log.events;
 211     }
 212 
 213     String search(Attributes attr, String name) {
 214         String result = attr.getValue(name);
 215         if (result != null) {


 401             String id = makeId(atts);
 402             NMethod nm = nmethods.get(id);
 403             if (nm == null) throw new InternalError();
 404             LogEvent e = new MakeNotEntrantEvent(Double.parseDouble(search(atts, "stamp")), id,
 405                                                  atts.getValue("zombie") != null, nm);
 406             events.add(e);
 407         } else if (qname.equals("uncommon_trap")) {
 408             String id = atts.getValue("compile_id");
 409             if (id != null) {
 410                 id = makeId(atts);
 411                 currentTrap = new UncommonTrapEvent(Double.parseDouble(search(atts, "stamp")),
 412                         id,
 413                         atts.getValue("reason"),
 414                         atts.getValue("action"),
 415                         Integer.parseInt(search(atts, "count", "0")));
 416                 events.add(currentTrap);
 417             } else {
 418                 // uncommon trap inserted during parsing.
 419                 // ignore for now
 420             }









 421         } else if (qname.equals("late_inline")) {
 422             long inlineId = Long.parseLong(search(atts, "inline_id"));





 423             lateInlineScope = new Stack<CallSite>();
 424             site = new CallSite(-999, method(search(atts, "method")));
 425             site.setInlineId(inlineId);
 426             lateInlineScope.push(site);
 427         } else if (qname.equals("jvms")) {
 428             // <jvms bci='4' method='java/io/DataInputStream readChar ()C' bytes='40' count='5815' iicount='20815'/>
 429             if (currentTrap != null) {
 430                 currentTrap.addJVMS(atts.getValue("method"), Integer.parseInt(atts.getValue("bci")));


 431             } else if (lateInlineScope != null) {
 432                 bci = Integer.parseInt(search(atts, "bci"));
 433                 site = new CallSite(bci, method(search(atts, "method")));
 434                 lateInlineScope.push(site);
 435             } else {
 436                 // Ignore <eliminate_allocation type='667'>,
 437                 //        <eliminate_lock lock='1'>,
 438                 //        <replace_string_concat arguments='2' string_alloc='0' multiple='0'>
 439             }
 440         } else if (qname.equals("inline_id")) {
 441             if (methodHandleSite != null) {
 442                 throw new InternalError("method handle site should have been replaced");
 443             }
 444             long id = Long.parseLong(search(atts, "id"));
 445             site.setInlineId(id);
 446         } else if (qname.equals("nmethod")) {
 447             String id = makeId(atts);
 448             NMethod nm = new NMethod(Double.parseDouble(search(atts, "stamp")),
 449                     id,
 450                     parseLong(atts.getValue("address")),


 495             CallSite call = scopes.pop();
 496             call.setEndNodes(Integer.parseInt(search(atts, "nodes", "0")));
 497             call.setEndLiveNodes(Integer.parseInt(search(atts, "live", "0")));
 498             call.setTimeStamp(Double.parseDouble(search(atts, "stamp")));
 499             scopes.push(call);
 500         }
 501     }
 502 
 503     @Override
 504     public void endElement(String uri,
 505             String localName,
 506             String qname) {
 507         if (qname.equals("parse")) {
 508             indent -= 2;
 509             scopes.pop();
 510             if (scopes.size() == 0) {
 511                 lateInlining = false;
 512             }
 513         } else if (qname.equals("uncommon_trap")) {
 514             currentTrap = null;


 515         } else if (qname.equals("late_inline")) {
 516             // Populate late inlining info.
 517             if (scopes.size() != 0) {
 518                 throw new InternalError("scopes should be empty for late inline");
 519             }
 520             // late inline scopes are specified in reverse order:
 521             // compiled method should be on top of stack.
 522             CallSite caller = lateInlineScope.pop();
 523             Method m = compile.getMethod();
 524             if (m != caller.getMethod()) {
 525                 System.out.println(m);
 526                 System.out.println(caller.getMethod() + " bci: " + bci);
 527                 throw new InternalError("call site and late_inline info don't match");
 528             }
 529 
 530             // late_inline contains caller+bci info, convert it
 531             // to bci+callee info used by LogCompilation.
 532             CallSite lateInlineSite = compile.getLateInlineCall();
 533             ArrayDeque<CallSite> thisCallScopes = new ArrayDeque<CallSite>();
 534             do {
 535                 bci = caller.getBci();
 536                 // Next inlined call.
 537                 caller = lateInlineScope.pop();
 538                 CallSite callee =  new CallSite(bci, caller.getMethod());
 539                 callee.setInlineId(caller.getInlineId());
 540                 thisCallScopes.addLast(callee);
 541                 lateInlineSite.add(callee);
 542                 lateInlineSite = callee;
 543             } while (!lateInlineScope.empty());
 544 
 545             site = compile.getCall().findCallSite(thisCallScopes);
 546             if (site == null) {


   1 /*
   2  * Copyright (c) 2009, 2015, 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  * A SAX based parser of LogCompilation output from HotSpot.  It takes a complete

  27  */
  28 
  29 package com.sun.hotspot.tools.compiler;
  30 
  31 import java.io.FileReader;
  32 import java.io.PrintStream;
  33 import java.io.Reader;
  34 import java.util.ArrayDeque;
  35 import java.util.ArrayList;
  36 import java.util.Collections;
  37 import java.util.Comparator;
  38 import java.util.HashMap;
  39 import java.util.LinkedHashMap;
  40 import java.util.Stack;
  41 import javax.xml.parsers.SAXParser;
  42 import javax.xml.parsers.SAXParserFactory;
  43 import org.xml.sax.Attributes;
  44 import org.xml.sax.ErrorHandler;
  45 import org.xml.sax.InputSource;
  46 import org.xml.sax.helpers.DefaultHandler;
  47 
  48 public class LogParser extends DefaultHandler implements ErrorHandler, Constants {
  49 
  50     static final HashMap<String, String> typeMap;
  51     static {
  52         typeMap = new HashMap<String, String>();


 117             if (difference < 0) {
 118                 return -1;
 119             }
 120             if (difference > 0) {
 121                 return 1;
 122             }
 123             return 0;
 124         }
 125 
 126         @Override
 127         public boolean equals(Object other) {
 128             return false;
 129         }
 130 
 131         @Override
 132         public int hashCode() {
 133             return 7;
 134         }
 135     };
 136 
 137     class Jvms {
 138         Jvms(Method method, int bci) {
 139             this.method = method;
 140             this.bci = bci;
 141         }
 142         final public Method method;
 143         final public int bci;
 144         final public String toString() {
 145             return "@" + bci + " " + method;
 146         }
 147     }
 148 
 149     class LockElimination extends BasicLogEvent {
 150 
 151         ArrayList<Jvms> jvms = new ArrayList<Jvms>(1);
 152         final String kind;
 153         final String classId;
 154         final String tagName;
 155         LockElimination(String tagName, double start, String id, String kind, String classId) {
 156             super(start, id);
 157             this.kind = kind;
 158             this.classId = classId;
 159             this.tagName = tagName;
 160         }
 161 
 162         @Override
 163         public void print(PrintStream stream) {
 164             stream.printf("%s %s %s %s  %.3f ", getId(), tagName, kind, classId, getStart());
 165             stream.print(jvms.toString());
 166             stream.print("\n");
 167         }
 168 
 169         void addJVMS(Method method, int bci) {
 170             jvms.add(new Jvms(method, bci));
 171         }
 172 
 173     }
 174 
 175     private ArrayList<LogEvent> events = new ArrayList<LogEvent>();
 176 
 177     private HashMap<String, String> types = new HashMap<String, String>();
 178     private HashMap<String, Method> methods = new HashMap<String, Method>();
 179     private LinkedHashMap<String, NMethod> nmethods = new LinkedHashMap<String, NMethod>();
 180     private HashMap<String, Compilation> compiles = new HashMap<String, Compilation>();
 181     private String failureReason;
 182     private int bci;
 183     private Stack<CallSite> scopes = new Stack<CallSite>();
 184     private Compilation compile;
 185     private CallSite site;
 186     private CallSite methodHandleSite;
 187     private Stack<Phase> phaseStack = new Stack<Phase>();
 188     private LockElimination currentLockElimination;
 189     private UncommonTrapEvent currentTrap;
 190     private Stack<CallSite> lateInlineScope;
 191     private boolean lateInlining;
 192 
 193 
 194     long parseLong(String l) {
 195         try {
 196             return Long.decode(l).longValue();
 197         } catch (NumberFormatException nfe) {
 198             int split = l.length() - 8;
 199             String s1 = "0x" + l.substring(split);
 200             String s2 = l.substring(0, split);
 201             long v1 = Long.decode(s1).longValue() & 0xffffffffL;
 202             long v2 = (Long.decode(s2).longValue() & 0xffffffffL) << 32;
 203             if (!l.equals("0x" + Long.toHexString(v1 + v2))) {
 204                 System.out.println(l);
 205                 System.out.println(s1);
 206                 System.out.println(s2);
 207                 System.out.println(v1);
 208                 System.out.println(v2);


 214     }
 215 
 216     public static ArrayList<LogEvent> parse(String file, boolean cleanup) throws Exception {
 217         return parse(new FileReader(file), cleanup);
 218     }
 219 
 220     public static ArrayList<LogEvent> parse(Reader reader, boolean cleanup) throws Exception {
 221         // Create the XML input factory
 222         SAXParserFactory factory = SAXParserFactory.newInstance();
 223 
 224         // Create the XML LogEvent reader
 225         SAXParser p = factory.newSAXParser();
 226 
 227         if (cleanup) {
 228             // some versions of the log have slightly malformed XML, so clean it
 229             // up before passing it to SAX
 230             reader = new LogCleanupReader(reader);
 231         }
 232 
 233         LogParser log = new LogParser();
 234         try {
 235             p.parse(new InputSource(reader), log);
 236         } catch (Throwable th) {
 237             th.printStackTrace();
 238             // Carry on with what we've got...
 239         }
 240 
 241         // Associate compilations with their NMethods
 242         for (NMethod nm : log.nmethods.values()) {
 243             Compilation c = log.compiles.get(nm.getId());
 244             nm.setCompilation(c);
 245             // Native wrappers for methods don't have a compilation
 246             if (c != null) {
 247                 c.setNMethod(nm);
 248             }
 249         }
 250 
 251         // Initially we want the LogEvent log sorted by timestamp
 252         Collections.sort(log.events, sortByStart);
 253 
 254         return log.events;
 255     }
 256 
 257     String search(Attributes attr, String name) {
 258         String result = attr.getValue(name);
 259         if (result != null) {


 445             String id = makeId(atts);
 446             NMethod nm = nmethods.get(id);
 447             if (nm == null) throw new InternalError();
 448             LogEvent e = new MakeNotEntrantEvent(Double.parseDouble(search(atts, "stamp")), id,
 449                                                  atts.getValue("zombie") != null, nm);
 450             events.add(e);
 451         } else if (qname.equals("uncommon_trap")) {
 452             String id = atts.getValue("compile_id");
 453             if (id != null) {
 454                 id = makeId(atts);
 455                 currentTrap = new UncommonTrapEvent(Double.parseDouble(search(atts, "stamp")),
 456                         id,
 457                         atts.getValue("reason"),
 458                         atts.getValue("action"),
 459                         Integer.parseInt(search(atts, "count", "0")));
 460                 events.add(currentTrap);
 461             } else {
 462                 // uncommon trap inserted during parsing.
 463                 // ignore for now
 464             }
 465         } else if (qname.startsWith("eliminate_lock")) {
 466             String id = atts.getValue("compile_id");
 467             if (id != null) {
 468                 id = makeId(atts);
 469                 String kind = atts.getValue("kind");
 470                 String classId = atts.getValue("class_id");
 471                 currentLockElimination = new LockElimination(qname, Double.parseDouble(search(atts, "stamp")), id, kind, classId);
 472                 events.add(currentLockElimination);
 473             }
 474         } else if (qname.equals("late_inline")) {
 475             long inlineId = 0;
 476             try {
 477                 Long.parseLong(search(atts, "inline_id"));
 478             } catch (InternalError ex) {
 479                 // 0 is an acceptable default value.
 480             }
 481             lateInlineScope = new Stack<CallSite>();
 482             site = new CallSite(-999, method(search(atts, "method")));
 483             site.setInlineId(inlineId);
 484             lateInlineScope.push(site);
 485         } else if (qname.equals("jvms")) {
 486             // <jvms bci='4' method='java/io/DataInputStream readChar ()C' bytes='40' count='5815' iicount='20815'/>
 487             if (currentTrap != null) {
 488                 currentTrap.addJVMS(atts.getValue("method"), Integer.parseInt(atts.getValue("bci")));
 489             } else if (currentLockElimination != null) {
 490                   currentLockElimination.addJVMS(method(atts.getValue("method")), Integer.parseInt(atts.getValue("bci")));
 491             } else if (lateInlineScope != null) {
 492                 bci = Integer.parseInt(search(atts, "bci"));
 493                 site = new CallSite(bci, method(search(atts, "method")));
 494                 lateInlineScope.push(site);
 495             } else {
 496                 // Ignore <eliminate_allocation type='667'>,
 497                 //        <eliminate_lock lock='1'>,
 498                 //        <replace_string_concat arguments='2' string_alloc='0' multiple='0'>
 499             }
 500         } else if (qname.equals("inline_id")) {
 501             if (methodHandleSite != null) {
 502                 throw new InternalError("method handle site should have been replaced");
 503             }
 504             long id = Long.parseLong(search(atts, "id"));
 505             site.setInlineId(id);
 506         } else if (qname.equals("nmethod")) {
 507             String id = makeId(atts);
 508             NMethod nm = new NMethod(Double.parseDouble(search(atts, "stamp")),
 509                     id,
 510                     parseLong(atts.getValue("address")),


 555             CallSite call = scopes.pop();
 556             call.setEndNodes(Integer.parseInt(search(atts, "nodes", "0")));
 557             call.setEndLiveNodes(Integer.parseInt(search(atts, "live", "0")));
 558             call.setTimeStamp(Double.parseDouble(search(atts, "stamp")));
 559             scopes.push(call);
 560         }
 561     }
 562 
 563     @Override
 564     public void endElement(String uri,
 565             String localName,
 566             String qname) {
 567         if (qname.equals("parse")) {
 568             indent -= 2;
 569             scopes.pop();
 570             if (scopes.size() == 0) {
 571                 lateInlining = false;
 572             }
 573         } else if (qname.equals("uncommon_trap")) {
 574             currentTrap = null;
 575         } else if (qname.startsWith("eliminate_lock")) {
 576             currentLockElimination = null;
 577         } else if (qname.equals("late_inline")) {
 578             // Populate late inlining info.
 579             if (scopes.size() != 0) {
 580                 throw new InternalError("scopes should be empty for late inline");
 581             }
 582             // late inline scopes are specified in reverse order:
 583             // compiled method should be on top of stack.
 584             CallSite caller = lateInlineScope.pop();
 585             Method m = compile.getMethod();
 586             if (m != caller.getMethod()) {
 587                 System.err.println(m);
 588                 System.err.println(caller.getMethod() + " bci: " + bci);
 589                 throw new InternalError("call site and late_inline info don't match");
 590             }
 591 
 592             // late_inline contains caller+bci info, convert it
 593             // to bci+callee info used by LogCompilation.
 594             CallSite lateInlineSite = compile.getLateInlineCall();
 595             ArrayDeque<CallSite> thisCallScopes = new ArrayDeque<CallSite>();
 596             do {
 597                 bci = caller.getBci();
 598                 // Next inlined call.
 599                 caller = lateInlineScope.pop();
 600                 CallSite callee =  new CallSite(bci, caller.getMethod());
 601                 callee.setInlineId(caller.getInlineId());
 602                 thisCallScopes.addLast(callee);
 603                 lateInlineSite.add(callee);
 604                 lateInlineSite = callee;
 605             } while (!lateInlineScope.empty());
 606 
 607             site = compile.getCall().findCallSite(thisCallScopes);
 608             if (site == null) {


< prev index next >