@@ -257,7 +257,7 @@ static unsigned int used_topSizeBlocks = 0;
257257
258258static struct SizeDistributionElement * SizeDistributionArray = nullptr ;
259259
260- static int latest_compilation_id = 0 ;
260+ static unsigned int latest_compilation_id = 0 ;
261261static volatile bool initialization_complete = false ;
262262
263263const char * CodeHeapState::get_heapName (CodeHeap* heap) {
@@ -591,7 +591,11 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, size_t granular
591591 // Finally, we adjust the granularity such that each granule covers at most 64k-1 segments.
592592 // This is necessary to prevent an unsigned short overflow while accumulating space information.
593593 //
594- assert (granularity > 0 , " granularity should be positive." );
594+ if (!(granularity > 0 )) {
595+ printBox (ast, ' -' , " Requested granularity must be > 0 to aggregate statistics." , nullptr );
596+ BUFFEREDSTREAM_FLUSH (" " )
597+ return ;
598+ }
595599
596600 if (granularity > size) {
597601 granularity = size;
@@ -658,7 +662,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, size_t granular
658662 prepare_SizeDistArray (out, nSizeDistElements, heapName);
659663
660664 latest_compilation_id = CompileBroker::get_compilation_id ();
661- int highest_compilation_id = 0 ;
665+ unsigned int highest_compilation_id = 0 ;
662666 size_t usedSpace = 0 ;
663667 size_t t1Space = 0 ;
664668 size_t t2Space = 0 ;
@@ -678,14 +682,14 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, size_t granular
678682 size_t hb_bytelen = ((size_t )hb_len)<<log2_seg_size;
679683 unsigned int ix_beg = (unsigned int )(((char *)h-low_bound)/granule_size);
680684 unsigned int ix_end = (unsigned int )(((char *)h-low_bound+(hb_bytelen-1 ))/granule_size);
681- int compile_id = 0 ;
685+ unsigned int compile_id = 0 ;
682686 CompLevel comp_lvl = CompLevel_none;
683687 compType cType = noComp;
684688 blobType cbType = noType;
685689
686690 // ---< some sanity checks >---
687- // Do not assert here, just check, print error message and return.
688691 // This is a diagnostic function. It is not supposed to tear down the VM.
692+ // Therefore, just print some failure message and quit processing.
689693 if ((char *)h < low_bound) {
690694 insane = true ; ast->print_cr (" Sanity check: HeapBlock @%p below low bound (%p)" , (char *)h, low_bound);
691695 }
@@ -800,9 +804,9 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, size_t granular
800804 used_topSizeBlocks++;
801805 blob_name = nullptr ; // indicate blob_name was consumed
802806 // This check roughly cuts 5000 iterations (JVM98, mixed, dbg, termination stats):
803- } else if ((used_topSizeBlocks < alloc_topSizeBlocks) && (hb_len < currMin)) {
807+ } else if ((used_topSizeBlocks < alloc_topSizeBlocks) && (hb_len <= currMin)) {
804808 // ---< all blocks in list are larger, but there is room left in array >---
805- TopSizeArray[currMin_ix].index = used_topSizeBlocks;
809+ TopSizeArray[currMin_ix].index = used_topSizeBlocks; // link currMin -> newMin
806810 TopSizeArray[used_topSizeBlocks].start = h;
807811 TopSizeArray[used_topSizeBlocks].blob_name = blob_name;
808812 TopSizeArray[used_topSizeBlocks].len = hb_len;
@@ -841,7 +845,6 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, size_t granular
841845 // That's necessary to keep the entry for the largest block at index 0.
842846 // This move might cause the current minimum to be moved to another place
843847 if (i == currMin_ix) {
844- assert (TopSizeArray[i].len == currMin, " sort error" );
845848 currMin_ix = used_topSizeBlocks;
846849 }
847850 memcpy ((void *)&TopSizeArray[used_topSizeBlocks], (void *)&TopSizeArray[i], sizeof (TopSizeBlk));
@@ -890,7 +893,7 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, size_t granular
890893 TopSizeArray[j].blob_name = blob_name;
891894 TopSizeArray[j].len = hb_len;
892895 TopSizeArray[j].index = tsbStopper; // already set!!
893- TopSizeArray[i ].nm_size = nm_size;
896+ TopSizeArray[j ].nm_size = nm_size;
894897 TopSizeArray[j].compiler = cType;
895898 TopSizeArray[j].level = comp_lvl;
896899 TopSizeArray[j].type = cbType;
@@ -1105,11 +1108,21 @@ void CodeHeapState::aggregate(outputStream* out, CodeHeap* heap, size_t granular
11051108 if (TopSizeArray[0 ].len != currMax) {
11061109 out->print_cr (" currMax(%d) differs from TopSizeArray[0].len(%d)" , currMax, TopSizeArray[0 ].len );
11071110 }
1108- for (unsigned int i = 0 ; (TopSizeArray[i].index != tsbStopper) && (j++ < alloc_topSizeBlocks); i = TopSizeArray[i].index ) {
1109- if (TopSizeArray[i].len < TopSizeArray[TopSizeArray[i].index ].len ) {
1110- out->print_cr (" sort error at index %d: %d !>= %d" , i, TopSizeArray[i].len , TopSizeArray[TopSizeArray[i].index ].len );
1111+
1112+ if (used_topSizeBlocks > 1 ) {
1113+ int this_i = 0 ;
1114+ int prev_i = tsbStopper;
1115+ int elem_i = 1 ;
1116+ while (TopSizeArray[this_i].index != tsbStopper) {
1117+ elem_i++;
1118+ prev_i = this_i;
1119+ this_i = TopSizeArray[this_i].index ;
1120+ if (TopSizeArray[this_i].len > TopSizeArray[prev_i].len ) {
1121+ out->print_cr (" TopSizeArray[%d].len(%d) <= TopSizeArray[%d].len(%d), #total = %d, #current = %d" , this_i, TopSizeArray[this_i].len , prev_i, TopSizeArray[prev_i].len , used_topSizeBlocks, elem_i);
1122+ }
11111123 }
11121124 }
1125+
11131126 if (j >= alloc_topSizeBlocks) {
11141127 out->print_cr (" Possible loop in TopSizeArray chaining!\n allocBlocks = %d, usedBlocks = %d" , alloc_topSizeBlocks, used_topSizeBlocks);
11151128 for (unsigned int i = 0 ; i < alloc_topSizeBlocks; i++) {
@@ -1259,13 +1272,7 @@ void CodeHeapState::print_usedSpace(outputStream* out, CodeHeap* heap) {
12591272 printBox (ast, ' -' , " Largest Used Blocks in " , heapName);
12601273 print_blobType_legend (ast);
12611274
1262- ast->fill_to (51 );
1263- ast->print (" %4s" , " blob" );
1264- ast->fill_to (56 );
1265- ast->print (" %9s" , " compiler" );
1266- ast->fill_to (66 );
1267- ast->print_cr (" %6s" , " method" );
1268- ast->print_cr (" %18s %13s %17s %9s %5s %s" , " Addr(module) " , " offset" , " size" , " type" , " type lvl" , " Name" );
1275+ print_MethodlistHeader (ast);
12691276 BUFFEREDSTREAM_FLUSH_LOCKED (" " )
12701277
12711278 // ---< print Top Ten Used Blocks >---
@@ -1282,19 +1289,11 @@ void CodeHeapState::print_usedSpace(outputStream* out, CodeHeap* heap) {
12821289 CodeBlob* this_blob = (CodeBlob*)(heap->find_start (heapBlock));
12831290 if (this_blob != nullptr ) {
12841291 // ---< access these fields only if we own the CodeCache_lock >---
1285- // ---< blob address >---
1286- ast->print (INTPTR_FORMAT, p2i (this_blob));
1287- ast->fill_to (19 );
1288- // ---< blob offset from CodeHeap begin >---
1289- ast->print (" (+" UINT32_FORMAT_X_0 " )" , (unsigned int )((char *)this_blob-low_bound));
1290- ast->fill_to (33 );
1292+ // ---< blob address and offset from CodeHeap begin >---
1293+ print_address_and_offset (ast, (address)this_blob, (address)low_bound);
12911294 } else {
1292- // ---< block address >---
1293- ast->print (INTPTR_FORMAT, p2i (TopSizeArray[i].start ));
1294- ast->fill_to (19 );
1295- // ---< block offset from CodeHeap begin >---
1296- ast->print (" (+" UINT32_FORMAT_X_0 " )" , (unsigned int )((char *)TopSizeArray[i].start -low_bound));
1297- ast->fill_to (33 );
1295+ // ---< block address and offset from CodeHeap begin >---
1296+ print_address_and_offset (ast, (address)TopSizeArray[i].start , (address)low_bound);
12981297 }
12991298
13001299 // ---< print size, name, and signature (for nMethods) >---
@@ -1309,7 +1308,7 @@ void CodeHeapState::print_usedSpace(outputStream* out, CodeHeap* heap) {
13091308 ast->fill_to (56 );
13101309 ast->print (" %5s %3d" , compTypeName[TopSizeArray[i].compiler ], TopSizeArray[i].level );
13111310 // ---< name and signature >---
1312- ast->fill_to (67 + 6 );
1311+ ast->fill_to (67 );
13131312 ast->print (" %s" , TopSizeArray[i].blob_name );
13141313 } else {
13151314 // ---< block size in hex >---
@@ -1318,7 +1317,7 @@ void CodeHeapState::print_usedSpace(outputStream* out, CodeHeap* heap) {
13181317 // ---< no compiler information >---
13191318 ast->fill_to (56 );
13201319 // ---< name and signature >---
1321- ast->fill_to (67 + 6 );
1320+ ast->fill_to (67 );
13221321 ast->print (" %s" , TopSizeArray[i].blob_name );
13231322 }
13241323 ast->cr ();
@@ -1977,11 +1976,11 @@ void CodeHeapState::print_age(outputStream* out, CodeHeap* heap) {
19771976 granules_per_line = 128 ;
19781977 for (unsigned int ix = 0 ; ix < alloc_granules; ix++) {
19791978 print_line_delim (out, ast, low_bound, ix, granules_per_line);
1980- int age1 = StatArray[ix].t1_age ;
1981- int age2 = StatArray[ix].t2_age ;
1982- int agex = StatArray[ix].tx_age ;
1983- int age = age1 > age2 ? age1 : age2;
1984- age = age > agex ? age : agex;
1979+ unsigned int age1 = StatArray[ix].t1_age ;
1980+ unsigned int age2 = StatArray[ix].t2_age ;
1981+ unsigned int agex = StatArray[ix].tx_age ;
1982+ unsigned int age = age1 > age2 ? age1 : age2;
1983+ age = age > agex ? age : agex;
19851984 print_age_single (ast, age);
19861985 }
19871986 ast->print (" |" );
@@ -2087,6 +2086,7 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
20872086 " is not continuously held, the displayed name might be wrong or no name\n "
20882087 " might be found at all. The likelihood for that to happen increases\n "
20892088 " over time passed between aggregation and print steps.\n " );
2089+ print_blobType_legend (ast);
20902090 BUFFEREDSTREAM_FLUSH_LOCKED (" " )
20912091
20922092 for (unsigned int ix = 0 ; ix < alloc_granules; ix++) {
@@ -2120,6 +2120,7 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
21202120 last_blob = this_blob;
21212121
21222122 // ---< get type and name >---
2123+ unsigned int blob_size = this_blob->size ();
21232124 blobType cbType = noType;
21242125 if (segment_granules) {
21252126 cbType = (blobType)StatArray[ix].type ;
@@ -2145,19 +2146,12 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
21452146 // ---< print table header for new print range >---
21462147 if (!name_in_addr_range) {
21472148 name_in_addr_range = true ;
2148- ast->fill_to (51 );
2149- ast->print (" %9s" , " compiler" );
2150- ast->fill_to (61 );
2151- ast->print_cr (" %6s" , " method" );
2152- ast->print_cr (" %18s %13s %17s %9s %18s %s" , " Addr(module) " , " offset" , " size" , " type lvl" , " blobType " , " Name" );
2149+ print_MethodlistHeader (ast);
21532150 BUFFEREDSTREAM_FLUSH_AUTO (" " )
21542151 }
21552152
21562153 // ---< print line prefix (address and offset from CodeHeap start) >---
2157- ast->print (INTPTR_FORMAT, p2i (this_blob));
2158- ast->fill_to (19 );
2159- ast->print (" (+" UINT32_FORMAT_X_0 " )" , (unsigned int )((char *)this_blob-low_bound));
2160- ast->fill_to (33 );
2154+ print_address_and_offset (ast, (address)this_blob, (address)low_bound);
21612155
21622156 // access nmethod and Method fields only if we own the CodeCache_lock.
21632157 // This fact is implicitly transported via nm != nullptr.
@@ -2167,27 +2161,48 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
21672161 // ---< collect all data to locals as quickly as possible >---
21682162 unsigned int total_size = nm->total_size ();
21692163 bool get_name = (cbType == nMethod_inuse) || (cbType == nMethod_notused);
2164+ #if 1
2165+ CompLevel level = (CompLevel)(nm->comp_level ());
2166+ u2 compiler = 0 ;
2167+ if (nm->is_compiled_by_c1 ()) {
2168+ compiler = c1;
2169+ }
2170+ if (nm->is_compiled_by_c2 ()) {
2171+ compiler = c2;
2172+ }
2173+ if (nm->is_compiled_by_jvmci ()) {
2174+ compiler = jvmci;
2175+ }
2176+ #else
2177+ u2 compiler = StatArray[ix].compiler;
2178+ CompLevel level = StatArray[ix].level
2179+ #endif
21702180 // ---< nMethod size in hex >---
21712181 ast->print (UINT32_FORMAT_X_0, total_size);
21722182 ast->print (" (%4zuK)" , total_size/K);
2173- // ---< compiler information >---
2183+ // ---< blob type >---
21742184 ast->fill_to (51 );
2175- ast->print (" %5s %3d" , compTypeName[StatArray[ix].compiler ], StatArray[ix].level );
2185+ ast->print (" %c" , blobTypeChar[cbType]);
2186+ // ---< compiler information >---
2187+ ast->fill_to (56 );
2188+ ast->print (" %5s %3d" , compTypeName[compiler], level);
21762189 // ---< name and signature >---
2177- ast->fill_to (62 );
2178- ast->print (" %s" , blobTypeName[cbType]);
2179- ast->fill_to (82 );
2190+ ast->fill_to (67 );
21802191
21812192 if (get_name) {
21822193 Symbol* methName = method->name ();
2194+ const char * classNameS;
21832195 const char * methNameS = (methName == nullptr ) ? nullptr : methName->as_C_string ();
21842196 methNameS = (methNameS == nullptr ) ? " <method name unavailable>" : methNameS;
21852197 Symbol* methSig = method->signature ();
21862198 const char * methSigS = (methSig == nullptr ) ? nullptr : methSig->as_C_string ();
21872199 methSigS = (methSigS == nullptr ) ? " <method signature unavailable>" : methSigS;
21882200 Klass* klass = method->method_holder ();
2189- assert (klass != nullptr , " No method holder" );
2190- const char * classNameS = (klass->name () == nullptr ) ? " <class name unavailable>" : klass->external_name ();
2201+ if (klass != nullptr ) {
2202+ classNameS = (klass->name () == nullptr ) ? " <class name unavailable>" : klass->external_name ();
2203+ } else {
2204+ classNameS = " <no method holder>" ;
2205+ }
21912206
21922207 ast->print (" %s." , classNameS);
21932208 ast->print (" %s" , methNameS);
@@ -2202,12 +2217,16 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
22022217 ast->print (" %s" , blob_name);
22032218 }
22042219 } else if (blob_is_safe) {
2205- ast->fill_to (62 );
2206- ast->print (" %s" , blobTypeName[cbType]);
2207- ast->fill_to (82 );
2220+ // ---< blob size in hex >---
2221+ ast->print (UINT32_FORMAT_X_0, blob_size);
2222+ ast->print (" (" SIZE_FORMAT_W (4 ) " K)" , blob_size/K);
2223+ ast->fill_to (51 );
2224+ // ---< blob type >---
2225+ ast->print (" %c" , blobTypeChar[cbType]);
2226+ ast->fill_to (67 );
22082227 ast->print (" %s" , blob_name);
22092228 } else {
2210- ast->fill_to (62 );
2229+ ast->fill_to (67 );
22112230 ast->print (" <stale blob>" );
22122231 }
22132232 ast->cr ();
@@ -2222,6 +2241,31 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
22222241}
22232242
22242243
2244+ void CodeHeapState::print_MethodlistHeader (outputStream* ast) {
2245+
2246+ // Header layout:
2247+ // 1 20 34 52 57 67
2248+ // | | | | | |
2249+ // blob compiler method
2250+ // Addr(module) offset size type type lvl Name
2251+ // 0x000000010a87c008 (+0x00000008) 0x00000098( 0K) N none 0 java.lang.Byte.toUnsignedInt(B)I
2252+
2253+ ast->fill_to (51 );
2254+ ast->print (" %4s" , " blob" );
2255+ ast->fill_to (56 );
2256+ ast->print (" %9s" , " compiler" );
2257+ ast->fill_to (67 );
2258+ ast->print_cr (" %6s" , " method" );
2259+ ast->print_cr (" %18s %13s %17s %4s %9s %s" , " Addr(module) " , " offset" , " size" , " type" , " type lvl" , " Name" );
2260+ }
2261+
2262+ void CodeHeapState::print_address_and_offset (outputStream* ast, address here, address base) {
2263+ ast->print (INTPTR_FORMAT, p2i (here));
2264+ ast->fill_to (19 );
2265+ ast->print (" (+" UINT32_FORMAT_X_0 " )" , (unsigned int )(here - base));
2266+ ast->fill_to (33 );
2267+ }
2268+
22252269void CodeHeapState::printBox (outputStream* ast, const char border, const char * text1, const char * text2) {
22262270 unsigned int lineLen = 1 + 2 + 2 + 1 ;
22272271 char edge, frame;
@@ -2273,7 +2317,6 @@ void CodeHeapState::print_blobType_legend(outputStream* out) {
22732317}
22742318
22752319void CodeHeapState::print_space_legend (outputStream* out) {
2276- int range_beg = latest_compilation_id;
22772320 out->cr ();
22782321 printBox (out, ' -' , " Space ranges, based on granule occupancy" , nullptr );
22792322 out->print_cr (" - 0%% == occupancy" );
@@ -2287,8 +2330,8 @@ void CodeHeapState::print_space_legend(outputStream* out) {
22872330
22882331void CodeHeapState::print_age_legend (outputStream* out) {
22892332 unsigned int indicator = 0 ;
2290- int age_range = 256 ;
2291- int range_beg = latest_compilation_id;
2333+ unsigned int age_range = 256 ;
2334+ unsigned int range_beg = latest_compilation_id;
22922335 out->cr ();
22932336 printBox (out, ' -' , " Age ranges, based on compilation id" , nullptr );
22942337 while (age_range > 0 ) {
@@ -2317,9 +2360,9 @@ void CodeHeapState::print_space_single(outputStream* out, unsigned short space)
23172360 out->print (" %c" , fraction);
23182361}
23192362
2320- void CodeHeapState::print_age_single (outputStream* out, int age) {
2363+ void CodeHeapState::print_age_single (outputStream* out, unsigned int age) {
23212364 unsigned int indicator = 0 ;
2322- int age_range = 256 ;
2365+ unsigned int age_range = 256 ;
23232366 if (age > 0 ) {
23242367 while ((age_range > 0 ) && (latest_compilation_id-age > latest_compilation_id/age_range)) {
23252368 age_range /= 2 ;
@@ -2332,21 +2375,20 @@ void CodeHeapState::print_age_single(outputStream* out, int age) {
23322375}
23332376
23342377void CodeHeapState::print_line_delim (outputStream* out, outputStream* ast, char * low_bound, unsigned int ix, unsigned int gpl) {
2378+ // Note: out and ast MUST designate the SAME stream!
23352379 if (ix % gpl == 0 ) {
23362380 if (ix > 0 ) {
23372381 ast->print (" |" );
23382382 }
23392383 ast->cr ();
2340- assert (out == ast, " must use the same stream!" );
23412384
2342- ast->print (INTPTR_FORMAT, p2i (low_bound + ix*granule_size));
2343- ast->fill_to (19 );
2344- ast->print (" (+" UINT32_FORMAT_X_0 " ): |" , (unsigned int )(ix*granule_size));
2385+ print_address_and_offset (ast, (address)(low_bound + ix*granule_size), (address)low_bound);
2386+ ast->print (" |" );
23452387 }
23462388}
23472389
23482390void CodeHeapState::print_line_delim (outputStream* out, bufferedStream* ast, char * low_bound, unsigned int ix, unsigned int gpl) {
2349- assert ( out != ast, " must not use the same stream!" );
2391+ // Note: out and ast MUST NOT designate the SAME stream!
23502392 if (ix % gpl == 0 ) {
23512393 if (ix > 0 ) {
23522394 ast->print (" |" );
@@ -2363,9 +2405,8 @@ void CodeHeapState::print_line_delim(outputStream* out, bufferedStream* ast, cha
23632405 ast->reset ();
23642406 }
23652407
2366- ast->print (INTPTR_FORMAT, p2i (low_bound + ix*granule_size));
2367- ast->fill_to (19 );
2368- ast->print (" (+" UINT32_FORMAT_X_0 " ): |" , (unsigned int )(ix*granule_size));
2408+ print_address_and_offset (ast, (address)(low_bound + ix*granule_size), (address)low_bound);
2409+ ast->print (" |" );
23692410 }
23702411}
23712412
0 commit comments