< prev index next >
src/hotspot/share/runtime/java.cpp
Print this page
@@ -90,13 +90,15 @@
#endif
GrowableArray<Method*>* collected_profiled_methods;
int compare_methods(Method** a, Method** b) {
- // %%% there can be 32-bit overflow here
- return ((*b)->invocation_count() + (*b)->compiled_invocation_count())
- - ((*a)->invocation_count() + (*a)->compiled_invocation_count());
+ // compiled_invocation_count() returns int64_t, forcing the entire expression
+ // to be evaluated as int64_t. Overflow is not an issue.
+ int64_t diff = (((*b)->invocation_count() + (*b)->compiled_invocation_count())
+ - ((*a)->invocation_count() + (*a)->compiled_invocation_count()));
+ return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
}
void collect_profiled_methods(Method* m) {
Thread* thread = Thread::current();
methodHandle mh(thread, m);
@@ -145,18 +147,19 @@
// Statistics printing (method invocation histogram)
GrowableArray<Method*>* collected_invoked_methods;
void collect_invoked_methods(Method* m) {
- if (m->invocation_count() + m->compiled_invocation_count() >= 1 ) {
+ if (m->invocation_count() + m->compiled_invocation_count() >= 1) {
collected_invoked_methods->push(m);
}
}
-
-
+// Invocation count accumulators should be unsigned long to shift the
+// overflow border. Longer-running workloads tend to create invocation
+// counts which already overflow 32-bit counters for individual methods.
void print_method_invocation_histogram() {
ResourceMark rm;
HandleMark hm;
collected_invoked_methods = new GrowableArray<Method*>(1024);
SystemDictionary::methods_do(collect_invoked_methods);
@@ -164,35 +167,49 @@
//
tty->cr();
tty->print_cr("Histogram Over Method Invocation Counters (cutoff = " INTX_FORMAT "):", MethodHistogramCutoff);
tty->cr();
tty->print_cr("____Count_(I+C)____Method________________________Module_________________");
- unsigned total = 0, int_total = 0, comp_total = 0, static_total = 0, final_total = 0,
- synch_total = 0, nativ_total = 0, acces_total = 0;
+ uint64_t total = 0,
+ int_total = 0,
+ comp_total = 0,
+ special_total= 0,
+ static_total = 0,
+ final_total = 0,
+ synch_total = 0,
+ native_total = 0,
+ access_total = 0;
for (int index = 0; index < collected_invoked_methods->length(); index++) {
+ // Counter values returned from getter methods are signed int.
+ // To shift the overflow border by a factor of two, we interpret
+ // them here as unsigned long. A counter can't be negative anyway.
Method* m = collected_invoked_methods->at(index);
- int c = m->invocation_count() + m->compiled_invocation_count();
- if (c >= MethodHistogramCutoff) m->print_invocation_count();
- int_total += m->invocation_count();
- comp_total += m->compiled_invocation_count();
- if (m->is_final()) final_total += c;
- if (m->is_static()) static_total += c;
- if (m->is_synchronized()) synch_total += c;
- if (m->is_native()) nativ_total += c;
- if (m->is_accessor()) acces_total += c;
+ uint64_t iic = (uint64_t)m->invocation_count();
+ uint64_t cic = (uint64_t)m->compiled_invocation_count();
+ if ((iic + cic) >= (uint64_t)MethodHistogramCutoff) m->print_invocation_count();
+ int_total += iic;
+ comp_total += cic;
+ if (m->is_final()) final_total += iic + cic;
+ if (m->is_static()) static_total += iic + cic;
+ if (m->is_synchronized()) synch_total += iic + cic;
+ if (m->is_native()) native_total += iic + cic;
+ if (m->is_accessor()) access_total += iic + cic;
}
tty->cr();
total = int_total + comp_total;
- tty->print_cr("Invocations summary:");
- tty->print_cr("\t%9d (%4.1f%%) interpreted", int_total, 100.0 * int_total / total);
- tty->print_cr("\t%9d (%4.1f%%) compiled", comp_total, 100.0 * comp_total / total);
- tty->print_cr("\t%9d (100%%) total", total);
- tty->print_cr("\t%9d (%4.1f%%) synchronized", synch_total, 100.0 * synch_total / total);
- tty->print_cr("\t%9d (%4.1f%%) final", final_total, 100.0 * final_total / total);
- tty->print_cr("\t%9d (%4.1f%%) static", static_total, 100.0 * static_total / total);
- tty->print_cr("\t%9d (%4.1f%%) native", nativ_total, 100.0 * nativ_total / total);
- tty->print_cr("\t%9d (%4.1f%%) accessor", acces_total, 100.0 * acces_total / total);
+ special_total = final_total + static_total +synch_total + native_total + access_total;
+ tty->print_cr("Invocations summary for %d methods:", collected_invoked_methods->length());
+ tty->print_cr("\t" UINT64_FORMAT_W(12) " (100%%) total", total);
+ tty->print_cr("\t" UINT64_FORMAT_W(12) " (%4.1f%%) |- interpreted", int_total, 100.0 * int_total / total);
+ tty->print_cr("\t" UINT64_FORMAT_W(12) " (%4.1f%%) |- compiled", comp_total, 100.0 * comp_total / total);
+ tty->print_cr("\t" UINT64_FORMAT_W(12) " (%4.1f%%) |- special methods (interpreted and compiled)",
+ special_total, 100.0 * special_total/ total);
+ tty->print_cr("\t" UINT64_FORMAT_W(12) " (%4.1f%%) |- synchronized",synch_total, 100.0 * synch_total / total);
+ tty->print_cr("\t" UINT64_FORMAT_W(12) " (%4.1f%%) |- final", final_total, 100.0 * final_total / total);
+ tty->print_cr("\t" UINT64_FORMAT_W(12) " (%4.1f%%) |- static", static_total, 100.0 * static_total / total);
+ tty->print_cr("\t" UINT64_FORMAT_W(12) " (%4.1f%%) |- native", native_total, 100.0 * native_total / total);
+ tty->print_cr("\t" UINT64_FORMAT_W(12) " (%4.1f%%) |- accessor", access_total, 100.0 * access_total / total);
tty->cr();
SharedRuntime::print_call_statistics(comp_total);
}
void print_bytecode_count() {
< prev index next >