# HG changeset patch # User Christian Haeubl # Date 1354538652 -3600 # Node ID ceb8c5b294199ab1fa1e279b08e5238554f136af # Parent acfca8c77dd297777efe4c88434a7e96aad68943 print more details when -XX:+PrintDeoptimizationDetails is enabled diff -r acfca8c77dd2 -r ceb8c5b29419 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Fri Nov 30 11:13:36 2012 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Mon Dec 03 13:44:12 2012 +0100 @@ -90,9 +90,13 @@ } private static InlineInfo logNotInlinedMethodAndReturnNull(Invoke invoke, ResolvedJavaMethod method, String msg) { + return logNotInlinedMethodAndReturnNull(invoke, method, msg, new Object[0]); + } + + private static InlineInfo logNotInlinedMethodAndReturnNull(Invoke invoke, ResolvedJavaMethod method, String msg, Object... args) { if (shouldLogInliningDecision()) { String methodString = methodName(method, invoke); - logInliningDecision(methodString, false, msg, new Object[0]); + logInliningDecision(methodString, false, msg, args); } return null; } @@ -285,7 +289,7 @@ @Override public String toString() { - return "type-checked " + MetaUtil.format("%H.%n(%p):%r", concrete); + return "type-checked with type " + type.getName() + " and method " + MetaUtil.format("%H.%n(%p):%r", concrete); } } @@ -594,10 +598,21 @@ @Override public String toString() { StringBuilder builder = new StringBuilder(shouldFallbackToInvoke() ? "megamorphic" : "polymorphic"); - builder.append(String.format(", %d methods with %d type checks:", concretes.size(), ptypes.length)); + builder.append(", "); + builder.append(concretes.size()); + builder.append(" methods [ "); for (int i = 0; i < concretes.size(); i++) { builder.append(MetaUtil.format(" %H.%n(%p):%r", concretes.get(i))); } + builder.append(" ], "); + builder.append(ptypes.length); + builder.append(" type checks [ "); + for (int i = 0; i < ptypes.length; i++) { + builder.append(" "); + builder.append(ptypes[i].getType().getName()); + builder.append(ptypes[i].getProbability()); + } + builder.append(" ]"); return builder.toString(); } } @@ -720,12 +735,11 @@ } else { invoke.setPolymorphic(true); - if (!optimisticOpts.inlinePolymorphicCalls() && notRecordedTypeProbability == 0) { - return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "inlining polymorphic calls is disabled"); + return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "inlining polymorphic calls is disabled (%d types)", ptypes.length); } if (!optimisticOpts.inlineMegamorphicCalls() && notRecordedTypeProbability > 0) { - return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "inlining megamorphic calls is disabled"); + return logNotInlinedMethodAndReturnNull(invoke, targetMethod, "inlining megamorphic calls is disabled (%d types, %f %% not recorded types)", ptypes.length, notRecordedTypeProbability * 100); } // TODO (chaeubl) inlining of multiple methods should work differently diff -r acfca8c77dd2 -r ceb8c5b29419 src/share/vm/runtime/vframeArray.cpp --- a/src/share/vm/runtime/vframeArray.cpp Fri Nov 30 11:13:36 2012 +0100 +++ b/src/share/vm/runtime/vframeArray.cpp Mon Dec 03 13:44:12 2012 +0100 @@ -311,6 +311,10 @@ } } + if (PrintDeoptimizationDetails) { + tty->print_cr("Expressions size: %d", expressions()->size()); + } + // Unpack expression stack // If this is an intermediate frame (i.e. not top frame) then this // only unpacks the part of the expression stack not used by callee @@ -323,9 +327,25 @@ switch(value->type()) { case T_INT: *addr = value->get_int(); +#ifndef PRODUCT + if (PrintDeoptimizationDetails) { + tty->print_cr("Reconstructed expression %d (INT): %d", i, (int)(*addr)); + } +#endif break; case T_OBJECT: *addr = value->get_int(T_OBJECT); +#ifndef PRODUCT + if (PrintDeoptimizationDetails) { + tty->print("Reconstructed expression %d (OBJECT): ", i); + oop o = (oop)(*addr); + if (o == NULL) { + tty->print_cr("NULL"); + } else { + tty->print_cr(err_msg("%s", o->klass()->name()->as_C_string())); + } + } +#endif break; case T_CONFLICT: // A dead stack slot. Initialize to null in case it is an oop. @@ -344,9 +364,25 @@ switch(value->type()) { case T_INT: *addr = value->get_int(); +#ifndef PRODUCT + if (PrintDeoptimizationDetails) { + tty->print_cr("Reconstructed local %d (INT): %d", i, (int)(*addr)); + } +#endif break; case T_OBJECT: *addr = value->get_int(T_OBJECT); +#ifndef PRODUCT + if (PrintDeoptimizationDetails) { + tty->print("Reconstructed local %d (OBJECT): ", i); + oop o = (oop)(*addr); + if (o == NULL) { + tty->print_cr("NULL"); + } else { + tty->print_cr(err_msg("%s", o->klass()->name()->as_C_string())); + } + } +#endif break; case T_CONFLICT: // A dead location. If it is an oop then we need a NULL to prevent GC from following it @@ -388,18 +424,13 @@ } #ifndef PRODUCT - if (TraceDeoptimization && Verbose) { + if (PrintDeoptimizationDetails) { ttyLocker ttyl; tty->print_cr("[%d Interpreted Frame]", ++unpack_counter); iframe()->print_on(tty); RegisterMap map(thread); vframe* f = vframe::new_vframe(iframe(), &map, thread); f->print(); - - tty->print_cr("locals size %d", locals()->size()); - tty->print_cr("expression size %d", expressions()->size()); - - method()->print_value(); tty->cr(); // method()->print_codes(); } else if (TraceDeoptimization) {