--- old/src/share/vm/code/codeCache.cpp 2013-08-26 16:31:52.269525784 +0200 +++ new/src/share/vm/code/codeCache.cpp 2013-08-26 16:31:52.209525787 +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" @@ -52,47 +53,52 @@ class CodeBlob_sizes { private: - int count; - int total_size; - int header_size; - int code_size; - int stub_size; - int relocation_size; - int scopes_oop_size; - int scopes_metadata_size; - int scopes_data_size; - int scopes_pcs_size; + size_t count; + size_t total_size; + size_t header_size; + size_t code_size; + size_t stub_size; + size_t relocation_size; + size_t scopes_oop_size; + size_t scopes_metadata_size; + size_t scopes_data_size; + size_t scopes_pcs_size; public: CodeBlob_sizes() { - count = 0; - total_size = 0; - header_size = 0; - code_size = 0; - stub_size = 0; - relocation_size = 0; - scopes_oop_size = 0; - scopes_metadata_size = 0; - scopes_data_size = 0; - scopes_pcs_size = 0; + count = 0; + total_size = 0; + header_size = 0; + code_size = 0; + stub_size = 0; + relocation_size = 0; + scopes_oop_size = 0; + scopes_metadata_size = 0; + scopes_data_size = 0; + scopes_pcs_size = 0; } - int total() { return total_size; } - bool is_empty() { return count == 0; } + size_t get_total_size() { return total_size; } + size_t get_total_count() { return count; } + 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(" #%u %s", count, title); + } else { + tty->print_cr(" #%d %s = %dkB (hdr %u%%, loc %u%%, code %u%%, stub %u%%, [oops %u%%, data %u%%, pcs %u%%])", + count, + title, + total_size / 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) { @@ -858,33 +864,35 @@ } void CodeCache::print_trace(const char* event, CodeBlob* cb, int size) { - if (PrintCodeCache2) { // Need to add a new flag + if (PrintCodeCacheAllocation) { // Need to add a new flag ResourceMark rm; if (size == 0) size = cb->size(); - tty->print_cr("CodeCache %s: addr: " INTPTR_FORMAT ", size: 0x%x", event, cb, size); + tty->print_cr("CodeCache %s: addr: " INTPTR_FORMAT ", size: %dB", event, cb, size); } } -void CodeCache::print_internals() { - int nmethodCount = 0; - int runtimeStubCount = 0; - int adapterCount = 0; - int deoptimizationStubCount = 0; - int uncommonTrapStubCount = 0; - int bufferBlobCount = 0; - int total = 0; - int nmethodAlive = 0; - int nmethodNotEntrant = 0; - int nmethodZombie = 0; - int nmethodUnloaded = 0; - int nmethodJava = 0; - int nmethodNative = 0; - int maxCodeSize = 0; +void CodeCache::print_details() { + size_t total_entries = 0; + size_t max_code_size = 0; + + CodeBlob_sizes runtime_stubs; + CodeBlob_sizes adapters; + CodeBlob_sizes deoptimization_stubs; + CodeBlob_sizes uncommon_trap_stubs; + CodeBlob_sizes buffer_blobs; + CodeBlob_sizes in_use; + CodeBlob_sizes not_entrant; + CodeBlob_sizes zombie; + CodeBlob_sizes unloaded; + CodeBlob_sizes java_methods; + CodeBlob_sizes native_methods; + CodeBlob_sizes other_entries; + CodeBlob_sizes tiers[CompLevel_full_optimization + 1]; + ResourceMark rm; - CodeBlob *cb; - for (cb = first(); cb != NULL; cb = next(cb)) { - total++; + FOR_ALL_BLOBS(cb) { + total_entries++; if (cb->is_nmethod()) { nmethod* nm = (nmethod*)cb; @@ -892,77 +900,112 @@ ResourceMark rm; char *method_name = nm->method()->name_and_sig_as_C_string(); tty->print("%s", method_name); - if(nm->is_alive()) { tty->print_cr(" alive"); } - if(nm->is_not_entrant()) { tty->print_cr(" not-entrant"); } - if(nm->is_zombie()) { tty->print_cr(" zombie"); } - } - - nmethodCount++; - - if(nm->is_alive()) { nmethodAlive++; } - if(nm->is_not_entrant()) { nmethodNotEntrant++; } - if(nm->is_zombie()) { nmethodZombie++; } - if(nm->is_unloaded()) { nmethodUnloaded++; } - if(nm->is_native_method()) { nmethodNative++; } - - if(nm->method() != NULL && nm->is_java_method()) { - nmethodJava++; - if (nm->insts_size() > maxCodeSize) { - maxCodeSize = nm->insts_size(); + if (nm->is_in_use()) { + tty->print_cr(" in-use"); + } else if (nm->is_not_entrant()) { + tty->print_cr(" not-entrant"); + } else if (nm->is_zombie()) { + tty->print_cr(" zombie"); + } + } + + if (nm->is_in_use()) { + in_use.add(nm); + } else if (nm->is_not_entrant()) { + not_entrant.add(nm); + } else if (nm->is_zombie()) { + zombie.add(nm); + } else if (nm->is_unloaded()) { + unloaded.add(nm); + } + + if(nm->is_native_method()) { + native_methods.add(nm); + } + + // Native methods are Tier 0 + tiers[nm->comp_level()].add(nm); + + if (nm->method() != NULL && nm->is_java_method()) { + java_methods.add(nm); + if ((size_t)nm->insts_size() > max_code_size) { + max_code_size = nm->insts_size(); } } } else if (cb->is_runtime_stub()) { - runtimeStubCount++; + runtime_stubs.add(cb); } else if (cb->is_deoptimization_stub()) { - deoptimizationStubCount++; + deoptimization_stubs.add(cb); } else if (cb->is_uncommon_trap_stub()) { - uncommonTrapStubCount++; + uncommon_trap_stubs.add(cb); } else if (cb->is_adapter_blob()) { - adapterCount++; + adapters.add(cb); } else if (cb->is_buffer_blob()) { - bufferBlobCount++; + buffer_blobs.add(cb); + } else { + other_entries.add(cb); } } - int bucketSize = 512; - int bucketLimit = maxCodeSize / bucketSize + 1; - int *buckets = NEW_C_HEAP_ARRAY(int, bucketLimit, mtCode); - memset(buckets,0,sizeof(int) * bucketLimit); - - for (cb = first(); cb != NULL; cb = next(cb)) { - if (cb->is_nmethod()) { - nmethod* nm = (nmethod*)cb; - if(nm->is_java_method()) { - buckets[nm->insts_size() / bucketSize]++; + tty->print_cr("\nCode cache entries: (total of #%u)", total_entries); + size_t total_nm_count = tiers[0].get_total_count() + tiers[1].get_total_count() + tiers[2].get_total_count() + + tiers[3].get_total_count() + tiers[4].get_total_count(); + size_t total_nm_size = tiers[0].get_total_size() + tiers[1].get_total_size() + tiers[2].get_total_size() + + tiers[3].get_total_size() + tiers[4].get_total_size(); + tty->print_cr("nmethods:\t#%u\t%ukB", total_nm_count, total_nm_size / K); + tty->print_cr(" Java:\t\t#%u\t%ukB", java_methods.get_total_count(), java_methods.get_total_size() / K); + tty->print_cr(" Tier 1:\t#%u\t%ukB", tiers[1].get_total_count(), tiers[1].get_total_size() / K); + tty->print_cr(" Tier 2:\t#%u\t%ukB", tiers[2].get_total_count(), tiers[2].get_total_size() / K); + tty->print_cr(" Tier 3:\t#%u\t%ukB", tiers[3].get_total_count(), tiers[3].get_total_size() / K); + tty->print_cr(" Tier 4:\t#%u\t%ukB", tiers[4].get_total_count(), tiers[4].get_total_size() / K); + tty->print_cr(" Native:\t#%u\t%ukB", native_methods.get_total_count(), native_methods.get_total_size() / K); + + tty->print_cr("runtime-stubs:\t#%u\t%ukB", runtime_stubs.get_total_count(), runtime_stubs.get_total_size() / K); + tty->print_cr("adapters:\t#%u\t%ukB", adapters.get_total_count(), adapters.get_total_size() / K); + tty->print_cr("buffer blobs:\t#%u\t%ukB", buffer_blobs.get_total_count(), buffer_blobs.get_total_size() / K); + tty->print_cr("deopt-stubs:\t#%u\t%ukB", deoptimization_stubs.get_total_count(), deoptimization_stubs.get_total_size() / K); + tty->print_cr("uncommon-traps:\t#%u\t%ukB", uncommon_trap_stubs.get_total_count(), uncommon_trap_stubs.get_total_size() / K); + tty->print_cr("others:\t\t#%u\t%ukB\n", other_entries.get_total_count(), other_entries.get_total_size() / K); + + tty->print_cr("nmethod state distribution"); + tty->print_cr(" in-use:\t#%u\t%ukB", in_use.get_total_count(), in_use.get_total_size() / K); + tty->print_cr(" not-entrant:\t#%u\t%ukB", not_entrant.get_total_count(), not_entrant.get_total_size() / K); + tty->print_cr(" zombie:\t#%u\t%ukB", zombie.get_total_count(), zombie.get_total_size() / K); + tty->print_cr(" unloaded:\t#%u\t%ukB", unloaded.get_total_count(), unloaded.get_total_size() / K); + + if (Verbose) { + tty->print_cr("\nnmethod size distribution (non-zombie java)"); + + int bucketSize = 512; + int bucketLimit = max_code_size / bucketSize + 1; + int *buckets = NEW_C_HEAP_ARRAY(int, bucketLimit, mtCode); + memset(buckets, 0, sizeof(int) * bucketLimit); + + FOR_ALL_BLOBS(cb) { + if (cb->is_nmethod()) { + nmethod* nm = (nmethod*)cb; + if(nm->is_java_method()) { + buckets[nm->insts_size() / bucketSize]++; + } } } - } - tty->print_cr("Code Cache Entries (total of %d)",total); - tty->print_cr("-------------------------------------------------"); - tty->print_cr("nmethods: %d",nmethodCount); - tty->print_cr("\talive: %d",nmethodAlive); - tty->print_cr("\tnot_entrant: %d",nmethodNotEntrant); - tty->print_cr("\tzombie: %d",nmethodZombie); - tty->print_cr("\tunloaded: %d",nmethodUnloaded); - tty->print_cr("\tjava: %d",nmethodJava); - tty->print_cr("\tnative: %d",nmethodNative); - tty->print_cr("runtime_stubs: %d",runtimeStubCount); - tty->print_cr("adapters: %d",adapterCount); - tty->print_cr("buffer blobs: %d",bufferBlobCount); - tty->print_cr("deoptimization_stubs: %d",deoptimizationStubCount); - tty->print_cr("uncommon_traps: %d",uncommonTrapStubCount); - tty->print_cr("\nnmethod size distribution (non-zombie java)"); - tty->print_cr("-------------------------------------------------"); - - for(int i=0; iprint("%d - %d bytes",i*bucketSize,(i+1)*bucketSize); - tty->fill_to(40); - tty->print_cr("%d",buckets[i]); + + for(int i=0; iprint("%d - %d bytes",i*bucketSize,(i+1)*bucketSize); + tty->fill_to(40); + tty->print_cr("%d",buckets[i]); + } } + + FREE_C_HEAP_ARRAY(int, buckets, mtCode); + +#ifndef PRODUCT + tty->print_cr("nmethod dependency checking time %f", dependentCheckTime.seconds(), + dependentCheckTime.seconds() / dependentCheckCount); +#endif } - FREE_C_HEAP_ARRAY(int, buckets, mtCode); } #endif // !PRODUCT @@ -970,33 +1013,6 @@ void CodeCache::print() { print_summary(tty); -#ifndef PRODUCT - if (!Verbose) return; - - CodeBlob_sizes live; - CodeBlob_sizes dead; - - FOR_ALL_BLOBS(p) { - if (!p->is_alive()) { - dead.add(p); - } else { - live.add(p); - } - } - - tty->print_cr("CodeCache:"); - - 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"); - } - - if (WizardMode) { // print the oop_map usage int code_size = 0; @@ -1020,25 +1036,52 @@ 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) { size_t total = (_heap->high_boundary() - _heap->low_boundary()); - st->print_cr("CodeCache: size=" SIZE_FORMAT "Kb used=" SIZE_FORMAT - "Kb max_used=" SIZE_FORMAT "Kb free=" SIZE_FORMAT "Kb", + st->print_cr("CodeCache: size=" SIZE_FORMAT "kB used=" SIZE_FORMAT + "kB max_used=" SIZE_FORMAT "kB free=" SIZE_FORMAT "kB", total/K, (total - unallocated_capacity())/K, maxCodeCacheUsed/K, unallocated_capacity()/K); + if (detailed) { + size_t interpreter_size = AbstractInterpreter::code()->total_space() / K; + CodeBlob_sizes live_nm; + CodeBlob_sizes dead_nm; + CodeBlob_sizes stubs; + CodeBlob_sizes adapters; + size_t total_size = 0; + + FOR_ALL_BLOBS(p) { + total_size += p->size(); + // live or not-entrant methods + if (p->is_nmethod()) { + if (p->is_alive()) { + live_nm.add(p); + } else { + dead_nm.add(p); + } + } else { + if (p->is_adapter_blob()) { + adapters.add(p); + } else { + stubs.add(p); + } + } + } + st->print_cr(" Interpreter=%ukB live_nmethods=%u(%ukB) dead_nmethods=%u(%ukB) stubs=%u(%ukB) adapters=%u(%ukB)", + interpreter_size, live_nm.get_total_count(), live_nm.get_total_size() / K, + dead_nm.get_total_count(), dead_nm.get_total_size() / K, + stubs.get_total_count(), stubs.get_total_size() / K, + adapters.get_total_count(), adapters.get_total_size() / K); + st->print_cr(" bounds [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT "]", _heap->low_boundary(), _heap->high(), _heap->high_boundary()); - st->print_cr(" total_blobs=" UINT32_FORMAT " nmethods=" UINT32_FORMAT - " adapters=" UINT32_FORMAT, - nof_blobs(), nof_nmethods(), nof_adapters()); + st->print_cr(" compilation: %s", CompileBroker::should_compile_new_jobs() ? "enabled" : Arguments::mode() == Arguments::_int ? "disabled (interpreter mode)" : --- old/src/share/vm/code/codeCache.hpp 2013-08-26 16:31:52.537525774 +0200 +++ new/src/share/vm/code/codeCache.hpp 2013-08-26 16:31:52.473525777 +0200 @@ -150,7 +150,7 @@ // Printing/debugging static void print(); // prints summary - static void print_internals(); + static void print_details(); static void verify(); // verifies the code cache static void print_trace(const char* event, CodeBlob* cb, int size = 0) PRODUCT_RETURN; static void print_summary(outputStream* st, bool detailed = true); // Prints a summary of the code cache usage --- old/src/share/vm/runtime/globals.hpp 2013-08-26 16:31:52.789525765 +0200 +++ new/src/share/vm/runtime/globals.hpp 2013-08-26 16:31:52.721525767 +0200 @@ -942,12 +942,15 @@ product(bool, PrintCodeCache, false, \ "Print the code cache memory usage when exiting") \ \ - develop(bool, PrintCodeCache2, false, \ + diagnostic(bool, PrintCodeCacheDetails, false, \ "Print detailed usage info on the code cache when exiting") \ \ product(bool, PrintCodeCacheOnCompilation, false, \ "Print the code cache memory usage each time a method is compiled") \ \ + develop(bool, PrintCodeCacheAllocation, false, \ + "Print the code cache memory usage each time a method is compiled")\ + \ diagnostic(bool, PrintStubCode, false, \ "Print generated stub code") \ \ --- old/src/share/vm/runtime/java.cpp 2013-08-26 16:31:53.097525753 +0200 +++ new/src/share/vm/runtime/java.cpp 2013-08-26 16:31:53.029525756 +0200 @@ -306,9 +306,9 @@ CodeCache::print(); } - if (PrintCodeCache2) { + if (PrintCodeCacheDetails) { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - CodeCache::print_internals(); + CodeCache::print_details(); } if (PrintClassStatistics) {