# HG changeset patch # User Tom Rodriguez # Date 1426645314 25200 # Node ID 077c16efeb6ddbd026d866d8ca45d3b909a8cd49 # Parent 5119e7f07d93641856f33a736fe4ae5391fbf22f Add option to print CompileQueue occupancy from LogCompilation output diff -r 5119e7f07d93 -r 077c16efeb6d src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCompilation.java --- a/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCompilation.java Tue Mar 17 19:21:22 2015 -0700 +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCompilation.java Tue Mar 17 19:21:54 2015 -0700 @@ -45,6 +45,7 @@ System.out.println(" -e: sort events by elapsed time"); System.out.println(" -n: sort events by name and start"); System.out.println(" -L: print eliminated locks"); + System.out.println(" -Q: print compile queue activity"); System.exit(exitcode); } @@ -54,6 +55,7 @@ boolean printInlining = false; boolean cleanup = false; boolean printEliminatedLocks = false; + boolean printCompileQueue = false; int index = 0; while (args.length > index) { @@ -80,6 +82,9 @@ } else if (args[index].equals("-L")) { printEliminatedLocks = true; index++; + } else if (args[index].equals("-Q")) { + printCompileQueue = true; + index++; } else { break; } @@ -92,32 +97,17 @@ while (index < args.length) { ArrayList events = LogParser.parse(args[index], cleanup); - if (printEliminatedLocks) { - Collections.sort(events, defaultSort); - for (LogEvent e : events) { - if (e instanceof Compilation) { - Compilation c = (Compilation) e; - List eliminated = c.getEliminatedLocks(); - if (!eliminated.isEmpty()) { - c.print(System.out); - System.out.println(" Eliminated locks"); - for (JVMState jvms : eliminated) { - System.err.print(" "); - while (jvms != null) { - System.out.printf(" %s.%s@%d", jvms.method.getHolder().replace('/', '.'), jvms.method.getName(), jvms.bci); - jvms = jvms.outer; - } - System.out.println(); - } - } - } - } + if (printCompileQueue) { + printCompileQueue(events, System.out); + } else if (printEliminatedLocks) { + printEliminatedLocks(events, System.out, defaultSort); } else if (statistics) { printStatistics(events, System.out); } else { Collections.sort(events, defaultSort); for (LogEvent c : events) { if (c instanceof NMethod) continue; + if (c instanceof TaskEvent) continue; System.out.printf("%f ", c.getStart()); if (printInlining && c instanceof Compilation) { @@ -131,7 +121,81 @@ index++; } } + + public static void printCompileQueue(ArrayList events, PrintStream out) { + int[] levels = new int[5]; + HashMap tasks = new HashMap(); + + out.printf("%7s ", "Stamp"); + for (int i = 1; i <= 4; i++) { + out.printf(" Level%d", i); + } + out.printf(" %10s", "Kind"); + out.println(); + for (LogEvent e : events) { + if (e instanceof TaskEvent) { + boolean demoted = false; + TaskEvent t = (TaskEvent) e; + TaskEvent start = tasks.get(t.getId()); + switch (t.getKind()) { + case Enqueue: + assert start == null; + levels[t.getLevel()] = levels[t.getLevel()] + 1; + tasks.put(t.getId(), t); + break; + + case Finish: + case Dequeue: + if (start != null && start.getLevel() != t.getLevel()) { + // Sometimes tasks are moved to a lower + // compilation level when the queue fills. + demoted = true; + levels[start.getLevel()] = levels[start.getLevel()] - 1; + } else { + levels[t.getLevel()] = levels[t.getLevel()] - 1; + } + break; + default: + throw new InternalError(); + } + out.printf("%7.3f ", t.getStart()); + for (int i = 1; i <= 4; i++) { + out.printf(" %6d", levels[i]); + } + out.printf(" %10s", t.getKind()); + if (t.getComment() != null) { + out.printf(" %s", t.getComment()); + } + if (demoted) { + out.printf(" %d->%d", start.getLevel(), t.getLevel()); + } + out.println(); + } + } + } + public static void printEliminatedLocks(ArrayList events, PrintStream out, Comparator defaultSort) { + Collections.sort(events, defaultSort); + for (LogEvent e : events) { + if (e instanceof Compilation) { + Compilation c = (Compilation) e; + List eliminated = c.getEliminatedLocks(); + if (!eliminated.isEmpty()) { + c.print(out); + out.println(" Eliminated locks"); + for (JVMState jvms : eliminated) { + System.err.print(" "); + while (jvms != null) { + out.printf(" %s.%s@%d", jvms.method.getHolder().replace('/', '.'), jvms.method.getName(), jvms.bci); + jvms = jvms.outer; + } + out.println(); + } + } + } + } + } + public static void printStatistics(ArrayList events, PrintStream out) { long cacheSize = 0; long maxCacheSize = 0; diff -r 5119e7f07d93 -r 077c16efeb6d src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java --- a/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java Tue Mar 17 19:21:22 2015 -0700 +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java Tue Mar 17 19:21:54 2015 -0700 @@ -204,7 +204,7 @@ } } else { if (c == null) { - throw new InternalError("can't find compilation " + ble.getId() + " for " + ble); + // throw new InternalError("can't find compilation " + ble.getId() + " for " + ble); } } } @@ -363,6 +363,17 @@ scopes.peek().last().setReason(search(atts, "reason")); } else if (qname.equals("failure")) { failureReason = search(atts, "reason"); + } else if (qname.equals("task_queued")) { + String id = makeId(atts); + int level = Integer.parseInt(search(atts, "level")); + TaskEvent t = new TaskEvent(Double.parseDouble(search(atts, "stamp")), id, level, TaskEvent.Kind.Enqueue); + events.add(t); + } else if (qname.equals("task_dequeued")) { + String id = makeId(atts); + int level = Integer.parseInt(search(atts, "level")); + TaskEvent t = new TaskEvent(Double.parseDouble(search(atts, "stamp")), id, level, TaskEvent.Kind.Dequeue); + t.setComment(search(atts, "comment")); + events.add(t); } else if (qname.equals("task_done")) { compile.setEnd(Double.parseDouble(search(atts, "stamp"))); if (Integer.parseInt(search(atts, "success")) == 0) { @@ -425,6 +436,12 @@ parseLong(atts.getValue("size"))); nmethods.put(id, nm); events.add(nm); + + int level = Integer.parseInt(search(atts, "level")); + if (level > 0) { + TaskEvent t = new TaskEvent(Double.parseDouble(search(atts, "stamp")), id, level, TaskEvent.Kind.Finish); + events.add(t); + } } else if (qname.equals("parse")) { Method m = method(search(atts, "method")); if (scopes.size() == 0) { diff -r 5119e7f07d93 -r 077c16efeb6d src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/TaskEvent.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/TaskEvent.java Tue Mar 17 19:21:54 2015 -0700 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2009, 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.sun.hotspot.tools.compiler; + +import java.io.PrintStream; + +public class TaskEvent extends BasicLogEvent { + private int level; + private String comment; + private Kind kind; + + enum Kind { + Enqueue, + Dequeue, + Finish + } + + public TaskEvent(double start, String id, int level, Kind kind) { + super(start, id); + this.level = level; + this.kind = kind; + } + + void setComment(String comment) { + this.comment = comment; + } + + String getComment() { + return comment; + } + + int getLevel() { + return level; + } + + Kind getKind() { + return kind; + } + + public void print(PrintStream stream) { + stream.printf("%s id='%s' level='%s' %s%n", start, id, level, kind); + } +}