--- old/src/share/vm/code/codeCache.cpp 2013-08-23 15:32:59.072482164 +0200 +++ new/src/share/vm/code/codeCache.cpp 2013-08-23 15:32:58.944482168 +0200 @@ -32,6 +32,7 @@ #include "code/pcDesc.hpp" #include "compiler/compileBroker.hpp" #include "gc_implementation/shared/markSweep.hpp" +#include "interpreter/abstractInterpreter.hpp" #include "memory/allocation.inline.hpp" #include "memory/gcLocker.hpp" #include "memory/iterator.hpp" @@ -81,18 +82,22 @@ bool is_empty() { return count == 0; } void print(const char* title) { - tty->print_cr(" #%d %s = %dK (hdr %d%%, loc %d%%, code %d%%, stub %d%%, [oops %d%%, data %d%%, pcs %d%%])", - count, - title, - total() / K, - header_size * 100 / total_size, - relocation_size * 100 / total_size, - code_size * 100 / total_size, - stub_size * 100 / total_size, - scopes_oop_size * 100 / total_size, - scopes_metadata_size * 100 / total_size, - scopes_data_size * 100 / total_size, - scopes_pcs_size * 100 / total_size); + if (count == 0) { + tty->print_cr(" #%d %s", count, title); + } else { + tty->print_cr(" #%d %s = %dK (hdr %d%%, loc %d%%, code %d%%, stub %d%%, [oops %d%%, data %d%%, pcs %d%%])", + count, + title, + total() / K, + header_size * 100 / total_size, + relocation_size * 100 / total_size, + code_size * 100 / total_size, + stub_size * 100 / total_size, + scopes_oop_size * 100 / total_size, + scopes_metadata_size * 100 / total_size, + scopes_data_size * 100 / total_size, + scopes_pcs_size * 100 / total_size); + } } void add(CodeBlob* cb) { @@ -970,32 +975,121 @@ void CodeCache::print() { print_summary(tty); -#ifndef PRODUCT - if (!Verbose) return; - - CodeBlob_sizes live; - CodeBlob_sizes dead; + CodeBlob_sizes live_java_methods [CompLevel_full_optimization + 1]; + CodeBlob_sizes live_osr_methods [CompLevel_full_optimization + 1]; + CodeBlob_sizes live_native_methods; + + CodeBlob_sizes dead_java_methods [CompLevel_full_optimization + 1]; + CodeBlob_sizes dead_osr_methods [CompLevel_full_optimization + 1]; + CodeBlob_sizes dead_native_methods; + + CodeBlob_sizes runtime_stubs; + CodeBlob_sizes deoptimization_stubs; + CodeBlob_sizes uncommon_trap_stubs; + CodeBlob_sizes exception_stubs; + CodeBlob_sizes safepoint_stubs; + CodeBlob_sizes adapter_blobs; + CodeBlob_sizes method_handles_adapter_blobs; + CodeBlob_sizes other_stubs; + + size_t total_live_nmethods = 0; + size_t total_dead_nmethods = 0; + size_t total_stubs_size = 0; FOR_ALL_BLOBS(p) { - if (!p->is_alive()) { - dead.add(p); + // live or not-entrant methods + if (p->is_alive()) { + if (p->is_nmethod()) { + total_live_nmethods++; + // Cannot return NULL, since we checked that it is an nmethod + nmethod* nm = p->as_nmethod_or_null(); + const int comp_level = nm->comp_level(); + + if (nm->is_osr_method()) { + live_osr_methods[comp_level].add(nm); + } else if (nm->is_native_method()) { + live_native_methods.add(nm); + } else if (nm->is_java_method()) { + live_java_methods[comp_level].add(nm); + } + } else { + total_stubs_size++; + if (p->is_runtime_stub()) { + runtime_stubs.add(p); + } else if (p->is_deoptimization_stub()) { + deoptimization_stubs.add(p); + } else if (p->is_uncommon_trap_stub()) { + uncommon_trap_stubs.add(p); + } else if (p->is_exception_stub()) { + exception_stubs.add(p); + } else if (p->is_safepoint_stub()) { + safepoint_stubs.add(p); + } else if (p->is_adapter_blob()) { + adapter_blobs.add(p); + } else if (p->is_method_handles_adapter_blob()) { + method_handles_adapter_blobs.add(p); + } else { + other_stubs.add(p); + } + } + // zombie or unloaded methods } else { - live.add(p); + if (p->is_nmethod()) { + total_dead_nmethods++; + nmethod* nm = p->as_nmethod_or_null(); + const int comp_level = nm->comp_level(); + + if (nm->is_osr_method()) { + dead_osr_methods[comp_level].add(nm); + } else if (nm->is_native_method()) { + dead_native_methods.add(nm); + } else if (nm->is_java_method()) { + dead_java_methods[comp_level].add(nm); + } + } } } - tty->print_cr("CodeCache:"); + // Tier 0 (interpreter) + StubQueue* code = AbstractInterpreter::code(); + tty->print("\nInterpreter:"); + tty->print_cr(" total=%dk, used=%dk", code->total_space() / K, code->used_space() / K); + + // Print live methods + tty->print_cr("\nTotal number of live methods: %u", total_live_nmethods); + for (int i = 1; i < CompLevel_full_optimization + 1; i++) { + tty->print_cr(" Tier %d:", i); + live_java_methods[i].print("Java methods"); + live_osr_methods[i].print("OSR methods"); + } + tty->print_cr(" Native methods:"); + live_native_methods.print("Native methods"); + + // Print dead methods + tty->print_cr("\nTotal number of dead methods: %u", total_dead_nmethods); + for (int i = 1; i < CompLevel_full_optimization + 1; i++) { + tty->print_cr(" Tier %d:", i); + dead_java_methods[i].print("Java methods"); + dead_osr_methods[i].print("OSR methods"); + } + tty->print_cr(" Native methods:"); + dead_native_methods.print("Native methods"); + + // Print stubs + tty->print_cr("\nTotal number of stubs: %u", total_stubs_size); + runtime_stubs.print("runtime"); + deoptimization_stubs.print("deoptimization"); + uncommon_trap_stubs.print("uncommon trap"); + exception_stubs.print("exception"); + safepoint_stubs.print("safepoint"); + adapter_blobs.print("C2I/I2C adapter"); + method_handles_adapter_blobs.print("method handles adapter"); + other_stubs.print("other"); +#ifndef PRODUCT tty->print_cr("nmethod dependency checking time %f", dependentCheckTime.seconds(), dependentCheckTime.seconds() / dependentCheckCount); - - if (!live.is_empty()) { - live.print("live"); - } - if (!dead.is_empty()) { - dead.print("dead"); - } - +#endif if (WizardMode) { // print the oop_map usage @@ -1020,8 +1114,6 @@ tty->print_cr(" #oop_maps = %d", number_of_oop_maps); tty->print_cr(" map size = %d", map_size); } - -#endif // !PRODUCT } void CodeCache::print_summary(outputStream* st, bool detailed) {