diff --git a/src/share/tools/LogCompilation/Makefile b/src/share/tools/LogCompilation/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..2a2e2a5d71ac06d1d9fb5a2a824cb6f483622fb7 --- /dev/null +++ b/src/share/tools/LogCompilation/Makefile @@ -0,0 +1,75 @@ +# +# Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, +# CA 95054 USA or visit www.sun.com if you need additional information or +# have any questions. +# +# +PKGLIST = \ +com.sun.hotspot.tools.compiler +#END PKGLIST + +FILELIST = com/sun/hotspot/tools/compiler/*.java + +ifneq "x$(ALT_BOOTDIR)" "x" + BOOTDIR := $(ALT_BOOTDIR) +endif + +ifeq "x$(BOOTDIR)" "x" + JDK_HOME := $(shell dirname $(shell which java))/.. +else + JDK_HOME := $(BOOTDIR) +endif + +isUnix := $(shell test -r c:/; echo $$?) + +ifeq "$(isUnix)" "1" + CPS := : +else + CPS := ";" +endif + +SRC_DIR = src +BUILD_DIR = build +OUTPUT_DIR = $(BUILD_DIR)/classes + +# gnumake 3.78.1 does not accept the *s, +# so use the shell to expand them +ALLFILES := $(patsubst %,$(SRC_DIR)/%,$(FILELIST)) +ALLFILES := $(shell /bin/ls $(ALLFILES)) + +JAVAC = $(JDK_HOME)/bin/javac +JAR = $(JDK_HOME)/bin/jar + +# Tagging it on because there's no reason not to run it +all: logc.jar + +logc.jar: filelist manifest.mf + @mkdir -p $(OUTPUT_DIR) + $(JAVAC) -source 1.5 -deprecation -sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) @filelist + $(JAR) cvfm logc.jar manifest.mf -C $(OUTPUT_DIR) com + +.PHONY: filelist +filelist: $(ALLFILES) + @rm -f $@ + @echo $(ALLFILES) > $@ + +clean:: + rm -rf filelist logc.jar + rm -rf $(BUILD_DIR) diff --git a/src/share/tools/LogCompilation/README b/src/share/tools/LogCompilation/README new file mode 100644 index 0000000000000000000000000000000000000000..ed3cbbc81215f77b63cb793bbbeee70bbf45c8da --- /dev/null +++ b/src/share/tools/LogCompilation/README @@ -0,0 +1,18 @@ +This is a very rough tool for parsing -XX:+LogCompilation output. +It's main purpose is to recreate output similar to +-XX:+PrintCompilation -XX:+PrintInlining output from a debug JVM. It +requires a 1.5 JDK to build and simply typing make should build it. + +It produces a jar file, logc.jar, that can be run on the +hotspot.log from LogCompilation output like this: + + java -jar logc.jar hotspot.log + +This will produce something like the normal PrintCompilation output. +Adding the -i option with also report inlining like PrintInlining. + +More information about the LogCompilation output can be found at + +http://wikis.sun.com/display/HotSpotInternals/LogCompilation+overview +http://wikis.sun.com/display/HotSpotInternals/PrintCompilation +http://wikis.sun.com/display/HotSpotInternals/LogCompilation+tool diff --git a/src/share/tools/LogCompilation/manifest.mf b/src/share/tools/LogCompilation/manifest.mf new file mode 100644 index 0000000000000000000000000000000000000000..62a36155dd05ccb6bc5fdb13f61239d28299b897 --- /dev/null +++ b/src/share/tools/LogCompilation/manifest.mf @@ -0,0 +1 @@ +Main-Class: com.sun.hotspot.tools.compiler.LogCompilation diff --git a/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/BasicLogEvent.java b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/BasicLogEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..8d9d630a474265f9c099b72d66aa773a22d460da --- /dev/null +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/BasicLogEvent.java @@ -0,0 +1,75 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package com.sun.hotspot.tools.compiler; + +import java.io.PrintStream; + +/** + * + * @author never + */ +public abstract class BasicLogEvent implements LogEvent { + + protected final String id; + protected final double start; + protected double end; + protected Compilation compilation; + + BasicLogEvent(double start, String id) { + this.start = start; + this.end = start; + this.id = id; + } + + public double getStart() { + return start; + } + + public double getEnd() { + return end; + } + + public void setEnd(double end) { + this.end = end; + } + + public double getElapsedTime() { + return ((int) ((getEnd() - getStart()) * 1000)) / 1000.0; + } + + public String getId() { + return id; + } + + public Compilation getCompilation() { + return compilation; + } + + public void setCompilation(Compilation compilation) { + this.compilation = compilation; + } + + abstract public void print(PrintStream stream); +} diff --git a/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java new file mode 100644 index 0000000000000000000000000000000000000000..bf96b1fbc91a20caf8f34fed3f3cb804d7eea78b --- /dev/null +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java @@ -0,0 +1,183 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package com.sun.hotspot.tools.compiler; + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + +public class CallSite { + + private int bci; + private Method method; + private int count; + private String receiver; + private int receiver_count; + private String reason; + private List calls; + + CallSite() { + } + + CallSite(int bci, Method m) { + this.bci = bci; + this.method = m; + } + + void add(CallSite site) { + if (getCalls() == null) { + setCalls(new ArrayList()); + } + getCalls().add(site); + } + + CallSite last() { + return last(-1); + } + + CallSite last(int fromEnd) { + return getCalls().get(getCalls().size() + fromEnd); + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + if (getReason() == null) { + sb.append(" @ " + getBci() + " " + getMethod()); + } else { + sb.append("- @ " + getBci() + " " + getMethod() + " " + getReason()); + } + sb.append("\n"); + if (getCalls() != null) { + for (CallSite site : getCalls()) { + sb.append(site); + sb.append("\n"); + } + } + return sb.toString(); + } + + public void print(PrintStream stream) { + print(stream, 0); + } + + void emit(PrintStream stream, int indent) { + for (int i = 0; i < indent; i++) { + stream.print(' '); + } + } + private static boolean compat = true; + + public void print(PrintStream stream, int indent) { + emit(stream, indent); + String m = getMethod().getHolder().replace('/', '.') + "::" + getMethod().getName(); + if (getReason() == null) { + stream.println(" @ " + getBci() + " " + m + " (" + getMethod().getBytes() + " bytes)"); + + } else { + if (isCompat()) { + stream.println(" @ " + getBci() + " " + m + " " + getReason()); + } else { + stream.println("- @ " + getBci() + " " + m + + " (" + getMethod().getBytes() + " bytes) " + getReason()); + } + } + if (getReceiver() != null) { + emit(stream, indent + 3); + // stream.println("type profile " + method.holder + " -> " + receiver + " (" + + // receiver_count + "/" + count + "," + (receiver_count * 100 / count) + "%)"); + stream.println("type profile " + getMethod().getHolder() + " -> " + getReceiver() + " (" + + (getReceiverCount() * 100 / getCount()) + "%)"); + } + if (getCalls() != null) { + for (CallSite site : getCalls()) { + site.print(stream, indent + 2); + } + } + } + + public int getBci() { + return bci; + } + + public void setBci(int bci) { + this.bci = bci; + } + + public Method getMethod() { + return method; + } + + public void setMethod(Method method) { + this.method = method; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public String getReceiver() { + return receiver; + } + + public void setReceiver(String receiver) { + this.receiver = receiver; + } + + public int getReceiverCount() { + return receiver_count; + } + + public void setReceiver_count(int receiver_count) { + this.receiver_count = receiver_count; + } + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } + + public List getCalls() { + return calls; + } + + public void setCalls(List calls) { + this.calls = calls; + } + + public static boolean isCompat() { + return compat; + } + + public static void setCompat(boolean aCompat) { + compat = aCompat; + } +} diff --git a/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java new file mode 100644 index 0000000000000000000000000000000000000000..3695ebd01e03152da21c1b2364749c143d57c1d0 --- /dev/null +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java @@ -0,0 +1,236 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package com.sun.hotspot.tools.compiler; + +import java.io.PrintStream; +import java.util.ArrayList; + +public class Compilation implements LogEvent { + + private int id; + private boolean osr; + private Method method; + private CallSite call = new CallSite(); + private int osrBci; + private String icount; + private String bcount; + private String special; + private double start; + private double end; + private int attempts; + private NMethod nmethod; + private ArrayList phases = new ArrayList(4); + private String failureReason; + + Compilation(int id) { + this.id = id; + } + + Phase getPhase(String s) { + for (Phase p : getPhases()) { + if (p.getName().equals(s)) { + return p; + } + } + return null; + } + + double getRegallocTime() { + return getPhase("regalloc").getElapsedTime(); + } + + public double getStart() { + return start; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getId()); + sb.append(" "); + sb.append(getMethod()); + sb.append(" "); + sb.append(getIcount()); + sb.append("+"); + sb.append(getBcount()); + sb.append("\n"); + for (CallSite site : getCall().getCalls()) { + sb.append(site); + sb.append("\n"); + } + return sb.toString(); + } + + public void printShort(PrintStream stream) { + if (getMethod() == null) { + stream.println(getSpecial()); + } else { + int bc = isOsr() ? getOsr_bci() : -1; + stream.print(getId() + getMethod().decodeFlags(bc) + getMethod().format(bc)); + } + } + + public void print(PrintStream stream) { + print(stream, 0, false); + } + + public void print(PrintStream stream, boolean printInlining) { + print(stream, 0, printInlining); + } + + public void print(PrintStream stream, int indent, boolean printInlining) { + if (getMethod() == null) { + stream.println(getSpecial()); + } else { + int bc = isOsr() ? getOsr_bci() : -1; + stream.print(getId() + getMethod().decodeFlags(bc) + getMethod().format(bc)); + stream.println(); + if (getFailureReason() != null) { + stream.println("COMPILE FAILED " + getFailureReason()); + } + if (printInlining && call.getCalls() != null) { + for (CallSite site : call.getCalls()) { + site.print(stream, indent + 2); + } + } + } + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public boolean isOsr() { + return osr; + } + + public void setOsr(boolean osr) { + this.osr = osr; + } + + public int getOsr_bci() { + return osrBci; + } + + public void setOsr_bci(int osrBci) { + this.osrBci = osrBci; + } + + public String getIcount() { + return icount; + } + + public void setICount(String icount) { + this.icount = icount; + } + + public String getBcount() { + return bcount; + } + + public void setBCount(String bcount) { + this.bcount = bcount; + } + + public String getSpecial() { + return special; + } + + public void setSpecial(String special) { + this.special = special; + } + + public void setStart(double start) { + this.start = start; + } + + public double getEnd() { + return end; + } + + public void setEnd(double end) { + this.end = end; + } + + public int getAttempts() { + return attempts; + } + + public void setAttempts(int attempts) { + this.attempts = attempts; + } + + public NMethod getNMethod() { + return nmethod; + } + + public void setNMethod(NMethod NMethod) { + this.nmethod = NMethod; + } + + public ArrayList getPhases() { + return phases; + } + + public void setPhases(ArrayList phases) { + this.setPhases(phases); + } + + public String getFailureReason() { + return failureReason; + } + + public void setFailureReason(String failureReason) { + this.failureReason = failureReason; + } + + public Method getMethod() { + return method; + } + + public void setMethod(Method method) { + this.method = method; + } + + public CallSite getCall() { + return call; + } + + public void setCall(CallSite call) { + this.call = call; + } + + public double getElapsedTime() { + return end - start; + } + + public Compilation getCompilation() { + return this; + } +} diff --git a/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Constants.java b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Constants.java new file mode 100644 index 0000000000000000000000000000000000000000..e06dd05db54ec39d0c50868e46f07f5bced96c7b --- /dev/null +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Constants.java @@ -0,0 +1,46 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package com.sun.hotspot.tools.compiler; + +interface Constants { + static final int JVM_ACC_PUBLIC = 0x0001; /* visible to everyone */ + static final int JVM_ACC_PRIVATE = 0x0002; /* visible only to the defining class */ + static final int JVM_ACC_PROTECTED = 0x0004; /* visible to subclasses */ + static final int JVM_ACC_STATIC = 0x0008; /* instance variable is static */ + static final int JVM_ACC_FINAL = 0x0010; /* no further subclassing, overriding */ + static final int JVM_ACC_SYNCHRONIZED = 0x0020; /* wrap method call in monitor lock */ + static final int JVM_ACC_SUPER = 0x0020; /* funky handling of invokespecial */ + static final int JVM_ACC_VOLATILE = 0x0040; /* can not cache in registers */ + static final int JVM_ACC_BRIDGE = 0x0040; /* bridge method generated by compiler */ + static final int JVM_ACC_TRANSIENT = 0x0080; /* not persistent */ + static final int JVM_ACC_VARARGS = 0x0080; /* method declared with variable number of args */ + static final int JVM_ACC_NATIVE = 0x0100; /* implemented in C */ + static final int JVM_ACC_INTERFACE = 0x0200; /* class is an interface */ + static final int JVM_ACC_ABSTRACT = 0x0400; /* no definition provided */ + static final int JVM_ACC_STRICT = 0x0800; /* strict floating point */ + static final int JVM_ACC_SYNTHETIC = 0x1000; /* compiler-generated class, method or field */ + static final int JVM_ACC_ANNOTATION = 0x2000; /* annotation type */ + static final int JVM_ACC_ENUM = 0x4000; /* field is declared as element of enum */ +} diff --git a/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCleanupReader.java b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCleanupReader.java new file mode 100644 index 0000000000000000000000000000000000000000..eb3140c171b7a930be789603f991c6d5f9e6b706 --- /dev/null +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCleanupReader.java @@ -0,0 +1,212 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package com.sun.hotspot.tools.compiler; + +import java.io.*; +import java.util.regex.*; + +/** + * This class is a filter class to deal with malformed XML that used + * to be produced by the JVM when generating LogCompilation. In 1.6 + * and later releases it shouldn't be required. + * @author never + */ + +class LogCleanupReader extends Reader { + private Reader reader; + + private char[] buffer = new char[4096]; + + private int bufferCount; + + private int bufferOffset; + + private char[] line = new char[1024]; + + private int index; + + private int length; + + private char[] one = new char[1]; + + LogCleanupReader(Reader r) { + reader = r; + } + + static final private Matcher pattern = Pattern.compile(".+ compile_id='[0-9]+'.*( compile_id='[0-9]+)").matcher(""); + static final private Matcher pattern2 = Pattern.compile("' (C[12]) compile_id=").matcher(""); + static final private Matcher pattern3 = Pattern.compile("'(destroy_vm)/").matcher(""); + + private void fill() throws IOException { + rawFill(); + if (length != -1) { + boolean changed = false; + String s = new String(line, 0, length); + String orig = s; + + pattern2.reset(s); + if (pattern2.find()) { + s = s.substring(0, pattern2.start(1)) + s.substring(pattern2.end(1) + 1); + changed = true; + } + + pattern.reset(s); + if (pattern.lookingAt()) { + s = s.substring(0, pattern.start(1)) + s.substring(pattern.end(1) + 1); + changed = true; + } + + pattern3.reset(s); + if (pattern3.find()) { + s = s.substring(0, pattern3.start(1)) + s.substring(pattern3.end(1)); + changed = true; + } + + if (changed) { + s.getChars(0, s.length(), line, 0); + length = s.length(); + } + } + } + + private void rawFill() throws IOException { + if (bufferCount == -1) { + length = -1; + return; + } + + int i = 0; + boolean fillNonEOL = true; + outer: + while (true) { + if (fillNonEOL) { + int p; + for (p = bufferOffset; p < bufferCount; p++) { + char c = buffer[p]; + if (c == '\r' || c == '\n') { + bufferOffset = p; + fillNonEOL = false; + continue outer; + } + if (i >= line.length) { + // copy and enlarge the line array + char[] newLine = new char[line.length * 2]; + System.arraycopy(line, 0, newLine, 0, line.length); + line = newLine; + } + line[i++] = c; + } + bufferOffset = p; + } else { + int p; + for (p = bufferOffset; p < bufferCount; p++) { + char c = buffer[p]; + if (c != '\r' && c != '\n') { + bufferOffset = p; + length = i; + index = 0; + return; + } + line[i++] = c; + } + bufferOffset = p; + } + if (bufferCount == -1) { + if (i == 0) { + length = -1; + } else { + length = i; + } + index = 0; + return; + } + if (bufferOffset != bufferCount) { + System.out.println(bufferOffset); + System.out.println(bufferCount); + throw new InternalError("how did we get here"); + } + // load more data and try again. + bufferCount = reader.read(buffer, 0, buffer.length); + bufferOffset = 0; + } + } + + public int read() throws java.io.IOException { + read(one, 0, 1); + return one[0]; + } + + public int read(char[] buffer) throws java.io.IOException { + return read(buffer, 0, buffer.length); + } + + public int read(char[] b, int off, int len) throws java.io.IOException { + if (length == -1) { + return -1; + } + + if (index == length) { + fill(); + if (length == -1) { + return -1; + } + } + int n = Math.min(length - index, Math.min(b.length - off, len)); + // System.out.printf("%d %d %d %d %d\n", index, length, off, len, n); + System.arraycopy(line, index, b, off, n); + index += n; + return n; + } + + public long skip(long n) throws java.io.IOException { + long result = n; + while (n-- > 0) read(); + return result; + } + + public boolean ready() throws java.io.IOException { + return reader.ready() || (line != null && length > 0); + } + + public boolean markSupported() { + return false; + } + + public void mark(int unused) throws java.io.IOException { + throw new UnsupportedOperationException("mark not supported"); + } + + public void reset() throws java.io.IOException { + reader.reset(); + line = null; + index = 0; + } + + public void close() throws java.io.IOException { + reader.close(); + line = null; + index = 0; + } +} diff --git a/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCompilation.java b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCompilation.java new file mode 100644 index 0000000000000000000000000000000000000000..5edbad656eefc5971b2ac65e2a112c7ccfb9f86f --- /dev/null +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogCompilation.java @@ -0,0 +1,177 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +/** + * The main command line driver of a parser for LogCompilation output. + * @author never + */ + +package com.sun.hotspot.tools.compiler; + +import java.io.PrintStream; +import java.util.*; +import org.xml.sax.*; +import org.xml.sax.helpers.*; + +public class LogCompilation extends DefaultHandler implements ErrorHandler, Constants { + + public static void usage(int exitcode) { + System.out.println("Usage: LogCompilation [ -v ] [ -c ] [ -s ] [ -e | -N ] file1 ..."); + System.out.println(" -c: clean up malformed 1.5 xml"); + System.out.println(" -i: print inlining decisions"); + System.out.println(" -S: print compilation statistics"); + System.out.println(" -s: sort events by start time"); + System.out.println(" -e: sort events by elapsed time"); + System.out.println(" -N: sort events by name and start"); + System.exit(exitcode); + } + + public static void main(String[] args) throws Exception { + Comparator defaultSort = LogParser.sortByStart; + boolean statistics = false; + boolean printInlining = false; + boolean cleanup = false; + int index = 0; + + while (args.length > index) { + if (args[index].equals("-e")) { + defaultSort = LogParser.sortByElapsed; + index++; + } else if (args[index].equals("-n")) { + defaultSort = LogParser.sortByNameAndStart; + index++; + } else if (args[index].equals("-s")) { + defaultSort = LogParser.sortByStart; + index++; + } else if (args[index].equals("-c")) { + cleanup = true; + index++; + } else if (args[index].equals("-S")) { + statistics = true; + index++; + } else if (args[index].equals("-h")) { + usage(0); + } else if (args[index].equals("-i")) { + printInlining = true; + index++; + } else { + break; + } + } + + if (index >= args.length) { + usage(1); + } + + while (index < args.length) { + ArrayList events = LogParser.parse(args[index], cleanup); + + if (statistics) { + printStatistics(events, System.out); + } else { + Collections.sort(events, defaultSort); + for (LogEvent c : events) { + if (printInlining && c instanceof Compilation) { + Compilation comp = (Compilation)c; + comp.print(System.out, true); + } else { + c.print(System.out); + } + } + } + index++; + } + } + + public static void printStatistics(ArrayList events, PrintStream out) { + long cacheSize = 0; + long maxCacheSize = 0; + int nmethodsCreated = 0; + int nmethodsLive = 0; + int[] attempts = new int[32]; + double regallocTime = 0; + int maxattempts = 0; + + LinkedHashMap phaseTime = new LinkedHashMap(7); + LinkedHashMap phaseNodes = new LinkedHashMap(7); + double elapsed = 0; + + for (LogEvent e : events) { + if (e instanceof Compilation) { + Compilation c = (Compilation) e; + c.printShort(out); + out.printf(" %6.4f\n", c.getElapsedTime()); + attempts[c.getAttempts()]++; + maxattempts = Math.max(maxattempts,c.getAttempts()); + elapsed += c.getElapsedTime(); + for (Phase phase : c.getPhases()) { + out.printf("\t%s %6.4f\n", phase.getName(), phase.getElapsedTime()); + Double v = phaseTime.get(phase.getName()); + if (v == null) { + v = Double.valueOf(0.0); + } + phaseTime.put(phase.getName(), Double.valueOf(v.doubleValue() + phase.getElapsedTime())); + + Integer v2 = phaseNodes.get(phase.getName()); + if (v2 == null) { + v2 = Integer.valueOf(0); + } + phaseNodes.put(phase.getName(), Integer.valueOf(v2.intValue() + phase.getNodes())); + } + } else if (e instanceof MakeNotEntrantEvent) { + MakeNotEntrantEvent mne = (MakeNotEntrantEvent) e; + NMethod nm = mne.getNMethod(); + if (mne.isZombie()) { + if (nm == null) { + System.err.println(mne.getId()); + } + cacheSize -= nm.getSize(); + nmethodsLive--; + } + } else if (e instanceof NMethod) { + nmethodsLive++; + nmethodsCreated++; + NMethod nm = (NMethod) e; + cacheSize += nm.getSize(); + maxCacheSize = Math.max(cacheSize, maxCacheSize); + } + } + out.printf("NMethods: %d created %d live %d bytes (%d peak) in the code cache\n", + nmethodsCreated, nmethodsLive, cacheSize, maxCacheSize); + out.println("Phase times:"); + for (String name : phaseTime.keySet()) { + Double v = phaseTime.get(name); + Integer v2 = phaseNodes.get(name); + out.printf("%20s %6.4f %d\n", name, v.doubleValue(), v2.intValue()); + } + out.printf("%20s %6.4f\n", "total", elapsed); + + if (maxattempts > 0) { + out.println("Distribution of regalloc passes:"); + for (int i = 0; i <= maxattempts; i++) { + out.printf("%2d %8d\n", i, attempts[i]); + } + } + } +} diff --git a/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogEvent.java b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..69f6d385b0e278ee0a3294e1e1d3948bca657529 --- /dev/null +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogEvent.java @@ -0,0 +1,38 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package com.sun.hotspot.tools.compiler; + +import java.io.PrintStream; +import java.util.*; + +public interface LogEvent { + public double getStart(); + + public double getElapsedTime(); + + public Compilation getCompilation(); + + public void print(PrintStream stream); +} diff --git a/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java new file mode 100644 index 0000000000000000000000000000000000000000..bfff7dfa916093c473674e4fb83dc9fe2dfd787f --- /dev/null +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java @@ -0,0 +1,430 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +/** + * A SAX based parser of LogCompilation output from HotSpot. It takes a complete + * @author never + */ + +package com.sun.hotspot.tools.compiler; + +import java.io.FileReader; +import java.io.Reader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Stack; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import org.xml.sax.Attributes; +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.helpers.DefaultHandler; + +public class LogParser extends DefaultHandler implements ErrorHandler, Constants { + + static final HashMap typeMap; + static { + typeMap = new HashMap(); + typeMap.put("[I", "int[]"); + typeMap.put("[C", "char[]"); + typeMap.put("[Z", "boolean[]"); + typeMap.put("[L", "Object[]"); + typeMap.put("[B", "byte[]"); + } + + static Comparator sortByStart = new Comparator() { + + public int compare(LogEvent a, LogEvent b) { + double difference = (a.getStart() - b.getStart()); + if (difference < 0) { + return -1; + } + if (difference > 0) { + return 1; + } + return 0; + } + + @Override + public boolean equals(Object other) { + return false; + } + + @Override + public int hashCode() { + return 7; + } + }; + static Comparator sortByNameAndStart = new Comparator() { + + public int compare(LogEvent a, LogEvent b) { + Compilation c1 = a.getCompilation(); + Compilation c2 = b.getCompilation(); + if (c1 != null && c2 != null) { + int result = c1.getMethod().toString().compareTo(c2.getMethod().toString()); + if (result != 0) { + return result; + } + } + double difference = (a.getStart() - b.getStart()); + if (difference < 0) { + return -1; + } + if (difference > 0) { + return 1; + } + return 0; + } + + public boolean equals(Object other) { + return false; + } + + @Override + public int hashCode() { + return 7; + } + }; + static Comparator sortByElapsed = new Comparator() { + + public int compare(LogEvent a, LogEvent b) { + double difference = (a.getElapsedTime() - b.getElapsedTime()); + if (difference < 0) { + return -1; + } + if (difference > 0) { + return 1; + } + return 0; + } + + @Override + public boolean equals(Object other) { + return false; + } + + @Override + public int hashCode() { + return 7; + } + }; + + private ArrayList events = new ArrayList(); + + private HashMap types = new HashMap(); + private HashMap methods = new HashMap(); + private LinkedHashMap nmethods = new LinkedHashMap(); + private HashMap compiles = new HashMap(); + private String failureReason; + private int bci; + private Stack scopes = new Stack(); + private Compilation compile; + private CallSite site; + private Stack phaseStack = new Stack(); + private UncommonTrapEvent currentTrap; + + long parseLong(String l) { + try { + return Long.decode(l).longValue(); + } catch (NumberFormatException nfe) { + int split = l.length() - 8; + String s1 = "0x" + l.substring(split); + String s2 = l.substring(0, split); + long v1 = Long.decode(s1).longValue() & 0xffffffffL; + long v2 = (Long.decode(s2).longValue() & 0xffffffffL) << 32; + if (!l.equals("0x" + Long.toHexString(v1 + v2))) { + System.out.println(l); + System.out.println(s1); + System.out.println(s2); + System.out.println(v1); + System.out.println(v2); + System.out.println(Long.toHexString(v1 + v2)); + throw new InternalError("bad conversion"); + } + return v1 + v2; + } + } + + public static ArrayList parse(String file, boolean cleanup) throws Exception { + return parse(new FileReader(file), cleanup); + } + + public static ArrayList parse(Reader reader, boolean cleanup) throws Exception { + // Create the XML input factory + SAXParserFactory factory = SAXParserFactory.newInstance(); + + // Create the XML LogEvent reader + SAXParser p = factory.newSAXParser(); + + if (cleanup) { + // some versions of the log have slightly malformed XML, so clean it + // up before passing it to SAX + reader = new LogCleanupReader(reader); + } + + LogParser log = new LogParser(); + p.parse(new InputSource(reader), log); + + // Associate compilations with their NMethods + for (NMethod nm : log.nmethods.values()) { + Compilation c = log.compiles.get(nm.getId()); + nm.setCompilation(c); + // Native wrappers for methods don't have a compilation + if (c != null) { + c.setNMethod(nm); + } + } + + // Initially we want the LogEvent log sorted by timestamp + Collections.sort(log.events, sortByStart); + + return log.events; + } + + String search(Attributes attr, String name) { + return search(attr, name, null); + } + + String search(Attributes attr, String name, String defaultValue) { + String result = attr.getValue(name); + if (result != null) { + return result; + } + if (defaultValue != null) { + return defaultValue; + } + for (int i = 0; i < attr.getLength(); i++) { + System.out.println(attr.getQName(i) + " " + attr.getValue(attr.getQName(i))); + } + throw new InternalError("can't find " + name); + } + int indent = 0; + String compile_id; + + String type(String id) { + String result = types.get(id); + if (result == null) { + throw new InternalError(id); + } + String remapped = typeMap.get(result); + if (remapped != null) { + return remapped; + } + return result; + } + + void type(String id, String name) { + assert type(id) == null; + types.put(id, name); + } + + Method method(String id) { + Method result = methods.get(id); + if (result == null) { + throw new InternalError(id); + } + return result; + } + + public String makeId(Attributes atts) { + String id = atts.getValue("compile_id"); + String kind = atts.getValue("kind"); + if (kind != null && kind.equals("osr")) { + id += "%"; + } + return id; + } + + @Override + public void startElement(String uri, + String localName, + String qname, + Attributes atts) { + if (qname.equals("phase")) { + Phase p = new Phase(search(atts, "name"), + Double.parseDouble(search(atts, "stamp")), + Integer.parseInt(search(atts, "nodes"))); + phaseStack.push(p); + } else if (qname.equals("phase_done")) { + Phase p = phaseStack.pop(); + p.setEndNodes(Integer.parseInt(search(atts, "nodes"))); + p.setEnd(Double.parseDouble(search(atts, "stamp"))); + compile.getPhases().add(p); + } else if (qname.equals("task")) { + compile = new Compilation(Integer.parseInt(search(atts, "compile_id", "-1"))); + compile.setStart(Double.parseDouble(search(atts, "stamp"))); + compile.setICount(search(atts, "count", "0")); + compile.setBCount(search(atts, "backedge_count", "0")); + + String method = atts.getValue("method"); + int space = method.indexOf(' '); + method = method.substring(0, space) + "::" + + method.substring(space + 1, method.indexOf(' ', space + 1) + 1); + String compiler = atts.getValue("compiler"); + if (compiler == null) { + compiler = ""; + } + String kind = atts.getValue("compile_kind"); + if (kind == null) { + kind = "normal"; + } + if (kind.equals("osr")) { + compile.setOsr(true); + compile.setOsr_bci(Integer.parseInt(search(atts, "osr_bci"))); + } else if (kind.equals("c2i")) { + compile.setSpecial("--- adapter " + method); + } else { + compile.setSpecial(compile.getId() + " " + method + " (0 bytes)"); + } + events.add(compile); + compiles.put(makeId(atts), compile); + } else if (qname.equals("type")) { + type(search(atts, "id"), search(atts, "name")); + } else if (qname.equals("bc")) { + bci = Integer.parseInt(search(atts, "bci")); + } else if (qname.equals("klass")) { + type(search(atts, "id"), search(atts, "name")); + } else if (qname.equals("method")) { + String id = search(atts, "id"); + Method m = new Method(); + m.setHolder(type(search(atts, "holder"))); + m.setName(search(atts, "name")); + m.setReturnType(type(search(atts, "return"))); + m.setArguments(search(atts, "arguments", "void")); + m.setBytes(search(atts, "bytes")); + m.setIICount(search(atts, "iicount")); + m.setFlags(search(atts, "flags")); + methods.put(id, m); + } else if (qname.equals("call")) { + site = new CallSite(bci, method(search(atts, "method"))); + site.setCount(Integer.parseInt(search(atts, "count"))); + String receiver = atts.getValue("receiver"); + if (receiver != null) { + site.setReceiver(type(receiver)); + site.setReceiver_count(Integer.parseInt(search(atts, "receiver_count"))); + } + scopes.peek().add(site); + } else if (qname.equals("regalloc")) { + compile.setAttempts(Integer.parseInt(search(atts, "attempts"))); + } else if (qname.equals("inline_fail")) { + scopes.peek().last().setReason(search(atts, "reason")); + } else if (qname.equals("failure")) { + failureReason = search(atts, "reason"); + } else if (qname.equals("task_done")) { + compile.setEnd(Double.parseDouble(search(atts, "stamp"))); + if (Integer.parseInt(search(atts, "success")) == 0) { + compile.setFailureReason(failureReason); + } + } else if (qname.equals("make_not_entrant")) { + String id = makeId(atts); + NMethod nm = nmethods.get(id); + if (nm == null) throw new InternalError(); + LogEvent e = new MakeNotEntrantEvent(Double.parseDouble(search(atts, "stamp")), id, + atts.getValue("zombie") != null, nm); + events.add(e); + } else if (qname.equals("uncommon_trap")) { + String id = atts.getValue("compile_id"); + if (id != null) { + id = makeId(atts); + currentTrap = new UncommonTrapEvent(Double.parseDouble(search(atts, "stamp")), + id, + atts.getValue("reason"), + atts.getValue("action"), + Integer.parseInt(search(atts, "count", "0"))); + events.add(currentTrap); + } else { + // uncommon trap inserted during parsing. + // ignore for now + } + } else if (qname.equals("jvms")) { + // + if (currentTrap != null) { + currentTrap.addJVMS(atts.getValue("method"), Integer.parseInt(atts.getValue("bci"))); + } else { + System.err.println("Missing uncommon_trap for jvms"); + } + } else if (qname.equals("nmethod")) { + String id = makeId(atts); + NMethod nm = new NMethod(Double.parseDouble(search(atts, "stamp")), + id, + parseLong(atts.getValue("address")), + parseLong(atts.getValue("size"))); + nmethods.put(id, nm); + events.add(nm); + } else if (qname.equals("parse")) { + Method m = method(search(atts, "method")); + if (scopes.size() == 0) { + compile.setMethod(m); + scopes.push(compile.getCall()); + } else { + if (site.getMethod() == m) { + scopes.push(site); + } else if (scopes.peek().getCalls().size() > 2 && m == scopes.peek().last(-2).getMethod()) { + scopes.push(scopes.peek().last(-2)); + } else { + System.out.println(site.getMethod()); + System.out.println(m); + throw new InternalError("call site and parse don't match"); + } + } + } + } + + @Override + public void endElement(String uri, + String localName, + String qname) { + if (qname.equals("parse")) { + indent -= 2; + scopes.pop(); + } else if (qname.equals("uncommon_trap")) { + currentTrap = null; + } else if (qname.equals("task")) { + types.clear(); + methods.clear(); + site = null; + } + } + + @Override + public void warning(org.xml.sax.SAXParseException e) { + System.err.println(e.getMessage() + " at line " + e.getLineNumber() + ", column " + e.getColumnNumber()); + e.printStackTrace(); + } + + @Override + public void error(org.xml.sax.SAXParseException e) { + System.err.println(e.getMessage() + " at line " + e.getLineNumber() + ", column " + e.getColumnNumber()); + e.printStackTrace(); + } + + @Override + public void fatalError(org.xml.sax.SAXParseException e) { + System.err.println(e.getMessage() + " at line " + e.getLineNumber() + ", column " + e.getColumnNumber()); + e.printStackTrace(); + } +} diff --git a/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/MakeNotEntrantEvent.java b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/MakeNotEntrantEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..2b3fc56b35993312f6f9ac1a102f72e1cf9811e8 --- /dev/null +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/MakeNotEntrantEvent.java @@ -0,0 +1,55 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package com.sun.hotspot.tools.compiler; + +import java.io.PrintStream; + +class MakeNotEntrantEvent extends BasicLogEvent { + private final boolean zombie; + + private NMethod nmethod; + + MakeNotEntrantEvent(double s, String i, boolean z, NMethod nm) { + super(s, i); + zombie = z; + nmethod = nm; + } + + public NMethod getNMethod() { + return nmethod; + } + + public void print(PrintStream stream) { + if (isZombie()) { + stream.printf("%s make_zombie\n", getId()); + } else { + stream.printf("%s make_not_entrant\n", getId()); + } + } + + public boolean isZombie() { + return zombie; + } +} diff --git a/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Method.java b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Method.java new file mode 100644 index 0000000000000000000000000000000000000000..f2c9a9c710b2c207aee3b731a7c05bf2b9f9028e --- /dev/null +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Method.java @@ -0,0 +1,120 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package com.sun.hotspot.tools.compiler; + +import java.util.Arrays; + +public class Method implements Constants { + + private String holder; + private String name; + private String returnType; + private String arguments; + private String bytes; + private String iicount; + private String flags; + + String decodeFlags(int osr_bci) { + int f = Integer.parseInt(getFlags()); + char[] c = new char[4]; + Arrays.fill(c, ' '); + if (osr_bci >= 0) { + c[0] = '%'; + } + if ((f & JVM_ACC_SYNCHRONIZED) != 0) { + c[1] = 's'; + } + return new String(c); + } + + String format(int osr_bci) { + if (osr_bci >= 0) { + return getHolder().replace('/', '.') + "::" + getName() + " @ " + osr_bci + " (" + getBytes() + " bytes)"; + } else { + return getHolder().replace('/', '.') + "::" + getName() + " (" + getBytes() + " bytes)"; + } + } + + @Override + public String toString() { + return getHolder().replace('/', '.') + "::" + getName() + " (" + getBytes() + " bytes)"; + } + + public String getHolder() { + return holder; + } + + public void setHolder(String holder) { + this.holder = holder; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getReturnType() { + return returnType; + } + + public void setReturnType(String returnType) { + this.returnType = returnType; + } + + public String getArguments() { + return arguments; + } + + public void setArguments(String arguments) { + this.arguments = arguments; + } + + public String getBytes() { + return bytes; + } + + public void setBytes(String bytes) { + this.bytes = bytes; + } + + public String getIICount() { + return iicount; + } + + public void setIICount(String iicount) { + this.iicount = iicount; + } + + public String getFlags() { + return flags; + } + + public void setFlags(String flags) { + this.flags = flags; + } +} diff --git a/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/NMethod.java b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/NMethod.java new file mode 100644 index 0000000000000000000000000000000000000000..8fb277d00d6ba3c42634b2775150d5378dc3dae2 --- /dev/null +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/NMethod.java @@ -0,0 +1,60 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package com.sun.hotspot.tools.compiler; + +import java.io.PrintStream; + +public class NMethod extends BasicLogEvent { + + private long address; + private long size; + + NMethod(double s, String i, long a, long sz) { + super(s, i); + address = a; + size = sz; + } + + public void print(PrintStream out) { + // XXX Currently we do nothing + // throw new InternalError(); + } + + public long getAddress() { + return address; + } + + public void setAddress(long address) { + this.address = address; + } + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } +} diff --git a/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Phase.java b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Phase.java new file mode 100644 index 0000000000000000000000000000000000000000..8c29149a2171592b97a5742cc43f8c4b97eacf38 --- /dev/null +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Phase.java @@ -0,0 +1,63 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package com.sun.hotspot.tools.compiler; + +import java.io.PrintStream; + +public class Phase extends BasicLogEvent { + + private final int startNodes; + private int endNodes; + + Phase(String n, double s, int nodes) { + super(s, n); + startNodes = nodes; + } + + int getNodes() { + return getStartNodes(); + } + + void setEndNodes(int n) { + endNodes = n; + } + + public String getName() { + return getId(); + } + + public int getStartNodes() { + return startNodes; + } + + public int getEndNodes() { + return endNodes; + } + + @Override + public void print(PrintStream stream) { + throw new UnsupportedOperationException("Not supported yet."); + } +} diff --git a/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/UncommonTrapEvent.java b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/UncommonTrapEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..894cbdc7724b9bc27482ccfe820844bdbdbc99f8 --- /dev/null +++ b/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/UncommonTrapEvent.java @@ -0,0 +1,84 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package com.sun.hotspot.tools.compiler; + +import java.io.PrintStream; + +class UncommonTrapEvent extends BasicLogEvent { + + private final String reason; + private final String action; + private int count; + private String jvms = ""; + + UncommonTrapEvent(double s, String i, String r, String a, int c) { + super(s, i); + reason = r; + action = a; + count = c; + } + + + public void addJVMS(String method, int bci) { + setJvms(getJvms() + " @" + bci + " " + method + "\n"); + } + + public void updateCount(UncommonTrapEvent trap) { + setCount(Math.max(getCount(), trap.getCount())); + } + + public void print(PrintStream stream) { + stream.printf("%s uncommon trap %s %s\n", getId(), getReason(), getAction()); + stream.print(getJvms()); + } + + public String getReason() { + return reason; + } + + public String getAction() { + return action; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public String getJvms() { + return jvms; + } + + public void setJvms(String jvms) { + this.jvms = jvms; + } + + public void setCompilation(Compilation compilation) { + this.compilation = compilation; + } +}