8043638: Multiple compilation attempts break LogCompulation, lead to confusing PrintInlining output
Summary: dumps inlining only for last compilation attempt. Fix LogCompilation tool so it handles multiple compilation attempts.
Reviewed-by: vlivanov, kvn
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java Mon May 26 10:48:58 2014 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/CallSite.java Mon May 26 14:27:01 2014 +0200
@@ -231,6 +231,9 @@
// identical call sites with the same method name/bci are
// possible so we have to try them all until we find the late
// inline call site that has a matching inline id.
+ if (calls == null) {
+ return null;
+ }
CallSite site = sites.pop();
for (CallSite c : calls) {
if (c.matches(site)) {
@@ -250,6 +253,27 @@
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() {
return inlineId;
}
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java Mon May 26 10:48:58 2014 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java Mon May 26 14:27:01 2014 +0200
@@ -49,6 +49,12 @@
this.id = id;
}
+ void reset() {
+ call = new CallSite();
+ lateInlineCall = new CallSite();
+ phases = new ArrayList<Phase>(4);
+ }
+
Phase getPhase(String s) {
for (Phase p : getPhases()) {
if (p.getName().equals(s)) {
@@ -212,10 +218,6 @@
return phases;
}
- public void setPhases(ArrayList<Phase> phases) {
- this.setPhases(phases);
- }
-
public String getFailureReason() {
return failureReason;
}
@@ -240,10 +242,6 @@
return call;
}
- public void setCall(CallSite call) {
- this.call = call;
- }
-
public CallSite getLateInlineCall() {
return lateInlineCall;
}
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java Mon May 26 10:48:58 2014 +0200
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java Mon May 26 14:27:01 2014 +0200
@@ -395,6 +395,7 @@
compile.setEnd(Double.parseDouble(search(atts, "stamp")));
if (Integer.parseInt(search(atts, "success")) == 0) {
compile.setFailureReason(failureReason);
+ failureReason = null;
}
} else if (qname.equals("make_not_entrant")) {
String id = makeId(atts);
@@ -451,6 +452,12 @@
nmethods.put(id, nm);
events.add(nm);
} else if (qname.equals("parse")) {
+ if (failureReason != null && scopes.size() == 0 && !lateInlining) {
+ failureReason = null;
+ compile.reset();
+ site = compile.getCall();
+ }
+
if (methodHandleSite != null) {
throw new InternalError("method handle site should have been replaced");
}
@@ -529,6 +536,18 @@
site = compile.getCall().findCallSite(thisCallScopes);
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);
throw new InternalError("couldn't find call site");
}
--- a/hotspot/src/share/vm/opto/c2compiler.cpp Mon May 26 10:48:58 2014 +0200
+++ b/hotspot/src/share/vm/opto/c2compiler.cpp Mon May 26 14:27:01 2014 +0200
@@ -155,6 +155,9 @@
}
}
+ // print inlining for last compilation only
+ C.dump_print_inlining();
+
// No retry; just break the loop.
break;
}
--- a/hotspot/src/share/vm/opto/compile.cpp Mon May 26 10:48:58 2014 +0200
+++ b/hotspot/src/share/vm/opto/compile.cpp Mon May 26 14:27:01 2014 +0200
@@ -672,6 +672,7 @@
_print_inlining_list(NULL),
_print_inlining_stream(NULL),
_print_inlining_idx(0),
+ _print_inlining_output(NULL),
_preserve_jvm_state(0),
_interpreter_frame_size(0) {
C = this;
@@ -978,6 +979,7 @@
_print_inlining_list(NULL),
_print_inlining_stream(NULL),
_print_inlining_idx(0),
+ _print_inlining_output(NULL),
_preserve_jvm_state(0),
_allowed_reasons(0),
_interpreter_frame_size(0) {
@@ -2207,7 +2209,7 @@
} // (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
{
NOT_PRODUCT( TracePhase t2("graphReshape", &_t_graphReshaping, TimeCompiler); )
@@ -3868,7 +3870,7 @@
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();
if (do_print_inlining || log() != NULL) {
// Print inlining message for candidates that we couldn't inline
@@ -3885,9 +3887,21 @@
}
}
if (do_print_inlining) {
+ ResourceMark rm;
+ stringStream ss;
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);
}
}
--- a/hotspot/src/share/vm/opto/compile.hpp Mon May 26 10:48:58 2014 +0200
+++ b/hotspot/src/share/vm/opto/compile.hpp Mon May 26 14:27:01 2014 +0200
@@ -420,6 +420,7 @@
stringStream* _print_inlining_stream;
GrowableArray<PrintInliningBuffer>* _print_inlining_list;
int _print_inlining_idx;
+ char* _print_inlining_output;
// Only keep nodes in the expensive node list that need to be optimized
void cleanup_expensive_nodes(PhaseIterGVN &igvn);
@@ -917,7 +918,8 @@
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 {
if (!inlining_incrementally()) {