src/share/vm/code/codeCache.cpp

Print this page

        

@@ -30,10 +30,11 @@
 #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"

@@ -79,10 +80,13 @@
 
   int total()                                    { return total_size; }
   bool is_empty()                                { return count == 0; }
 
   void print(const char* title) {
+    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,

@@ -92,10 +96,11 @@
                   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();

@@ -968,36 +973,125 @@
 #endif // !PRODUCT
 
 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
     int code_size = 0;
     int number_of_blobs = 0;

@@ -1018,12 +1112,10 @@
     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