mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 19:14:38 +02:00
8043638: Multiple compilation attempts break LogCompulation, lead to confusing PrintInlining output
Dumps inlining only for last compilation attempt. Fix LogCompilation tool so it handles multiple compilation attempts. Reviewed-by: vlivanov, kvn
This commit is contained in:
parent
a7d8aec5fb
commit
ee80d81323
6 changed files with 72 additions and 12 deletions
|
@ -231,6 +231,9 @@ public class CallSite {
|
||||||
// identical call sites with the same method name/bci are
|
// identical call sites with the same method name/bci are
|
||||||
// possible so we have to try them all until we find the late
|
// possible so we have to try them all until we find the late
|
||||||
// inline call site that has a matching inline id.
|
// inline call site that has a matching inline id.
|
||||||
|
if (calls == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
CallSite site = sites.pop();
|
CallSite site = sites.pop();
|
||||||
for (CallSite c : calls) {
|
for (CallSite c : calls) {
|
||||||
if (c.matches(site)) {
|
if (c.matches(site)) {
|
||||||
|
@ -250,6 +253,27 @@ public class CallSite {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ArrayDeque<CallSite> findCallSite2(CallSite site) {
|
||||||
|
if (calls == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (CallSite c : calls) {
|
||||||
|
if (c.matches(site)) {
|
||||||
|
ArrayDeque<CallSite> stack = new ArrayDeque<CallSite>();
|
||||||
|
stack.push(c);
|
||||||
|
return stack;
|
||||||
|
} else {
|
||||||
|
ArrayDeque<CallSite> stack = c.findCallSite2(site);
|
||||||
|
if (stack != null) {
|
||||||
|
stack.push(c);
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public long getInlineId() {
|
public long getInlineId() {
|
||||||
return inlineId;
|
return inlineId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,12 @@ public class Compilation implements LogEvent {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
call = new CallSite();
|
||||||
|
lateInlineCall = new CallSite();
|
||||||
|
phases = new ArrayList<Phase>(4);
|
||||||
|
}
|
||||||
|
|
||||||
Phase getPhase(String s) {
|
Phase getPhase(String s) {
|
||||||
for (Phase p : getPhases()) {
|
for (Phase p : getPhases()) {
|
||||||
if (p.getName().equals(s)) {
|
if (p.getName().equals(s)) {
|
||||||
|
@ -212,10 +218,6 @@ public class Compilation implements LogEvent {
|
||||||
return phases;
|
return phases;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPhases(ArrayList<Phase> phases) {
|
|
||||||
this.setPhases(phases);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFailureReason() {
|
public String getFailureReason() {
|
||||||
return failureReason;
|
return failureReason;
|
||||||
}
|
}
|
||||||
|
@ -240,10 +242,6 @@ public class Compilation implements LogEvent {
|
||||||
return call;
|
return call;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCall(CallSite call) {
|
|
||||||
this.call = call;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CallSite getLateInlineCall() {
|
public CallSite getLateInlineCall() {
|
||||||
return lateInlineCall;
|
return lateInlineCall;
|
||||||
}
|
}
|
||||||
|
|
|
@ -395,6 +395,7 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants
|
||||||
compile.setEnd(Double.parseDouble(search(atts, "stamp")));
|
compile.setEnd(Double.parseDouble(search(atts, "stamp")));
|
||||||
if (Integer.parseInt(search(atts, "success")) == 0) {
|
if (Integer.parseInt(search(atts, "success")) == 0) {
|
||||||
compile.setFailureReason(failureReason);
|
compile.setFailureReason(failureReason);
|
||||||
|
failureReason = null;
|
||||||
}
|
}
|
||||||
} else if (qname.equals("make_not_entrant")) {
|
} else if (qname.equals("make_not_entrant")) {
|
||||||
String id = makeId(atts);
|
String id = makeId(atts);
|
||||||
|
@ -451,6 +452,12 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants
|
||||||
nmethods.put(id, nm);
|
nmethods.put(id, nm);
|
||||||
events.add(nm);
|
events.add(nm);
|
||||||
} else if (qname.equals("parse")) {
|
} else if (qname.equals("parse")) {
|
||||||
|
if (failureReason != null && scopes.size() == 0 && !lateInlining) {
|
||||||
|
failureReason = null;
|
||||||
|
compile.reset();
|
||||||
|
site = compile.getCall();
|
||||||
|
}
|
||||||
|
|
||||||
if (methodHandleSite != null) {
|
if (methodHandleSite != null) {
|
||||||
throw new InternalError("method handle site should have been replaced");
|
throw new InternalError("method handle site should have been replaced");
|
||||||
}
|
}
|
||||||
|
@ -529,6 +536,18 @@ public class LogParser extends DefaultHandler implements ErrorHandler, Constants
|
||||||
|
|
||||||
site = compile.getCall().findCallSite(thisCallScopes);
|
site = compile.getCall().findCallSite(thisCallScopes);
|
||||||
if (site == null) {
|
if (site == null) {
|
||||||
|
System.out.println("call scopes:");
|
||||||
|
for (CallSite c : thisCallScopes) {
|
||||||
|
System.out.println(c.getMethod() + " " + c.getBci() + " " + c.getInlineId());
|
||||||
|
}
|
||||||
|
CallSite c = thisCallScopes.getLast();
|
||||||
|
if (c.getInlineId() != 0) {
|
||||||
|
System.out.println("Looking for call site in entire tree:");
|
||||||
|
ArrayDeque<CallSite> stack = compile.getCall().findCallSite2(c);
|
||||||
|
for (CallSite c2 : stack) {
|
||||||
|
System.out.println(c2.getMethod() + " " + c2.getBci() + " " + c2.getInlineId());
|
||||||
|
}
|
||||||
|
}
|
||||||
System.out.println(caller.getMethod() + " bci: " + bci);
|
System.out.println(caller.getMethod() + " bci: " + bci);
|
||||||
throw new InternalError("couldn't find call site");
|
throw new InternalError("couldn't find call site");
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,6 +155,9 @@ void C2Compiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// print inlining for last compilation only
|
||||||
|
C.dump_print_inlining();
|
||||||
|
|
||||||
// No retry; just break the loop.
|
// No retry; just break the loop.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -672,6 +672,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
|
||||||
_print_inlining_list(NULL),
|
_print_inlining_list(NULL),
|
||||||
_print_inlining_stream(NULL),
|
_print_inlining_stream(NULL),
|
||||||
_print_inlining_idx(0),
|
_print_inlining_idx(0),
|
||||||
|
_print_inlining_output(NULL),
|
||||||
_preserve_jvm_state(0),
|
_preserve_jvm_state(0),
|
||||||
_interpreter_frame_size(0) {
|
_interpreter_frame_size(0) {
|
||||||
C = this;
|
C = this;
|
||||||
|
@ -978,6 +979,7 @@ Compile::Compile( ciEnv* ci_env,
|
||||||
_print_inlining_list(NULL),
|
_print_inlining_list(NULL),
|
||||||
_print_inlining_stream(NULL),
|
_print_inlining_stream(NULL),
|
||||||
_print_inlining_idx(0),
|
_print_inlining_idx(0),
|
||||||
|
_print_inlining_output(NULL),
|
||||||
_preserve_jvm_state(0),
|
_preserve_jvm_state(0),
|
||||||
_allowed_reasons(0),
|
_allowed_reasons(0),
|
||||||
_interpreter_frame_size(0) {
|
_interpreter_frame_size(0) {
|
||||||
|
@ -2207,7 +2209,7 @@ void Compile::Optimize() {
|
||||||
|
|
||||||
} // (End scope of igvn; run destructor if necessary for asserts.)
|
} // (End scope of igvn; run destructor if necessary for asserts.)
|
||||||
|
|
||||||
dump_inlining();
|
process_print_inlining();
|
||||||
// A method with only infinite loops has no edges entering loops from root
|
// A method with only infinite loops has no edges entering loops from root
|
||||||
{
|
{
|
||||||
NOT_PRODUCT( TracePhase t2("graphReshape", &_t_graphReshaping, TimeCompiler); )
|
NOT_PRODUCT( TracePhase t2("graphReshape", &_t_graphReshaping, TimeCompiler); )
|
||||||
|
@ -3868,7 +3870,7 @@ void Compile::print_inlining_assert_ready() {
|
||||||
assert(!_print_inlining || _print_inlining_stream->size() == 0, "loosing data");
|
assert(!_print_inlining || _print_inlining_stream->size() == 0, "loosing data");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compile::dump_inlining() {
|
void Compile::process_print_inlining() {
|
||||||
bool do_print_inlining = print_inlining() || print_intrinsics();
|
bool do_print_inlining = print_inlining() || print_intrinsics();
|
||||||
if (do_print_inlining || log() != NULL) {
|
if (do_print_inlining || log() != NULL) {
|
||||||
// Print inlining message for candidates that we couldn't inline
|
// Print inlining message for candidates that we couldn't inline
|
||||||
|
@ -3885,9 +3887,21 @@ void Compile::dump_inlining() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (do_print_inlining) {
|
if (do_print_inlining) {
|
||||||
|
ResourceMark rm;
|
||||||
|
stringStream ss;
|
||||||
for (int i = 0; i < _print_inlining_list->length(); i++) {
|
for (int i = 0; i < _print_inlining_list->length(); i++) {
|
||||||
tty->print("%s", _print_inlining_list->adr_at(i)->ss()->as_string());
|
ss.print("%s", _print_inlining_list->adr_at(i)->ss()->as_string());
|
||||||
}
|
}
|
||||||
|
size_t end = ss.size();
|
||||||
|
_print_inlining_output = NEW_ARENA_ARRAY(comp_arena(), char, end+1);
|
||||||
|
strncpy(_print_inlining_output, ss.base(), end+1);
|
||||||
|
_print_inlining_output[end] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Compile::dump_print_inlining() {
|
||||||
|
if (_print_inlining_output != NULL) {
|
||||||
|
tty->print_raw(_print_inlining_output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -420,6 +420,7 @@ class Compile : public Phase {
|
||||||
stringStream* _print_inlining_stream;
|
stringStream* _print_inlining_stream;
|
||||||
GrowableArray<PrintInliningBuffer>* _print_inlining_list;
|
GrowableArray<PrintInliningBuffer>* _print_inlining_list;
|
||||||
int _print_inlining_idx;
|
int _print_inlining_idx;
|
||||||
|
char* _print_inlining_output;
|
||||||
|
|
||||||
// Only keep nodes in the expensive node list that need to be optimized
|
// Only keep nodes in the expensive node list that need to be optimized
|
||||||
void cleanup_expensive_nodes(PhaseIterGVN &igvn);
|
void cleanup_expensive_nodes(PhaseIterGVN &igvn);
|
||||||
|
@ -917,7 +918,8 @@ class Compile : public Phase {
|
||||||
|
|
||||||
void remove_useless_late_inlines(GrowableArray<CallGenerator*>* inlines, Unique_Node_List &useful);
|
void remove_useless_late_inlines(GrowableArray<CallGenerator*>* inlines, Unique_Node_List &useful);
|
||||||
|
|
||||||
void dump_inlining();
|
void process_print_inlining();
|
||||||
|
void dump_print_inlining();
|
||||||
|
|
||||||
bool over_inlining_cutoff() const {
|
bool over_inlining_cutoff() const {
|
||||||
if (!inlining_incrementally()) {
|
if (!inlining_incrementally()) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue