< prev index next >

src/hotspot/share/code/codeHeapState.cpp

Print this page
rev 54097 : 8216314: SIGILL in CodeHeapState::print_names()
Reviewed-by: thartmann, kvn
   1 /*
   2  * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2018 SAP SE. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include "precompiled.hpp"
  27 #include "code/codeHeapState.hpp"
  28 #include "compiler/compileBroker.hpp"
  29 #include "runtime/sweeper.hpp"
  30 
  31 // -------------------------
  32 // |  General Description  |
  33 // -------------------------
  34 // The CodeHeap state analytics are divided in two parts.
  35 // The first part examines the entire CodeHeap and aggregates all
  36 // information that is believed useful/important.
  37 //
  38 // Aggregation condenses the information of a piece of the CodeHeap
  39 // (4096 bytes by default) into an analysis granule. These granules
  40 // contain enough detail to gain initial insight while keeping the
  41 // internal structure sizes in check.
  42 //
  43 // The CodeHeap is a living thing. Therefore, the aggregate is collected
  44 // under the CodeCache_lock. The subsequent print steps are only locked
  45 // against concurrent aggregations. That keeps the impact on
  46 // "normal operation" (JIT compiler and sweeper activity) to a minimum.
  47 //
  48 // The second part, which consists of several, independent steps,
  49 // prints the previously collected information with emphasis on
  50 // various aspects.
  51 //







  52 // Data collection and printing is done on an "on request" basis.
  53 // While no request is being processed, there is no impact on performance.
  54 // The CodeHeap state analytics do have some memory footprint.
  55 // The "aggregate" step allocates some data structures to hold the aggregated
  56 // information for later output. These data structures live until they are
  57 // explicitly discarded (function "discard") or until the VM terminates.
  58 // There is one exception: the function "all" does not leave any data
  59 // structures allocated.
  60 //
  61 // Requests for real-time, on-the-fly analysis can be issued via
  62 //   jcmd <pid> Compiler.CodeHeap_Analytics [<function>] [<granularity>]
  63 //
  64 // If you are (only) interested in how the CodeHeap looks like after running
  65 // a sample workload, you can use the command line option
  66 //   -XX:+PrintCodeHeapAnalytics
  67 // It will cause a full analysis to be written to tty. In addition, a full
  68 // analysis will be written the first time a "CodeCache full" condition is
  69 // detected.
  70 //
  71 // The command line option produces output identical to the jcmd function


 439 
 440 void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, size_t granularity) {
 441   unsigned int nBlocks_free    = 0;
 442   unsigned int nBlocks_used    = 0;
 443   unsigned int nBlocks_zomb    = 0;
 444   unsigned int nBlocks_disconn = 0;
 445   unsigned int nBlocks_notentr = 0;
 446 
 447   //---<  max & min of TopSizeArray  >---
 448   //  it is sufficient to have these sizes as 32bit unsigned ints.
 449   //  The CodeHeap is limited in size to 4GB. Furthermore, the sizes
 450   //  are stored in _segment_size units, scaling them down by a factor of 64 (at least).
 451   unsigned int  currMax          = 0;
 452   unsigned int  currMin          = 0;
 453   unsigned int  currMin_ix       = 0;
 454   unsigned long total_iterations = 0;
 455 
 456   bool  done             = false;
 457   const int min_granules = 256;
 458   const int max_granules = 512*K; // limits analyzable CodeHeap (with segment_granules) to 32M..128M
 459                                   // results in StatArray size of 20M (= max_granules * 40 Bytes per element)
 460                                   // For a 1GB CodeHeap, the granule size must be at least 2kB to not violate the max_granles limit.
 461   const char* heapName   = get_heapName(heap);
 462   STRINGSTREAM_DECL(ast, out)
 463 
 464   if (!initialization_complete) {
 465     memset(CodeHeapStatArray, 0, sizeof(CodeHeapStatArray));
 466     initialization_complete = true;
 467 
 468     printBox(ast, '=', "C O D E   H E A P   A N A L Y S I S   (general remarks)", NULL);
 469     ast->print_cr("   The code heap analysis function provides deep insights into\n"
 470                   "   the inner workings and the internal state of the Java VM's\n"
 471                   "   code cache - the place where all the JVM generated machine\n"
 472                   "   code is stored.\n"
 473                   "   \n"
 474                   "   This function is designed and provided for support engineers\n"
 475                   "   to help them understand and solve issues in customer systems.\n"
 476                   "   It is not intended for use and interpretation by other persons.\n"
 477                   "   \n");
 478     STRINGSTREAM_FLUSH("")
 479   }
 480   get_HeapStatGlobals(out, heapName);
 481 
 482 
 483   // Since we are (and must be) analyzing the CodeHeap contents under the CodeCache_lock,
 484   // all heap information is "constant" and can be safely extracted/calculated before we
 485   // enter the while() loop. Actually, the loop will only be iterated once.
 486   char*  low_bound     = heap->low_boundary();
 487   size_t size          = heap->capacity();
 488   size_t res_size      = heap->max_capacity();
 489   seg_size             = heap->segment_size();
 490   log2_seg_size        = seg_size == 0 ? 0 : exact_log2(seg_size);  // This is a global static value.
 491 
 492   if (seg_size == 0) {
 493     printBox(ast, '-', "Heap not fully initialized yet, segment size is zero for segment ", heapName);
 494     STRINGSTREAM_FLUSH("")
 495     return;
 496   }
 497 






 498   // Calculate granularity of analysis (and output).
 499   //   The CodeHeap is managed (allocated) in segments (units) of CodeCacheSegmentSize.
 500   //   The CodeHeap can become fairly large, in particular in productive real-life systems.
 501   //
 502   //   It is often neither feasible nor desirable to aggregate the data with the highest possible
 503   //   level of detail, i.e. inspecting and printing each segment on its own.
 504   //
 505   //   The granularity parameter allows to specify the level of detail available in the analysis.
 506   //   It must be a positive multiple of the segment size and should be selected such that enough
 507   //   detail is provided while, at the same time, the printed output does not explode.
 508   //
 509   //   By manipulating the granularity value, we enforce that at least min_granules units
 510   //   of analysis are available. We also enforce an upper limit of max_granules units to
 511   //   keep the amount of allocated storage in check.
 512   //
 513   //   Finally, we adjust the granularity such that each granule covers at most 64k-1 segments.
 514   //   This is necessary to prevent an unsigned short overflow while accumulating space information.
 515   //
 516   assert(granularity > 0, "granularity should be positive.");
 517 


1012       ast->print_cr("Building TopSizeList iterations = %ld", total_iterations);
1013       ast->cr();
1014 
1015       int             reset_val = NMethodSweeper::hotness_counter_reset_val();
1016       double reverse_free_ratio = (res_size > size) ? (double)res_size/(double)(res_size-size) : (double)res_size;
1017       printBox(ast, '-', "Method hotness information at time of this analysis", NULL);
1018       ast->print_cr("Highest possible method temperature:          %12d", reset_val);
1019       ast->print_cr("Threshold for method to be considered 'cold': %12.3f", -reset_val + reverse_free_ratio * NmethodSweepActivity);
1020       if (n_methods > 0) {
1021         avgTemp = hotnessAccumulator/n_methods;
1022         ast->print_cr("min. hotness = %6d", minTemp);
1023         ast->print_cr("avg. hotness = %6d", avgTemp);
1024         ast->print_cr("max. hotness = %6d", maxTemp);
1025       } else {
1026         avgTemp = 0;
1027         ast->print_cr("No hotness data available");
1028       }
1029       STRINGSTREAM_FLUSH("\n")
1030 
1031       // This loop is intentionally printing directly to "out".

1032       out->print("Verifying collected data...");
1033       size_t granule_segs = granule_size>>log2_seg_size;
1034       for (unsigned int ix = 0; ix < granules; ix++) {
1035         if (StatArray[ix].t1_count   > granule_segs) {
1036           out->print_cr("t1_count[%d]   = %d", ix, StatArray[ix].t1_count);
1037         }
1038         if (StatArray[ix].t2_count   > granule_segs) {
1039           out->print_cr("t2_count[%d]   = %d", ix, StatArray[ix].t2_count);
1040         }
1041         if (StatArray[ix].tx_count   > granule_segs) {
1042           out->print_cr("tx_count[%d]   = %d", ix, StatArray[ix].tx_count);
1043         }
1044         if (StatArray[ix].stub_count > granule_segs) {
1045           out->print_cr("stub_count[%d] = %d", ix, StatArray[ix].stub_count);
1046         }
1047         if (StatArray[ix].dead_count > granule_segs) {
1048           out->print_cr("dead_count[%d] = %d", ix, StatArray[ix].dead_count);
1049         }
1050         if (StatArray[ix].t1_space   > granule_segs) {
1051           out->print_cr("t1_space[%d]   = %d", ix, StatArray[ix].t1_space);


1055         }
1056         if (StatArray[ix].tx_space   > granule_segs) {
1057           out->print_cr("tx_space[%d]   = %d", ix, StatArray[ix].tx_space);
1058         }
1059         if (StatArray[ix].stub_space > granule_segs) {
1060           out->print_cr("stub_space[%d] = %d", ix, StatArray[ix].stub_space);
1061         }
1062         if (StatArray[ix].dead_space > granule_segs) {
1063           out->print_cr("dead_space[%d] = %d", ix, StatArray[ix].dead_space);
1064         }
1065         //   this cast is awful! I need it because NT/Intel reports a signed/unsigned mismatch.
1066         if ((size_t)(StatArray[ix].t1_count+StatArray[ix].t2_count+StatArray[ix].tx_count+StatArray[ix].stub_count+StatArray[ix].dead_count) > granule_segs) {
1067           out->print_cr("t1_count[%d] = %d, t2_count[%d] = %d, tx_count[%d] = %d, stub_count[%d] = %d", ix, StatArray[ix].t1_count, ix, StatArray[ix].t2_count, ix, StatArray[ix].tx_count, ix, StatArray[ix].stub_count);
1068         }
1069         if ((size_t)(StatArray[ix].t1_space+StatArray[ix].t2_space+StatArray[ix].tx_space+StatArray[ix].stub_space+StatArray[ix].dead_space) > granule_segs) {
1070           out->print_cr("t1_space[%d] = %d, t2_space[%d] = %d, tx_space[%d] = %d, stub_space[%d] = %d", ix, StatArray[ix].t1_space, ix, StatArray[ix].t2_space, ix, StatArray[ix].tx_space, ix, StatArray[ix].stub_space);
1071         }
1072       }
1073 
1074       // This loop is intentionally printing directly to "out".

1075       if (used_topSizeBlocks > 0) {
1076         unsigned int j = 0;
1077         if (TopSizeArray[0].len != currMax) {
1078           out->print_cr("currMax(%d) differs from TopSizeArray[0].len(%d)", currMax, TopSizeArray[0].len);
1079         }
1080         for (unsigned int i = 0; (TopSizeArray[i].index != tsbStopper) && (j++ < alloc_topSizeBlocks); i = TopSizeArray[i].index) {
1081           if (TopSizeArray[i].len < TopSizeArray[TopSizeArray[i].index].len) {
1082             out->print_cr("sort error at index %d: %d !>= %d", i, TopSizeArray[i].len, TopSizeArray[TopSizeArray[i].index].len);
1083           }
1084         }
1085         if (j >= alloc_topSizeBlocks) {
1086           out->print_cr("Possible loop in TopSizeArray chaining!\n  allocBlocks = %d, usedBlocks = %d", alloc_topSizeBlocks, used_topSizeBlocks);
1087           for (unsigned int i = 0; i < alloc_topSizeBlocks; i++) {
1088             out->print_cr("  TopSizeArray[%d].index = %d, len = %d", i, TopSizeArray[i].index, TopSizeArray[i].len);
1089           }
1090         }
1091       }
1092       out->print_cr("...done\n\n");
1093     } else {
1094       // insane heap state detected. Analysis data incomplete. Just throw it away.


1150   }
1151 
1152   if (!done || (nBlocks_free == 0)) {
1153     if (nBlocks_free == 0) {
1154       printBox(ast, '-', "no free blocks found in ", heapName);
1155     } else if (!done) {
1156       ast->print_cr("Free block count mismatch could not be resolved.");
1157       ast->print_cr("Try to run \"aggregate\" function to update counters");
1158     }
1159     STRINGSTREAM_FLUSH("")
1160 
1161     //---< discard old array and update global values  >---
1162     discard_FreeArray(out);
1163     set_HeapStatGlobals(out, heapName);
1164     return;
1165   }
1166 
1167   //---<  calculate and fill remaining fields  >---
1168   if (FreeArray != NULL) {
1169     // This loop is intentionally printing directly to "out".

1170     for (unsigned int ix = 0; ix < alloc_freeBlocks-1; ix++) {
1171       size_t lenSum = 0;
1172       FreeArray[ix].gap = (unsigned int)((address)FreeArray[ix+1].start - ((address)FreeArray[ix].start + FreeArray[ix].len));
1173       for (HeapBlock *h = heap->next_block(FreeArray[ix].start); (h != NULL) && (h != FreeArray[ix+1].start); h = heap->next_block(h)) {
1174         CodeBlob *cb  = (CodeBlob*)(heap->find_start(h));
1175         if ((cb != NULL) && !cb->is_nmethod()) {
1176           FreeArray[ix].stubs_in_gap = true;
1177         }
1178         FreeArray[ix].n_gapBlocks++;
1179         lenSum += h->length()<<log2_seg_size;
1180         if (((address)h < ((address)FreeArray[ix].start+FreeArray[ix].len)) || (h >= FreeArray[ix+1].start)) {
1181           out->print_cr("unsorted occupied CodeHeap block found @ %p, gap interval [%p, %p)", h, (address)FreeArray[ix].start+FreeArray[ix].len, FreeArray[ix+1].start);
1182         }
1183       }
1184       if (lenSum != FreeArray[ix].gap) {
1185         out->print_cr("Length mismatch for gap between FreeBlk[%d] and FreeBlk[%d]. Calculated: %d, accumulated: %d.", ix, ix+1, FreeArray[ix].gap, (unsigned int)lenSum);
1186       }
1187     }
1188   }
1189   set_HeapStatGlobals(out, heapName);


1207   STRINGSTREAM_DECL(ast, out)
1208 
1209   {
1210     printBox(ast, '=', "U S E D   S P A C E   S T A T I S T I C S   for ", heapName);
1211     ast->print_cr("Note: The Top%d list of the largest used blocks associates method names\n"
1212                   "      and other identifying information with the block size data.\n"
1213                   "\n"
1214                   "      Method names are dynamically retrieved from the code cache at print time.\n"
1215                   "      Due to the living nature of the code cache and because the CodeCache_lock\n"
1216                   "      is not continuously held, the displayed name might be wrong or no name\n"
1217                   "      might be found at all. The likelihood for that to happen increases\n"
1218                   "      over time passed between analysis and print step.\n", used_topSizeBlocks);
1219     STRINGSTREAM_FLUSH_LOCKED("\n")
1220   }
1221 
1222   //----------------------------
1223   //--  Print Top Used Blocks --
1224   //----------------------------
1225   {
1226     char*     low_bound = heap->low_boundary();

1227 
1228     printBox(ast, '-', "Largest Used Blocks in ", heapName);
1229     print_blobType_legend(ast);
1230 
1231     ast->fill_to(51);
1232     ast->print("%4s", "blob");
1233     ast->fill_to(56);
1234     ast->print("%9s", "compiler");
1235     ast->fill_to(66);
1236     ast->print_cr("%6s", "method");
1237     ast->print_cr("%18s %13s %17s %4s %9s  %5s %s",      "Addr(module)      ", "offset", "size", "type", " type lvl", " temp", "Name");
1238     STRINGSTREAM_FLUSH_LOCKED("")
1239 
1240     //---<  print Top Ten Used Blocks  >---
1241     if (used_topSizeBlocks > 0) {
1242       unsigned int printed_topSizeBlocks = 0;
1243       for (unsigned int i = 0; i != tsbStopper; i = TopSizeArray[i].index) {
1244         printed_topSizeBlocks++;
1245         CodeBlob*   this_blob = (CodeBlob*)(heap->find_start(TopSizeArray[i].start));
1246         nmethod*           nm = NULL;
1247         const char* blob_name = "unnamed blob";
1248         if (this_blob != NULL) {







1249           blob_name = this_blob->name();
1250           nm        = this_blob->as_nmethod_or_null();

1251           //---<  blob address  >---
1252           ast->print(INTPTR_FORMAT, p2i(this_blob));
1253           ast->fill_to(19);
1254           //---<  blob offset from CodeHeap begin  >---
1255           ast->print("(+" PTR32_FORMAT ")", (unsigned int)((char*)this_blob-low_bound));
1256           ast->fill_to(33);
1257         } else {
1258           //---<  block address  >---
1259           ast->print(INTPTR_FORMAT, p2i(TopSizeArray[i].start));
1260           ast->fill_to(19);
1261           //---<  block offset from CodeHeap begin  >---
1262           ast->print("(+" PTR32_FORMAT ")", (unsigned int)((char*)TopSizeArray[i].start-low_bound));
1263           ast->fill_to(33);
1264         }
1265 
1266 
1267         //---<  print size, name, and signature (for nMethods)  >---
1268         if ((nm != NULL) && (nm->method() != NULL)) {


1269           ResourceMark rm;







1270           //---<  nMethod size in hex  >---
1271           unsigned int total_size = nm->total_size();
1272           ast->print(PTR32_FORMAT, total_size);
1273           ast->print("(" SIZE_FORMAT_W(4) "K)", total_size/K);
1274           ast->fill_to(51);
1275           ast->print("  %c", blobTypeChar[TopSizeArray[i].type]);
1276           //---<  compiler information  >---
1277           ast->fill_to(56);
1278           ast->print("%5s %3d", compTypeName[TopSizeArray[i].compiler], TopSizeArray[i].level);
1279           //---<  method temperature  >---
1280           ast->fill_to(67);
1281           ast->print("%5d", nm->hotness_counter());
1282           //---<  name and signature  >---
1283           ast->fill_to(67+6);
1284           if (nm->is_in_use())        {blob_name = nm->method()->name_and_sig_as_C_string(); }
1285           if (nm->is_not_entrant())   {blob_name = nm->method()->name_and_sig_as_C_string(); }
1286           if (nm->is_not_installed()) {ast->print("%s", " not (yet) installed method "); }
1287           if (nm->is_zombie())        {ast->print("%s", " zombie method "); }


1288           ast->print("%s", blob_name);
1289         } else {
1290           //---<  block size in hex  >---
1291           ast->print(PTR32_FORMAT, (unsigned int)(TopSizeArray[i].len<<log2_seg_size));
1292           ast->print("(" SIZE_FORMAT_W(4) "K)", (TopSizeArray[i].len<<log2_seg_size)/K);
1293           //---<  no compiler information  >---
1294           ast->fill_to(56);
1295           //---<  name and signature  >---
1296           ast->fill_to(67+6);
1297           ast->print("%s", blob_name);
1298         }
1299         STRINGSTREAM_FLUSH_LOCKED("\n")
1300       }
1301       if (used_topSizeBlocks != printed_topSizeBlocks) {
1302         ast->print_cr("used blocks: %d, printed blocks: %d", used_topSizeBlocks, printed_topSizeBlocks);
1303         STRINGSTREAM_FLUSH("")
1304         for (unsigned int i = 0; i < alloc_topSizeBlocks; i++) {
1305           ast->print_cr("  TopSizeArray[%d].index = %d, len = %d", i, TopSizeArray[i].index, TopSizeArray[i].len);
1306           STRINGSTREAM_FLUSH("")
1307         }


2071 }
2072 
2073 
2074 void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
2075   if (!initialization_complete) {
2076     return;
2077   }
2078 
2079   const char* heapName   = get_heapName(heap);
2080   get_HeapStatGlobals(out, heapName);
2081 
2082   if ((StatArray == NULL) || (alloc_granules == 0)) {
2083     return;
2084   }
2085   STRINGSTREAM_DECL(ast, out)
2086 
2087   unsigned int granules_per_line  = 128;
2088   char*        low_bound          = heap->low_boundary();
2089   CodeBlob*    last_blob          = NULL;
2090   bool         name_in_addr_range = true;

2091 
2092   //---<  print at least 128K per block (i.e. between headers)  >---
2093   if (granules_per_line*granule_size < 128*K) {
2094     granules_per_line = (unsigned int)((128*K)/granule_size);
2095   }
2096 
2097   printBox(ast, '=', "M E T H O D   N A M E S   for ", heapName);
2098   ast->print_cr("  Method names are dynamically retrieved from the code cache at print time.\n"
2099                 "  Due to the living nature of the code heap and because the CodeCache_lock\n"
2100                 "  is not continuously held, the displayed name might be wrong or no name\n"
2101                 "  might be found at all. The likelihood for that to happen increases\n"
2102                 "  over time passed between aggregtion and print steps.\n");
2103   STRINGSTREAM_FLUSH_LOCKED("")
2104 
2105   for (unsigned int ix = 0; ix < alloc_granules; ix++) {
2106     //---<  print a new blob on a new line  >---
2107     if (ix%granules_per_line == 0) {
2108       if (!name_in_addr_range) {
2109         ast->print_cr("No methods, blobs, or stubs found in this address range");
2110       }
2111       name_in_addr_range = false;
2112 
2113       size_t end_ix = (ix+granules_per_line <= alloc_granules) ? ix+granules_per_line : alloc_granules;
2114       ast->cr();
2115       ast->print_cr("--------------------------------------------------------------------");
2116       ast->print_cr("Address range [" INTPTR_FORMAT "," INTPTR_FORMAT "), " SIZE_FORMAT "k", p2i(low_bound+ix*granule_size), p2i(low_bound + end_ix*granule_size), (end_ix - ix)*granule_size/(size_t)K);
2117       ast->print_cr("--------------------------------------------------------------------");
2118       STRINGSTREAM_FLUSH_LOCKED("")
2119     }
2120     // Only check granule if it contains at least one blob.
2121     unsigned int nBlobs  = StatArray[ix].t1_count   + StatArray[ix].t2_count + StatArray[ix].tx_count +
2122                            StatArray[ix].stub_count + StatArray[ix].dead_count;
2123     if (nBlobs > 0 ) {
2124     for (unsigned int is = 0; is < granule_size; is+=(unsigned int)seg_size) {
2125       // heap->find_start() is safe. Only working with _segmap. Returns NULL or void*. Returned CodeBlob may be uninitialized.
2126       CodeBlob* this_blob = (CodeBlob *)(heap->find_start(low_bound+ix*granule_size+is));
2127       bool blob_initialized = (this_blob != NULL) && (this_blob->header_size() >= 0) && (this_blob->relocation_size() >= 0) &&
2128                               ((address)this_blob + this_blob->header_size() == (address)(this_blob->relocation_begin())) &&
2129                               ((address)this_blob + CodeBlob::align_code_offset(this_blob->header_size() + this_blob->relocation_size()) == (address)(this_blob->content_begin())) &&
2130                               os::is_readable_pointer((address)(this_blob->relocation_begin())) &&
2131                               os::is_readable_pointer(this_blob->content_begin());
2132       // blob could have been flushed, freed, and merged.
2133       // this_blob < last_blob is an indicator for that.
2134       if (blob_initialized && (this_blob > last_blob)) {
2135         last_blob          = this_blob;
2136 
2137         //---<  get type and name  >---
2138         blobType       cbType = noType;
2139         if (segment_granules) {
2140           cbType = (blobType)StatArray[ix].type;
2141         } else {


2142           cbType = get_cbType(this_blob);
2143         }








2144         // this_blob->name() could return NULL if no name was given to CTOR. Inlined, maybe invisible on stack
2145         const char* blob_name = this_blob->name();
2146         if ((blob_name == NULL) || !os::is_readable_pointer(blob_name)) {
2147           blob_name = "<unavailable>";
2148         }

2149 
2150         //---<  print table header for new print range  >---
2151         if (!name_in_addr_range) {
2152           name_in_addr_range = true;
2153           ast->fill_to(51);
2154           ast->print("%9s", "compiler");
2155           ast->fill_to(61);
2156           ast->print_cr("%6s", "method");
2157           ast->print_cr("%18s %13s %17s %9s  %5s %18s  %s", "Addr(module)      ", "offset", "size", " type lvl", " temp", "blobType          ", "Name");
2158           STRINGSTREAM_FLUSH_LOCKED("")
2159         }
2160 
2161         //---<  print line prefix (address and offset from CodeHeap start)  >---
2162         ast->print(INTPTR_FORMAT, p2i(this_blob));
2163         ast->fill_to(19);
2164         ast->print("(+" PTR32_FORMAT ")", (unsigned int)((char*)this_blob-low_bound));
2165         ast->fill_to(33);
2166 
2167         // this_blob->as_nmethod_or_null() is safe. Inlined, maybe invisible on stack.
2168         nmethod*    nm     = this_blob->as_nmethod_or_null();
2169         if (CompiledMethod::nmethod_access_is_safe(nm)) {
2170           Method* method = nm->method();
2171           ResourceMark rm;
2172           //---<  collect all data to locals as quickly as possible  >---
2173           unsigned int total_size = nm->total_size();
2174           int          hotness    = nm->hotness_counter();
2175           bool         get_name   = (cbType == nMethod_inuse) || (cbType == nMethod_notused);
2176           //---<  nMethod size in hex  >---
2177           ast->print(PTR32_FORMAT, total_size);
2178           ast->print("(" SIZE_FORMAT_W(4) "K)", total_size/K);
2179           //---<  compiler information  >---
2180           ast->fill_to(51);
2181           ast->print("%5s %3d", compTypeName[StatArray[ix].compiler], StatArray[ix].level);
2182           //---<  method temperature  >---
2183           ast->fill_to(62);
2184           ast->print("%5d", hotness);
2185           //---<  name and signature  >---
2186           ast->fill_to(62+6);
2187           ast->print("%s", blobTypeName[cbType]);
2188           ast->fill_to(82+6);
2189           if (cbType == nMethod_dead) {
2190             ast->print("%14s", " zombie method");
2191           }
2192 
2193           if (get_name) {
2194             Symbol* methName  = method->name();
2195             const char*   methNameS = (methName == NULL) ? NULL : methName->as_C_string();
2196             methNameS = (methNameS == NULL) ? "<method name unavailable>" : methNameS;
2197             Symbol* methSig   = method->signature();
2198             const char*   methSigS  = (methSig  == NULL) ? NULL : methSig->as_C_string();
2199             methSigS  = (methSigS  == NULL) ? "<method signature unavailable>" : methSigS;
2200             ast->print("%s", methNameS);
2201             ast->print("%s", methSigS);
2202           } else {
2203             ast->print("%s", blob_name);
2204           }
2205         } else {
2206           ast->fill_to(62+6);
2207           ast->print("%s", blobTypeName[cbType]);
2208           ast->fill_to(82+6);
2209           ast->print("%s", blob_name);



2210         }
2211         STRINGSTREAM_FLUSH_LOCKED("\n")
2212       } else if (!blob_initialized && (this_blob != last_blob) && (this_blob != NULL)) {
2213         last_blob          = this_blob;
2214         STRINGSTREAM_FLUSH_LOCKED("\n")
2215       }
2216     }
2217     } // nBlobs > 0
2218   }
2219   STRINGSTREAM_FLUSH_LOCKED("\n\n")
2220 }
2221 
2222 
2223 void CodeHeapState::printBox(outputStream* ast, const char border, const char* text1, const char* text2) {
2224   unsigned int lineLen = 1 + 2 + 2 + 1;
2225   char edge, frame;
2226 
2227   if (text1 != NULL) {
2228     lineLen += (unsigned int)strlen(text1); // text1 is much shorter than MAX_INT chars.
2229   }
2230   if (text2 != NULL) {
2231     lineLen += (unsigned int)strlen(text2); // text2 is much shorter than MAX_INT chars.
2232   }


2359       ast->reset();
2360     }
2361 
2362     ast->print(INTPTR_FORMAT, p2i(low_bound + ix*granule_size));
2363     ast->fill_to(19);
2364     ast->print("(+" PTR32_FORMAT "): |", (unsigned int)(ix*granule_size));
2365   }
2366 }
2367 
2368 CodeHeapState::blobType CodeHeapState::get_cbType(CodeBlob* cb) {
2369   if ((cb != NULL) && os::is_readable_pointer(cb)) {
2370     if (cb->is_runtime_stub())                return runtimeStub;
2371     if (cb->is_deoptimization_stub())         return deoptimizationStub;
2372     if (cb->is_uncommon_trap_stub())          return uncommonTrapStub;
2373     if (cb->is_exception_stub())              return exceptionStub;
2374     if (cb->is_safepoint_stub())              return safepointStub;
2375     if (cb->is_adapter_blob())                return adapterBlob;
2376     if (cb->is_method_handles_adapter_blob()) return mh_adapterBlob;
2377     if (cb->is_buffer_blob())                 return bufferBlob;
2378 



2379     nmethod*  nm = cb->as_nmethod_or_null();
2380     if (nm != NULL) { // no is_readable check required, nm = (nmethod*)cb.
2381       if (nm->is_not_installed()) return nMethod_inconstruction;
2382       if (nm->is_zombie())        return nMethod_dead;
2383       if (nm->is_unloaded())      return nMethod_unloaded;
2384       if (nm->is_in_use())        return nMethod_inuse;
2385       if (nm->is_alive() && !(nm->is_not_entrant()))   return nMethod_notused;
2386       if (nm->is_alive())         return nMethod_alive;
2387       return nMethod_dead;
2388     }
2389   }

2390   return noType;











2391 }
   1 /*
   2  * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2018, 2019 SAP SE. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include "precompiled.hpp"
  27 #include "code/codeHeapState.hpp"
  28 #include "compiler/compileBroker.hpp"
  29 #include "runtime/sweeper.hpp"
  30 
  31 // -------------------------
  32 // |  General Description  |
  33 // -------------------------
  34 // The CodeHeap state analytics are divided in two parts.
  35 // The first part examines the entire CodeHeap and aggregates all
  36 // information that is believed useful/important.
  37 //
  38 // Aggregation condenses the information of a piece of the CodeHeap
  39 // (4096 bytes by default) into an analysis granule. These granules
  40 // contain enough detail to gain initial insight while keeping the
  41 // internal structure sizes in check.
  42 //





  43 // The second part, which consists of several, independent steps,
  44 // prints the previously collected information with emphasis on
  45 // various aspects.
  46 //
  47 // The CodeHeap is a living thing. Therefore, protection against concurrent
  48 // modification (by acquiring the CodeCache_lock) is necessary. It has
  49 // to be provided by the caller of the analysis functions.
  50 // If the CodeCache_lock is not held, the analysis functions may print
  51 // less detailed information or may just do nothing. It is by intention
  52 // that an unprotected invocation is not abnormally terminated.
  53 //
  54 // Data collection and printing is done on an "on request" basis.
  55 // While no request is being processed, there is no impact on performance.
  56 // The CodeHeap state analytics do have some memory footprint.
  57 // The "aggregate" step allocates some data structures to hold the aggregated
  58 // information for later output. These data structures live until they are
  59 // explicitly discarded (function "discard") or until the VM terminates.
  60 // There is one exception: the function "all" does not leave any data
  61 // structures allocated.
  62 //
  63 // Requests for real-time, on-the-fly analysis can be issued via
  64 //   jcmd <pid> Compiler.CodeHeap_Analytics [<function>] [<granularity>]
  65 //
  66 // If you are (only) interested in how the CodeHeap looks like after running
  67 // a sample workload, you can use the command line option
  68 //   -XX:+PrintCodeHeapAnalytics
  69 // It will cause a full analysis to be written to tty. In addition, a full
  70 // analysis will be written the first time a "CodeCache full" condition is
  71 // detected.
  72 //
  73 // The command line option produces output identical to the jcmd function


 441 
 442 void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, size_t granularity) {
 443   unsigned int nBlocks_free    = 0;
 444   unsigned int nBlocks_used    = 0;
 445   unsigned int nBlocks_zomb    = 0;
 446   unsigned int nBlocks_disconn = 0;
 447   unsigned int nBlocks_notentr = 0;
 448 
 449   //---<  max & min of TopSizeArray  >---
 450   //  it is sufficient to have these sizes as 32bit unsigned ints.
 451   //  The CodeHeap is limited in size to 4GB. Furthermore, the sizes
 452   //  are stored in _segment_size units, scaling them down by a factor of 64 (at least).
 453   unsigned int  currMax          = 0;
 454   unsigned int  currMin          = 0;
 455   unsigned int  currMin_ix       = 0;
 456   unsigned long total_iterations = 0;
 457 
 458   bool  done             = false;
 459   const int min_granules = 256;
 460   const int max_granules = 512*K; // limits analyzable CodeHeap (with segment_granules) to 32M..128M
 461                                   // results in StatArray size of 24M (= max_granules * 48 Bytes per element)
 462                                   // For a 1GB CodeHeap, the granule size must be at least 2kB to not violate the max_granles limit.
 463   const char* heapName   = get_heapName(heap);
 464   STRINGSTREAM_DECL(ast, out)
 465 
 466   if (!initialization_complete) {
 467     memset(CodeHeapStatArray, 0, sizeof(CodeHeapStatArray));
 468     initialization_complete = true;
 469 
 470     printBox(ast, '=', "C O D E   H E A P   A N A L Y S I S   (general remarks)", NULL);
 471     ast->print_cr("   The code heap analysis function provides deep insights into\n"
 472                   "   the inner workings and the internal state of the Java VM's\n"
 473                   "   code cache - the place where all the JVM generated machine\n"
 474                   "   code is stored.\n"
 475                   "   \n"
 476                   "   This function is designed and provided for support engineers\n"
 477                   "   to help them understand and solve issues in customer systems.\n"
 478                   "   It is not intended for use and interpretation by other persons.\n"
 479                   "   \n");
 480     STRINGSTREAM_FLUSH("")
 481   }
 482   get_HeapStatGlobals(out, heapName);
 483 
 484 
 485   // Since we are (and must be) analyzing the CodeHeap contents under the CodeCache_lock,
 486   // all heap information is "constant" and can be safely extracted/calculated before we
 487   // enter the while() loop. Actually, the loop will only be iterated once.
 488   char*  low_bound     = heap->low_boundary();
 489   size_t size          = heap->capacity();
 490   size_t res_size      = heap->max_capacity();
 491   seg_size             = heap->segment_size();
 492   log2_seg_size        = seg_size == 0 ? 0 : exact_log2(seg_size);  // This is a global static value.
 493 
 494   if (seg_size == 0) {
 495     printBox(ast, '-', "Heap not fully initialized yet, segment size is zero for segment ", heapName);
 496     STRINGSTREAM_FLUSH("")
 497     return;
 498   }
 499 
 500   if (!CodeCache_lock->owned_by_self()) {
 501     printBox(ast, '-', "aggregate function called without holding the CodeCache_lock for ", heapName);
 502     STRINGSTREAM_FLUSH("")
 503     return;
 504   }
 505 
 506   // Calculate granularity of analysis (and output).
 507   //   The CodeHeap is managed (allocated) in segments (units) of CodeCacheSegmentSize.
 508   //   The CodeHeap can become fairly large, in particular in productive real-life systems.
 509   //
 510   //   It is often neither feasible nor desirable to aggregate the data with the highest possible
 511   //   level of detail, i.e. inspecting and printing each segment on its own.
 512   //
 513   //   The granularity parameter allows to specify the level of detail available in the analysis.
 514   //   It must be a positive multiple of the segment size and should be selected such that enough
 515   //   detail is provided while, at the same time, the printed output does not explode.
 516   //
 517   //   By manipulating the granularity value, we enforce that at least min_granules units
 518   //   of analysis are available. We also enforce an upper limit of max_granules units to
 519   //   keep the amount of allocated storage in check.
 520   //
 521   //   Finally, we adjust the granularity such that each granule covers at most 64k-1 segments.
 522   //   This is necessary to prevent an unsigned short overflow while accumulating space information.
 523   //
 524   assert(granularity > 0, "granularity should be positive.");
 525 


1020       ast->print_cr("Building TopSizeList iterations = %ld", total_iterations);
1021       ast->cr();
1022 
1023       int             reset_val = NMethodSweeper::hotness_counter_reset_val();
1024       double reverse_free_ratio = (res_size > size) ? (double)res_size/(double)(res_size-size) : (double)res_size;
1025       printBox(ast, '-', "Method hotness information at time of this analysis", NULL);
1026       ast->print_cr("Highest possible method temperature:          %12d", reset_val);
1027       ast->print_cr("Threshold for method to be considered 'cold': %12.3f", -reset_val + reverse_free_ratio * NmethodSweepActivity);
1028       if (n_methods > 0) {
1029         avgTemp = hotnessAccumulator/n_methods;
1030         ast->print_cr("min. hotness = %6d", minTemp);
1031         ast->print_cr("avg. hotness = %6d", avgTemp);
1032         ast->print_cr("max. hotness = %6d", maxTemp);
1033       } else {
1034         avgTemp = 0;
1035         ast->print_cr("No hotness data available");
1036       }
1037       STRINGSTREAM_FLUSH("\n")
1038 
1039       // This loop is intentionally printing directly to "out".
1040       // It should not print anything, anyway.
1041       out->print("Verifying collected data...");
1042       size_t granule_segs = granule_size>>log2_seg_size;
1043       for (unsigned int ix = 0; ix < granules; ix++) {
1044         if (StatArray[ix].t1_count   > granule_segs) {
1045           out->print_cr("t1_count[%d]   = %d", ix, StatArray[ix].t1_count);
1046         }
1047         if (StatArray[ix].t2_count   > granule_segs) {
1048           out->print_cr("t2_count[%d]   = %d", ix, StatArray[ix].t2_count);
1049         }
1050         if (StatArray[ix].tx_count   > granule_segs) {
1051           out->print_cr("tx_count[%d]   = %d", ix, StatArray[ix].tx_count);
1052         }
1053         if (StatArray[ix].stub_count > granule_segs) {
1054           out->print_cr("stub_count[%d] = %d", ix, StatArray[ix].stub_count);
1055         }
1056         if (StatArray[ix].dead_count > granule_segs) {
1057           out->print_cr("dead_count[%d] = %d", ix, StatArray[ix].dead_count);
1058         }
1059         if (StatArray[ix].t1_space   > granule_segs) {
1060           out->print_cr("t1_space[%d]   = %d", ix, StatArray[ix].t1_space);


1064         }
1065         if (StatArray[ix].tx_space   > granule_segs) {
1066           out->print_cr("tx_space[%d]   = %d", ix, StatArray[ix].tx_space);
1067         }
1068         if (StatArray[ix].stub_space > granule_segs) {
1069           out->print_cr("stub_space[%d] = %d", ix, StatArray[ix].stub_space);
1070         }
1071         if (StatArray[ix].dead_space > granule_segs) {
1072           out->print_cr("dead_space[%d] = %d", ix, StatArray[ix].dead_space);
1073         }
1074         //   this cast is awful! I need it because NT/Intel reports a signed/unsigned mismatch.
1075         if ((size_t)(StatArray[ix].t1_count+StatArray[ix].t2_count+StatArray[ix].tx_count+StatArray[ix].stub_count+StatArray[ix].dead_count) > granule_segs) {
1076           out->print_cr("t1_count[%d] = %d, t2_count[%d] = %d, tx_count[%d] = %d, stub_count[%d] = %d", ix, StatArray[ix].t1_count, ix, StatArray[ix].t2_count, ix, StatArray[ix].tx_count, ix, StatArray[ix].stub_count);
1077         }
1078         if ((size_t)(StatArray[ix].t1_space+StatArray[ix].t2_space+StatArray[ix].tx_space+StatArray[ix].stub_space+StatArray[ix].dead_space) > granule_segs) {
1079           out->print_cr("t1_space[%d] = %d, t2_space[%d] = %d, tx_space[%d] = %d, stub_space[%d] = %d", ix, StatArray[ix].t1_space, ix, StatArray[ix].t2_space, ix, StatArray[ix].tx_space, ix, StatArray[ix].stub_space);
1080         }
1081       }
1082 
1083       // This loop is intentionally printing directly to "out".
1084       // It should not print anything, anyway.
1085       if (used_topSizeBlocks > 0) {
1086         unsigned int j = 0;
1087         if (TopSizeArray[0].len != currMax) {
1088           out->print_cr("currMax(%d) differs from TopSizeArray[0].len(%d)", currMax, TopSizeArray[0].len);
1089         }
1090         for (unsigned int i = 0; (TopSizeArray[i].index != tsbStopper) && (j++ < alloc_topSizeBlocks); i = TopSizeArray[i].index) {
1091           if (TopSizeArray[i].len < TopSizeArray[TopSizeArray[i].index].len) {
1092             out->print_cr("sort error at index %d: %d !>= %d", i, TopSizeArray[i].len, TopSizeArray[TopSizeArray[i].index].len);
1093           }
1094         }
1095         if (j >= alloc_topSizeBlocks) {
1096           out->print_cr("Possible loop in TopSizeArray chaining!\n  allocBlocks = %d, usedBlocks = %d", alloc_topSizeBlocks, used_topSizeBlocks);
1097           for (unsigned int i = 0; i < alloc_topSizeBlocks; i++) {
1098             out->print_cr("  TopSizeArray[%d].index = %d, len = %d", i, TopSizeArray[i].index, TopSizeArray[i].len);
1099           }
1100         }
1101       }
1102       out->print_cr("...done\n\n");
1103     } else {
1104       // insane heap state detected. Analysis data incomplete. Just throw it away.


1160   }
1161 
1162   if (!done || (nBlocks_free == 0)) {
1163     if (nBlocks_free == 0) {
1164       printBox(ast, '-', "no free blocks found in ", heapName);
1165     } else if (!done) {
1166       ast->print_cr("Free block count mismatch could not be resolved.");
1167       ast->print_cr("Try to run \"aggregate\" function to update counters");
1168     }
1169     STRINGSTREAM_FLUSH("")
1170 
1171     //---< discard old array and update global values  >---
1172     discard_FreeArray(out);
1173     set_HeapStatGlobals(out, heapName);
1174     return;
1175   }
1176 
1177   //---<  calculate and fill remaining fields  >---
1178   if (FreeArray != NULL) {
1179     // This loop is intentionally printing directly to "out".
1180     // It should not print anything, anyway.
1181     for (unsigned int ix = 0; ix < alloc_freeBlocks-1; ix++) {
1182       size_t lenSum = 0;
1183       FreeArray[ix].gap = (unsigned int)((address)FreeArray[ix+1].start - ((address)FreeArray[ix].start + FreeArray[ix].len));
1184       for (HeapBlock *h = heap->next_block(FreeArray[ix].start); (h != NULL) && (h != FreeArray[ix+1].start); h = heap->next_block(h)) {
1185         CodeBlob *cb  = (CodeBlob*)(heap->find_start(h));
1186         if ((cb != NULL) && !cb->is_nmethod()) {
1187           FreeArray[ix].stubs_in_gap = true;
1188         }
1189         FreeArray[ix].n_gapBlocks++;
1190         lenSum += h->length()<<log2_seg_size;
1191         if (((address)h < ((address)FreeArray[ix].start+FreeArray[ix].len)) || (h >= FreeArray[ix+1].start)) {
1192           out->print_cr("unsorted occupied CodeHeap block found @ %p, gap interval [%p, %p)", h, (address)FreeArray[ix].start+FreeArray[ix].len, FreeArray[ix+1].start);
1193         }
1194       }
1195       if (lenSum != FreeArray[ix].gap) {
1196         out->print_cr("Length mismatch for gap between FreeBlk[%d] and FreeBlk[%d]. Calculated: %d, accumulated: %d.", ix, ix+1, FreeArray[ix].gap, (unsigned int)lenSum);
1197       }
1198     }
1199   }
1200   set_HeapStatGlobals(out, heapName);


1218   STRINGSTREAM_DECL(ast, out)
1219 
1220   {
1221     printBox(ast, '=', "U S E D   S P A C E   S T A T I S T I C S   for ", heapName);
1222     ast->print_cr("Note: The Top%d list of the largest used blocks associates method names\n"
1223                   "      and other identifying information with the block size data.\n"
1224                   "\n"
1225                   "      Method names are dynamically retrieved from the code cache at print time.\n"
1226                   "      Due to the living nature of the code cache and because the CodeCache_lock\n"
1227                   "      is not continuously held, the displayed name might be wrong or no name\n"
1228                   "      might be found at all. The likelihood for that to happen increases\n"
1229                   "      over time passed between analysis and print step.\n", used_topSizeBlocks);
1230     STRINGSTREAM_FLUSH_LOCKED("\n")
1231   }
1232 
1233   //----------------------------
1234   //--  Print Top Used Blocks --
1235   //----------------------------
1236   {
1237     char*     low_bound = heap->low_boundary();
1238     bool      have_CodeCache_lock = CodeCache_lock->owned_by_self();
1239 
1240     printBox(ast, '-', "Largest Used Blocks in ", heapName);
1241     print_blobType_legend(ast);
1242 
1243     ast->fill_to(51);
1244     ast->print("%4s", "blob");
1245     ast->fill_to(56);
1246     ast->print("%9s", "compiler");
1247     ast->fill_to(66);
1248     ast->print_cr("%6s", "method");
1249     ast->print_cr("%18s %13s %17s %4s %9s  %5s %s",      "Addr(module)      ", "offset", "size", "type", " type lvl", " temp", "Name");
1250     STRINGSTREAM_FLUSH_LOCKED("")
1251 
1252     //---<  print Top Ten Used Blocks  >---
1253     if (used_topSizeBlocks > 0) {
1254       unsigned int printed_topSizeBlocks = 0;
1255       for (unsigned int i = 0; i != tsbStopper; i = TopSizeArray[i].index) {
1256         printed_topSizeBlocks++;

1257         nmethod*           nm = NULL;
1258         const char* blob_name = "unnamed blob or blob name unavailable";
1259         // heap->find_start() is safe. Only works on _segmap.
1260         // Returns NULL or void*. Returned CodeBlob may be uninitialized.
1261         HeapBlock* heapBlock = TopSizeArray[i].start;
1262         CodeBlob*  this_blob = (CodeBlob*)(heap->find_start(heapBlock));
1263         bool    blob_is_safe = blob_access_is_safe(this_blob, NULL);
1264         if (blob_is_safe) {
1265           //---<  access these fields only if we own the CodeCache_lock  >---
1266           if (have_CodeCache_lock) {
1267             blob_name = this_blob->name();
1268             nm        = this_blob->as_nmethod_or_null();
1269           }
1270           //---<  blob address  >---
1271           ast->print(INTPTR_FORMAT, p2i(this_blob));
1272           ast->fill_to(19);
1273           //---<  blob offset from CodeHeap begin  >---
1274           ast->print("(+" PTR32_FORMAT ")", (unsigned int)((char*)this_blob-low_bound));
1275           ast->fill_to(33);
1276         } else {
1277           //---<  block address  >---
1278           ast->print(INTPTR_FORMAT, p2i(TopSizeArray[i].start));
1279           ast->fill_to(19);
1280           //---<  block offset from CodeHeap begin  >---
1281           ast->print("(+" PTR32_FORMAT ")", (unsigned int)((char*)TopSizeArray[i].start-low_bound));
1282           ast->fill_to(33);
1283         }
1284 

1285         //---<  print size, name, and signature (for nMethods)  >---
1286         // access nmethod and Method fields only if we own the CodeCache_lock.
1287         // This fact is implicitly transported via nm != NULL.
1288         if (CompiledMethod::nmethod_access_is_safe(nm)) {
1289           ResourceMark rm;
1290           Method* method = nm->method();
1291           if (nm->is_in_use()) {
1292             blob_name = method->name_and_sig_as_C_string();
1293           }
1294           if (nm->is_not_entrant()) {
1295             blob_name = method->name_and_sig_as_C_string();
1296           }
1297           //---<  nMethod size in hex  >---
1298           unsigned int total_size = nm->total_size();
1299           ast->print(PTR32_FORMAT, total_size);
1300           ast->print("(" SIZE_FORMAT_W(4) "K)", total_size/K);
1301           ast->fill_to(51);
1302           ast->print("  %c", blobTypeChar[TopSizeArray[i].type]);
1303           //---<  compiler information  >---
1304           ast->fill_to(56);
1305           ast->print("%5s %3d", compTypeName[TopSizeArray[i].compiler], TopSizeArray[i].level);
1306           //---<  method temperature  >---
1307           ast->fill_to(67);
1308           ast->print("%5d", nm->hotness_counter());
1309           //---<  name and signature  >---
1310           ast->fill_to(67+6);
1311           if (nm->is_not_installed()) {
1312             ast->print(" not (yet) installed method ");
1313           }
1314           if (nm->is_zombie()) {
1315             ast->print(" zombie method ");
1316           }
1317           ast->print("%s", blob_name);
1318         } else {
1319           //---<  block size in hex  >---
1320           ast->print(PTR32_FORMAT, (unsigned int)(TopSizeArray[i].len<<log2_seg_size));
1321           ast->print("(" SIZE_FORMAT_W(4) "K)", (TopSizeArray[i].len<<log2_seg_size)/K);
1322           //---<  no compiler information  >---
1323           ast->fill_to(56);
1324           //---<  name and signature  >---
1325           ast->fill_to(67+6);
1326           ast->print("%s", blob_name);
1327         }
1328         STRINGSTREAM_FLUSH_LOCKED("\n")
1329       }
1330       if (used_topSizeBlocks != printed_topSizeBlocks) {
1331         ast->print_cr("used blocks: %d, printed blocks: %d", used_topSizeBlocks, printed_topSizeBlocks);
1332         STRINGSTREAM_FLUSH("")
1333         for (unsigned int i = 0; i < alloc_topSizeBlocks; i++) {
1334           ast->print_cr("  TopSizeArray[%d].index = %d, len = %d", i, TopSizeArray[i].index, TopSizeArray[i].len);
1335           STRINGSTREAM_FLUSH("")
1336         }


2100 }
2101 
2102 
2103 void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
2104   if (!initialization_complete) {
2105     return;
2106   }
2107 
2108   const char* heapName   = get_heapName(heap);
2109   get_HeapStatGlobals(out, heapName);
2110 
2111   if ((StatArray == NULL) || (alloc_granules == 0)) {
2112     return;
2113   }
2114   STRINGSTREAM_DECL(ast, out)
2115 
2116   unsigned int granules_per_line   = 128;
2117   char*        low_bound           = heap->low_boundary();
2118   CodeBlob*    last_blob           = NULL;
2119   bool         name_in_addr_range  = true;
2120   bool         have_CodeCache_lock = CodeCache_lock->owned_by_self();
2121 
2122   //---<  print at least 128K per block (i.e. between headers)  >---
2123   if (granules_per_line*granule_size < 128*K) {
2124     granules_per_line = (unsigned int)((128*K)/granule_size);
2125   }
2126 
2127   printBox(ast, '=', "M E T H O D   N A M E S   for ", heapName);
2128   ast->print_cr("  Method names are dynamically retrieved from the code cache at print time.\n"
2129                 "  Due to the living nature of the code heap and because the CodeCache_lock\n"
2130                 "  is not continuously held, the displayed name might be wrong or no name\n"
2131                 "  might be found at all. The likelihood for that to happen increases\n"
2132                 "  over time passed between aggregtion and print steps.\n");
2133   STRINGSTREAM_FLUSH_LOCKED("")
2134 
2135   for (unsigned int ix = 0; ix < alloc_granules; ix++) {
2136     //---<  print a new blob on a new line  >---
2137     if (ix%granules_per_line == 0) {
2138       if (!name_in_addr_range) {
2139         ast->print_cr("No methods, blobs, or stubs found in this address range");
2140       }
2141       name_in_addr_range = false;
2142 
2143       size_t end_ix = (ix+granules_per_line <= alloc_granules) ? ix+granules_per_line : alloc_granules;
2144       ast->cr();
2145       ast->print_cr("--------------------------------------------------------------------");
2146       ast->print_cr("Address range [" INTPTR_FORMAT "," INTPTR_FORMAT "), " SIZE_FORMAT "k", p2i(low_bound+ix*granule_size), p2i(low_bound + end_ix*granule_size), (end_ix - ix)*granule_size/(size_t)K);
2147       ast->print_cr("--------------------------------------------------------------------");
2148       STRINGSTREAM_FLUSH_LOCKED("")
2149     }
2150     // Only check granule if it contains at least one blob.
2151     unsigned int nBlobs  = StatArray[ix].t1_count   + StatArray[ix].t2_count + StatArray[ix].tx_count +
2152                            StatArray[ix].stub_count + StatArray[ix].dead_count;
2153     if (nBlobs > 0 ) {
2154     for (unsigned int is = 0; is < granule_size; is+=(unsigned int)seg_size) {
2155       // heap->find_start() is safe. Only works on _segmap.
2156       // Returns NULL or void*. Returned CodeBlob may be uninitialized.
2157       char*     this_seg  = low_bound + ix*granule_size + is;
2158       CodeBlob* this_blob = (CodeBlob*)(heap->find_start(this_seg));
2159       bool   blob_is_safe = blob_access_is_safe(this_blob, NULL);


2160       // blob could have been flushed, freed, and merged.
2161       // this_blob < last_blob is an indicator for that.
2162       if (blob_is_safe && (this_blob > last_blob)) {
2163         last_blob          = this_blob;
2164 
2165         //---<  get type and name  >---
2166         blobType       cbType = noType;
2167         if (segment_granules) {
2168           cbType = (blobType)StatArray[ix].type;
2169         } else {
2170           //---<  access these fields only if we own the CodeCache_lock  >---
2171           if (have_CodeCache_lock) {
2172             cbType = get_cbType(this_blob);
2173           }
2174         }
2175 
2176         //---<  access these fields only if we own the CodeCache_lock  >---
2177         const char* blob_name = "<unavailable>";
2178         nmethod*           nm = NULL;
2179         if (have_CodeCache_lock) {
2180           blob_name = this_blob->name();
2181           nm        = this_blob->as_nmethod_or_null();
2182           // this_blob->name() could return NULL if no name was given to CTOR. Inlined, maybe invisible on stack

2183           if ((blob_name == NULL) || !os::is_readable_pointer(blob_name)) {
2184             blob_name = "<unavailable>";
2185           }
2186         }
2187 
2188         //---<  print table header for new print range  >---
2189         if (!name_in_addr_range) {
2190           name_in_addr_range = true;
2191           ast->fill_to(51);
2192           ast->print("%9s", "compiler");
2193           ast->fill_to(61);
2194           ast->print_cr("%6s", "method");
2195           ast->print_cr("%18s %13s %17s %9s  %5s %18s  %s", "Addr(module)      ", "offset", "size", " type lvl", " temp", "blobType          ", "Name");
2196           STRINGSTREAM_FLUSH_LOCKED("")
2197         }
2198 
2199         //---<  print line prefix (address and offset from CodeHeap start)  >---
2200         ast->print(INTPTR_FORMAT, p2i(this_blob));
2201         ast->fill_to(19);
2202         ast->print("(+" PTR32_FORMAT ")", (unsigned int)((char*)this_blob-low_bound));
2203         ast->fill_to(33);
2204 
2205         // access nmethod and Method fields only if we own the CodeCache_lock.
2206         // This fact is implicitly transported via nm != NULL.
2207         if (CompiledMethod::nmethod_access_is_safe(nm)) {
2208           Method* method = nm->method();
2209           ResourceMark rm;
2210           //---<  collect all data to locals as quickly as possible  >---
2211           unsigned int total_size = nm->total_size();
2212           int          hotness    = nm->hotness_counter();
2213           bool         get_name   = (cbType == nMethod_inuse) || (cbType == nMethod_notused);
2214           //---<  nMethod size in hex  >---
2215           ast->print(PTR32_FORMAT, total_size);
2216           ast->print("(" SIZE_FORMAT_W(4) "K)", total_size/K);
2217           //---<  compiler information  >---
2218           ast->fill_to(51);
2219           ast->print("%5s %3d", compTypeName[StatArray[ix].compiler], StatArray[ix].level);
2220           //---<  method temperature  >---
2221           ast->fill_to(62);
2222           ast->print("%5d", hotness);
2223           //---<  name and signature  >---
2224           ast->fill_to(62+6);
2225           ast->print("%s", blobTypeName[cbType]);
2226           ast->fill_to(82+6);
2227           if (cbType == nMethod_dead) {
2228             ast->print("%14s", " zombie method");
2229           }
2230 
2231           if (get_name) {
2232             Symbol* methName  = method->name();
2233             const char*   methNameS = (methName == NULL) ? NULL : methName->as_C_string();
2234             methNameS = (methNameS == NULL) ? "<method name unavailable>" : methNameS;
2235             Symbol* methSig   = method->signature();
2236             const char*   methSigS  = (methSig  == NULL) ? NULL : methSig->as_C_string();
2237             methSigS  = (methSigS  == NULL) ? "<method signature unavailable>" : methSigS;
2238             ast->print("%s", methNameS);
2239             ast->print("%s", methSigS);
2240           } else {
2241             ast->print("%s", blob_name);
2242           }
2243         } else if (blob_is_safe) {
2244           ast->fill_to(62+6);
2245           ast->print("%s", blobTypeName[cbType]);
2246           ast->fill_to(82+6);
2247           ast->print("%s", blob_name);
2248         } else {
2249           ast->fill_to(62+6);
2250           ast->print("<stale blob>");
2251         }
2252         STRINGSTREAM_FLUSH_LOCKED("\n")
2253       } else if (!blob_is_safe && (this_blob != last_blob) && (this_blob != NULL)) {
2254         last_blob          = this_blob;
2255         STRINGSTREAM_FLUSH_LOCKED("\n")
2256       }
2257     }
2258     } // nBlobs > 0
2259   }
2260   STRINGSTREAM_FLUSH_LOCKED("\n\n")
2261 }
2262 
2263 
2264 void CodeHeapState::printBox(outputStream* ast, const char border, const char* text1, const char* text2) {
2265   unsigned int lineLen = 1 + 2 + 2 + 1;
2266   char edge, frame;
2267 
2268   if (text1 != NULL) {
2269     lineLen += (unsigned int)strlen(text1); // text1 is much shorter than MAX_INT chars.
2270   }
2271   if (text2 != NULL) {
2272     lineLen += (unsigned int)strlen(text2); // text2 is much shorter than MAX_INT chars.
2273   }


2400       ast->reset();
2401     }
2402 
2403     ast->print(INTPTR_FORMAT, p2i(low_bound + ix*granule_size));
2404     ast->fill_to(19);
2405     ast->print("(+" PTR32_FORMAT "): |", (unsigned int)(ix*granule_size));
2406   }
2407 }
2408 
2409 CodeHeapState::blobType CodeHeapState::get_cbType(CodeBlob* cb) {
2410   if ((cb != NULL) && os::is_readable_pointer(cb)) {
2411     if (cb->is_runtime_stub())                return runtimeStub;
2412     if (cb->is_deoptimization_stub())         return deoptimizationStub;
2413     if (cb->is_uncommon_trap_stub())          return uncommonTrapStub;
2414     if (cb->is_exception_stub())              return exceptionStub;
2415     if (cb->is_safepoint_stub())              return safepointStub;
2416     if (cb->is_adapter_blob())                return adapterBlob;
2417     if (cb->is_method_handles_adapter_blob()) return mh_adapterBlob;
2418     if (cb->is_buffer_blob())                 return bufferBlob;
2419 
2420     //---<  access these fields only if we own the CodeCache_lock  >---
2421     // Should be ensured by caller. aggregate() amd print_names() do that.
2422     if (CodeCache_lock->owned_by_self()) {
2423       nmethod*  nm = cb->as_nmethod_or_null();
2424       if (nm != NULL) { // no is_readable check required, nm = (nmethod*)cb.
2425         if (nm->is_not_installed()) return nMethod_inconstruction;
2426         if (nm->is_zombie())        return nMethod_dead;
2427         if (nm->is_unloaded())      return nMethod_unloaded;
2428         if (nm->is_in_use())        return nMethod_inuse;
2429         if (nm->is_alive() && !(nm->is_not_entrant()))   return nMethod_notused;
2430         if (nm->is_alive())         return nMethod_alive;
2431         return nMethod_dead;
2432       }
2433     }
2434   }
2435   return noType;
2436 }
2437 
2438 bool CodeHeapState::blob_access_is_safe(CodeBlob* this_blob, CodeBlob* prev_blob) {
2439   return (this_blob != NULL) && // a blob must have been found, obviously
2440          ((this_blob == prev_blob) || (prev_blob == NULL)) &&  // when re-checking, the same blob must have been found
2441          (this_blob->header_size() >= 0) &&
2442          (this_blob->relocation_size() >= 0) &&
2443          ((address)this_blob + this_blob->header_size() == (address)(this_blob->relocation_begin())) &&
2444          ((address)this_blob + CodeBlob::align_code_offset(this_blob->header_size() + this_blob->relocation_size()) == (address)(this_blob->content_begin())) &&
2445          os::is_readable_pointer((address)(this_blob->relocation_begin())) &&
2446          os::is_readable_pointer(this_blob->content_begin());
2447 }
< prev index next >