2089 }
2090 name_in_addr_range = false;
2091
2092 size_t end_ix = (ix+granules_per_line <= alloc_granules) ? ix+granules_per_line : alloc_granules;
2093 ast->cr();
2094 ast->print_cr("--------------------------------------------------------------------");
2095 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);
2096 ast->print_cr("--------------------------------------------------------------------");
2097 STRINGSTREAM_FLUSH_LOCKED("")
2098 }
2099 // Only check granule if it contains at least one blob.
2100 unsigned int nBlobs = StatArray[ix].t1_count + StatArray[ix].t2_count + StatArray[ix].tx_count +
2101 StatArray[ix].stub_count + StatArray[ix].dead_count;
2102 if (nBlobs > 0 ) {
2103 for (unsigned int is = 0; is < granule_size; is+=(unsigned int)seg_size) {
2104 // heap->find_start() is safe. Only working with _segmap. Returns NULL or void*. Returned CodeBlob may be uninitialized.
2105 CodeBlob* this_blob = (CodeBlob *)(heap->find_start(low_bound+ix*granule_size+is));
2106 bool blob_initialized = (this_blob != NULL) && (this_blob->header_size() >= 0) && (this_blob->relocation_size() >= 0) &&
2107 ((address)this_blob + this_blob->header_size() == (address)(this_blob->relocation_begin())) &&
2108 ((address)this_blob + CodeBlob::align_code_offset(this_blob->header_size() + this_blob->relocation_size()) == (address)(this_blob->content_begin())) &&
2109 is_readable_pointer((address)(this_blob->relocation_begin())) &&
2110 is_readable_pointer(this_blob->content_begin());
2111 // blob could have been flushed, freed, and merged.
2112 // this_blob < last_blob is an indicator for that.
2113 if (blob_initialized && (this_blob > last_blob)) {
2114 last_blob = this_blob;
2115
2116 //---< get type and name >---
2117 blobType cbType = noType;
2118 if (segment_granules) {
2119 cbType = (blobType)StatArray[ix].type;
2120 } else {
2121 cbType = get_cbType(this_blob);
2122 }
2123 // this_blob->name() could return NULL if no name was given to CTOR. Inlined, maybe invisible on stack
2124 const char* blob_name = this_blob->name();
2125 if ((blob_name == NULL) || !is_readable_pointer(blob_name)) {
2126 blob_name = "<unavailable>";
2127 }
2128
2129 //---< print table header for new print range >---
2130 if (!name_in_addr_range) {
2131 name_in_addr_range = true;
2132 ast->fill_to(51);
2133 ast->print("%9s", "compiler");
2134 ast->fill_to(61);
2135 ast->print_cr("%6s", "method");
2136 ast->print_cr("%18s %13s %17s %9s %5s %18s %s", "Addr(module) ", "offset", "size", " type lvl", " temp", "blobType ", "Name");
2137 STRINGSTREAM_FLUSH_LOCKED("")
2138 }
2139
2140 //---< print line prefix (address and offset from CodeHeap start) >---
2141 ast->print(INTPTR_FORMAT, p2i(this_blob));
2142 ast->fill_to(19);
2143 ast->print("(+" PTR32_FORMAT ")", (unsigned int)((char*)this_blob-low_bound));
2144 ast->fill_to(33);
2145
2146 // this_blob->as_nmethod_or_null() is safe. Inlined, maybe invisible on stack.
2147 nmethod* nm = this_blob->as_nmethod_or_null();
2148 Method* method = (nm == NULL) ? NULL : nm->method(); // may be uninitialized, i.e. != NULL, but invalid
2149 if ((nm != NULL) && (method != NULL) && (cbType != nMethod_dead) &&
2150 is_readable_pointer(method) && is_readable_pointer(method->constants())) {
2151 ResourceMark rm;
2152 //---< collect all data to locals as quickly as possible >---
2153 unsigned int total_size = nm->total_size();
2154 int hotness = nm->hotness_counter();
2155 bool get_name = (cbType == nMethod_inuse) || (cbType == nMethod_notused);
2156 //---< nMethod size in hex >---
2157 ast->print(PTR32_FORMAT, total_size);
2158 ast->print("(" SIZE_FORMAT_W(4) "K)", total_size/K);
2159 //---< compiler information >---
2160 ast->fill_to(51);
2161 ast->print("%5s %3d", compTypeName[StatArray[ix].compiler], StatArray[ix].level);
2162 //---< method temperature >---
2163 ast->fill_to(62);
2164 ast->print("%5d", hotness);
2165 //---< name and signature >---
2166 ast->fill_to(62+6);
2167 ast->print("%s", blobTypeName[cbType]);
2168 ast->fill_to(82+6);
2169 if (cbType == nMethod_dead) {
2170 ast->print("%14s", " zombie method");
2329 assert(out != ast, "must not use the same stream!");
2330 if (ix % gpl == 0) {
2331 if (ix > 0) {
2332 ast->print("|");
2333 }
2334 ast->cr();
2335
2336 { // can't use STRINGSTREAM_FLUSH_LOCKED("") here.
2337 ttyLocker ttyl;
2338 out->print("%s", ast->as_string());
2339 ast->reset();
2340 }
2341
2342 ast->print(INTPTR_FORMAT, p2i(low_bound + ix*granule_size));
2343 ast->fill_to(19);
2344 ast->print("(+" PTR32_FORMAT "): |", (unsigned int)(ix*granule_size));
2345 }
2346 }
2347
2348 CodeHeapState::blobType CodeHeapState::get_cbType(CodeBlob* cb) {
2349 if ((cb != NULL) && is_readable_pointer(cb)) {
2350 if (cb->is_runtime_stub()) return runtimeStub;
2351 if (cb->is_deoptimization_stub()) return deoptimizationStub;
2352 if (cb->is_uncommon_trap_stub()) return uncommonTrapStub;
2353 if (cb->is_exception_stub()) return exceptionStub;
2354 if (cb->is_safepoint_stub()) return safepointStub;
2355 if (cb->is_adapter_blob()) return adapterBlob;
2356 if (cb->is_method_handles_adapter_blob()) return mh_adapterBlob;
2357 if (cb->is_buffer_blob()) return bufferBlob;
2358
2359 nmethod* nm = cb->as_nmethod_or_null();
2360 if (nm != NULL) { // no is_readable check required, nm = (nmethod*)cb.
2361 if (nm->is_zombie()) return nMethod_dead;
2362 if (nm->is_unloaded()) return nMethod_unloaded;
2363 if (nm->is_alive() && !(nm->is_not_entrant())) return nMethod_notused;
2364 if (nm->is_alive()) return nMethod_alive;
2365 if (nm->is_in_use()) return nMethod_inuse;
2366 return nMethod_dead;
2367 }
2368 }
2369 return noType;
2370 }
2371
2372 // Check if pointer can be read from (4-byte read access).
2373 // Helps to prove validity of a not-NULL pointer.
2374 // Returns true in very early stages of VM life when stub is not yet generated.
2375 #define SAFEFETCH_DEFAULT true
2376 bool CodeHeapState::is_readable_pointer(const void* p) {
2377 if (!CanUseSafeFetch32()) {
2378 return SAFEFETCH_DEFAULT;
2379 }
2380 int* const aligned = (int*) align_down((intptr_t)p, 4);
2381 int cafebabe = 0xcafebabe; // tester value 1
2382 int deadbeef = 0xdeadbeef; // tester value 2
2383 return (SafeFetch32(aligned, cafebabe) != cafebabe) || (SafeFetch32(aligned, deadbeef) != deadbeef);
2384 }
|
2089 }
2090 name_in_addr_range = false;
2091
2092 size_t end_ix = (ix+granules_per_line <= alloc_granules) ? ix+granules_per_line : alloc_granules;
2093 ast->cr();
2094 ast->print_cr("--------------------------------------------------------------------");
2095 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);
2096 ast->print_cr("--------------------------------------------------------------------");
2097 STRINGSTREAM_FLUSH_LOCKED("")
2098 }
2099 // Only check granule if it contains at least one blob.
2100 unsigned int nBlobs = StatArray[ix].t1_count + StatArray[ix].t2_count + StatArray[ix].tx_count +
2101 StatArray[ix].stub_count + StatArray[ix].dead_count;
2102 if (nBlobs > 0 ) {
2103 for (unsigned int is = 0; is < granule_size; is+=(unsigned int)seg_size) {
2104 // heap->find_start() is safe. Only working with _segmap. Returns NULL or void*. Returned CodeBlob may be uninitialized.
2105 CodeBlob* this_blob = (CodeBlob *)(heap->find_start(low_bound+ix*granule_size+is));
2106 bool blob_initialized = (this_blob != NULL) && (this_blob->header_size() >= 0) && (this_blob->relocation_size() >= 0) &&
2107 ((address)this_blob + this_blob->header_size() == (address)(this_blob->relocation_begin())) &&
2108 ((address)this_blob + CodeBlob::align_code_offset(this_blob->header_size() + this_blob->relocation_size()) == (address)(this_blob->content_begin())) &&
2109 os::is_readable_pointer((address)(this_blob->relocation_begin())) &&
2110 os::is_readable_pointer(this_blob->content_begin());
2111 // blob could have been flushed, freed, and merged.
2112 // this_blob < last_blob is an indicator for that.
2113 if (blob_initialized && (this_blob > last_blob)) {
2114 last_blob = this_blob;
2115
2116 //---< get type and name >---
2117 blobType cbType = noType;
2118 if (segment_granules) {
2119 cbType = (blobType)StatArray[ix].type;
2120 } else {
2121 cbType = get_cbType(this_blob);
2122 }
2123 // this_blob->name() could return NULL if no name was given to CTOR. Inlined, maybe invisible on stack
2124 const char* blob_name = this_blob->name();
2125 if ((blob_name == NULL) || !os::is_readable_pointer(blob_name)) {
2126 blob_name = "<unavailable>";
2127 }
2128
2129 //---< print table header for new print range >---
2130 if (!name_in_addr_range) {
2131 name_in_addr_range = true;
2132 ast->fill_to(51);
2133 ast->print("%9s", "compiler");
2134 ast->fill_to(61);
2135 ast->print_cr("%6s", "method");
2136 ast->print_cr("%18s %13s %17s %9s %5s %18s %s", "Addr(module) ", "offset", "size", " type lvl", " temp", "blobType ", "Name");
2137 STRINGSTREAM_FLUSH_LOCKED("")
2138 }
2139
2140 //---< print line prefix (address and offset from CodeHeap start) >---
2141 ast->print(INTPTR_FORMAT, p2i(this_blob));
2142 ast->fill_to(19);
2143 ast->print("(+" PTR32_FORMAT ")", (unsigned int)((char*)this_blob-low_bound));
2144 ast->fill_to(33);
2145
2146 // this_blob->as_nmethod_or_null() is safe. Inlined, maybe invisible on stack.
2147 nmethod* nm = this_blob->as_nmethod_or_null();
2148 Method* method = (nm == NULL) ? NULL : nm->method(); // may be uninitialized, i.e. != NULL, but invalid
2149 if ((nm != NULL) && (method != NULL) && (cbType != nMethod_dead) &&
2150 os::is_readable_pointer(method) && os::is_readable_pointer(method->constants())) {
2151 ResourceMark rm;
2152 //---< collect all data to locals as quickly as possible >---
2153 unsigned int total_size = nm->total_size();
2154 int hotness = nm->hotness_counter();
2155 bool get_name = (cbType == nMethod_inuse) || (cbType == nMethod_notused);
2156 //---< nMethod size in hex >---
2157 ast->print(PTR32_FORMAT, total_size);
2158 ast->print("(" SIZE_FORMAT_W(4) "K)", total_size/K);
2159 //---< compiler information >---
2160 ast->fill_to(51);
2161 ast->print("%5s %3d", compTypeName[StatArray[ix].compiler], StatArray[ix].level);
2162 //---< method temperature >---
2163 ast->fill_to(62);
2164 ast->print("%5d", hotness);
2165 //---< name and signature >---
2166 ast->fill_to(62+6);
2167 ast->print("%s", blobTypeName[cbType]);
2168 ast->fill_to(82+6);
2169 if (cbType == nMethod_dead) {
2170 ast->print("%14s", " zombie method");
2329 assert(out != ast, "must not use the same stream!");
2330 if (ix % gpl == 0) {
2331 if (ix > 0) {
2332 ast->print("|");
2333 }
2334 ast->cr();
2335
2336 { // can't use STRINGSTREAM_FLUSH_LOCKED("") here.
2337 ttyLocker ttyl;
2338 out->print("%s", ast->as_string());
2339 ast->reset();
2340 }
2341
2342 ast->print(INTPTR_FORMAT, p2i(low_bound + ix*granule_size));
2343 ast->fill_to(19);
2344 ast->print("(+" PTR32_FORMAT "): |", (unsigned int)(ix*granule_size));
2345 }
2346 }
2347
2348 CodeHeapState::blobType CodeHeapState::get_cbType(CodeBlob* cb) {
2349 if ((cb != NULL) && os::is_readable_pointer(cb)) {
2350 if (cb->is_runtime_stub()) return runtimeStub;
2351 if (cb->is_deoptimization_stub()) return deoptimizationStub;
2352 if (cb->is_uncommon_trap_stub()) return uncommonTrapStub;
2353 if (cb->is_exception_stub()) return exceptionStub;
2354 if (cb->is_safepoint_stub()) return safepointStub;
2355 if (cb->is_adapter_blob()) return adapterBlob;
2356 if (cb->is_method_handles_adapter_blob()) return mh_adapterBlob;
2357 if (cb->is_buffer_blob()) return bufferBlob;
2358
2359 nmethod* nm = cb->as_nmethod_or_null();
2360 if (nm != NULL) { // no is_readable check required, nm = (nmethod*)cb.
2361 if (nm->is_zombie()) return nMethod_dead;
2362 if (nm->is_unloaded()) return nMethod_unloaded;
2363 if (nm->is_alive() && !(nm->is_not_entrant())) return nMethod_notused;
2364 if (nm->is_alive()) return nMethod_alive;
2365 if (nm->is_in_use()) return nMethod_inuse;
2366 return nMethod_dead;
2367 }
2368 }
2369 return noType;
2370 }
|