src/share/vm/code/codeCache.cpp

Print this page

        

*** 30,39 **** --- 30,40 ---- #include "code/icBuffer.hpp" #include "code/nmethod.hpp" #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" #include "memory/resourceArea.hpp" #include "oops/method.hpp"
*** 50,69 **** // Helper class for printing in CodeCache 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; public: CodeBlob_sizes() { count = 0; total_size = 0; --- 51,70 ---- // Helper class for printing in CodeCache class CodeBlob_sizes { private: ! 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;
*** 75,101 **** scopes_metadata_size = 0; scopes_data_size = 0; scopes_pcs_size = 0; } ! int total() { return total_size; } 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); } void add(CodeBlob* cb) { count++; total_size += cb->size(); header_size += cb->header_size(); --- 76,107 ---- scopes_metadata_size = 0; scopes_data_size = 0; scopes_pcs_size = 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) { ! 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) { count++; total_size += cb->size(); header_size += cb->header_size();
*** 856,1003 **** _heap->verify(); } } void CodeCache::print_trace(const char* event, CodeBlob* cb, int size) { ! if (PrintCodeCache2) { // 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); } } ! 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; ResourceMark rm; ! CodeBlob *cb; ! for (cb = first(); cb != NULL; cb = next(cb)) { ! total++; if (cb->is_nmethod()) { nmethod* nm = (nmethod*)cb; if (Verbose && nm->method() != NULL) { 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(); } } } else if (cb->is_runtime_stub()) { ! runtimeStubCount++; } else if (cb->is_deoptimization_stub()) { ! deoptimizationStubCount++; } else if (cb->is_uncommon_trap_stub()) { ! uncommonTrapStubCount++; } else if (cb->is_adapter_blob()) { ! adapterCount++; } else if (cb->is_buffer_blob()) { ! bufferBlobCount++; } } 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("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; i<bucketLimit; i++) { ! if(buckets[i] != 0) { tty->print("%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); - } - - #endif // !PRODUCT - - 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; int number_of_blobs = 0; --- 862,1019 ---- _heap->verify(); } } void CodeCache::print_trace(const char* event, CodeBlob* cb, int size) { ! 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: %dB", event, cb, size); } } ! 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; ! FOR_ALL_BLOBS(cb) { ! total_entries++; if (cb->is_nmethod()) { nmethod* nm = (nmethod*)cb; if (Verbose && nm->method() != NULL) { ResourceMark rm; char *method_name = nm->method()->name_and_sig_as_C_string(); tty->print("%s", method_name); ! 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()) { ! runtime_stubs.add(cb); } else if (cb->is_deoptimization_stub()) { ! deoptimization_stubs.add(cb); } else if (cb->is_uncommon_trap_stub()) { ! uncommon_trap_stubs.add(cb); } else if (cb->is_adapter_blob()) { ! adapters.add(cb); } else if (cb->is_buffer_blob()) { ! buffer_blobs.add(cb); ! } else { ! other_entries.add(cb); } } + 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]++; } } } for(int i=0; i<bucketLimit; i++) { ! if (buckets[i] != 0) { tty->print("%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 } + } + + #endif // !PRODUCT + + void CodeCache::print() { + print_summary(tty); if (WizardMode) { // print the oop_map usage int code_size = 0; int number_of_blobs = 0;
*** 1018,1046 **** tty->print_cr(" #blobs = %d", number_of_blobs); tty->print_cr(" code size = %d", code_size); 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", total/K, (total - unallocated_capacity())/K, maxCodeCacheUsed/K, unallocated_capacity()/K); if (detailed) { 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)" : "disabled (not enough contiguous free space left)"); } --- 1034,1089 ---- tty->print_cr(" #blobs = %d", number_of_blobs); tty->print_cr(" code size = %d", code_size); tty->print_cr(" #oop_maps = %d", number_of_oop_maps); tty->print_cr(" map size = %d", map_size); } } 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", 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(" compilation: %s", CompileBroker::should_compile_new_jobs() ? "enabled" : Arguments::mode() == Arguments::_int ? "disabled (interpreter mode)" : "disabled (not enough contiguous free space left)"); }