blob: 379067f3071b416967780930c4740366001a174a [file] [log] [blame]
/*
* Copyright (c) 2009, 2015, 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;
import java.util.ArrayList;
/**
* One particular compilation, represented in the compilation log file as a
* {@code task} element.
*/
public class Compilation implements LogEvent {
/**
* The compilation ID.
*/
private int id;
/**
* Whether this is a compilation for on-stack replacement (OSR).
*/
private boolean osr;
/**
* The method being compiled.
*/
private Method method;
/**
* The {@linkplain CallSite scope} of this compilation. This is created as
* an empty {@link CallSite} instance, to be filled with data (and
* meaning) later on.
*/
private CallSite call = new CallSite();
/**
* In case a {@code late_inline} event occurs during the compilation, this
* field holds the information about it.
*/
private CallSite lateInlineCall = new CallSite();
/**
* The bytecode instruction index for on-stack replacement compilations; -1
* if this is not an OSR compilation.
*/
private int bci;
/**
* The method under compilation's invocation count.
*/
private String icount;
/**
* The method under compilation's backedge count.
*/
private String bcount;
/**
* Additional information for special compilations (e.g., adapters).
*/
private String special;
/**
* The name of the compiler performing this compilation.
*/
private String compiler;
/**
* Start time stamp.
*/
private double start;
/**
* End time stamp.
*/
private double end;
/**
* Trip count of the register allocator.
*/
private int attempts;
/**
* The compilation result (a native method).
*/
private NMethod nmethod;
/**
* The phases through which this compilation goes.
*/
private ArrayList<Phase> phases = new ArrayList<>(4);
/**
* In case this compilation fails, the reason for that.
*/
private String failureReason;
Compilation(int id) {
this.id = id;
}
void reset() {
call = new CallSite();
lateInlineCall = new CallSite();
phases = new ArrayList<>(4);
}
/**
* Get a compilation phase by name, or {@code null}.
*
* @param s the name of the phase to retrieve in this compilation.
*
* @return a compilation phase, or {@code null} if no phase with the given
* name is found.
*/
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;
}
public void setCompiler(String compiler) {
this.compiler = compiler;
}
public String getCompiler() {
return compiler;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getId());
sb.append(" ");
sb.append(getCompiler());
sb.append(" ");
sb.append(getMethod());
sb.append(" ");
sb.append(getIcount());
sb.append("+");
sb.append(getBcount());
sb.append("\n");
if (getCall() != null && getCall().getCalls() != null) {
for (CallSite site : getCall().getCalls()) {
sb.append(site);
sb.append("\n");
}
}
if (getLateInlineCall().getCalls() != null) {
sb.append("late inline:\n");
for (CallSite site : getLateInlineCall().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() ? getBCI() : -1;
stream.print(getId() + getMethod().decodeFlags(bc) + " " + compiler + " " + getMethod().format(bc));
}
}
public void print(PrintStream stream, boolean printID) {
print(stream, 0, printID, true, false);
}
public void print(PrintStream stream, boolean printID, boolean printInlining) {
print(stream, 0, printID, printInlining, false);
}
public void print(PrintStream stream, boolean printID, boolean printInlining, boolean printUncommonTraps) {
print(stream, 0, printID, printInlining, printUncommonTraps);
}
public void print(PrintStream stream, int indent, boolean printID, boolean printInlining, boolean printUncommonTraps) {
if (getMethod() == null) {
stream.println(getSpecial());
} else {
if (printID) {
stream.print(getId());
}
int bc = isOsr() ? getBCI() : -1;
stream.print(getMethod().decodeFlags(bc) + " " + compiler + " " + getMethod().format(bc));
stream.println();
if (getFailureReason() != null) {
stream.println("COMPILE SKIPPED: " + getFailureReason() + " (not retryable)");
}
if (printInlining && call.getCalls() != null) {
for (CallSite site : call.getCalls()) {
site.print(stream, indent + 2, printInlining, printUncommonTraps);
}
}
if (printUncommonTraps && call.getTraps() != null) {
for (UncommonTrap site : call.getTraps()) {
site.print(stream, indent + 2);
}
}
if (printInlining && lateInlineCall.getCalls() != null) {
stream.println("late inline:");
for (CallSite site : lateInlineCall.getCalls()) {
site.print(stream, indent + 2, printInlining, printUncommonTraps);
}
}
}
}
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 getBCI() {
return bci;
}
public void setBCI(int osrBci) {
this.bci = 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<Phase> getPhases() {
return phases;
}
public String getFailureReason() {
return failureReason;
}
public void setFailureReason(String failureReason) {
this.failureReason = failureReason;
}
public Method getMethod() {
return method;
}
/**
* Set the method under compilation. If it is already set, ignore the
* argument to avoid changing the method by post-parse inlining info.
*
* @param method the method under compilation. May be ignored.
*/
public void setMethod(Method method) {
if (getMethod() == null) {
this.method = method;
}
}
public CallSite getCall() {
return call;
}
public CallSite getLateInlineCall() {
return lateInlineCall;
}
public double getElapsedTime() {
return end - start;
}
public Compilation getCompilation() {
return this;
}
}