1 /* 2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 #include "precompiled.hpp" 25 #include "classfile/systemDictionary.hpp" 26 #include "runtime/os.hpp" 27 #include "services/memReporter.hpp" 28 #include "services/memPtrArray.hpp" 29 #include "services/memTracker.hpp" 30 31 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC 32 33 const char* BaselineOutputer::memory_unit(size_t scale) { 34 switch(scale) { 35 case K: return "KB"; 36 case M: return "MB"; 37 case G: return "GB"; 38 } 39 ShouldNotReachHere(); 40 return NULL; 41 } 42 43 44 void BaselineReporter::report_baseline(const MemBaseline& baseline, bool summary_only) { 45 assert(MemTracker::is_on(), "Native memory tracking is off"); 46 _outputer.start(scale()); 47 _outputer.total_usage( 48 amount_in_current_scale(baseline.total_malloc_amount() + baseline.total_reserved_amount()), 49 amount_in_current_scale(baseline.total_malloc_amount() + baseline.total_committed_amount())); 50 51 _outputer.num_of_classes(baseline.number_of_classes()); 52 _outputer.num_of_threads(baseline.number_of_threads()); 53 54 report_summaries(baseline); 55 if (!summary_only && MemTracker::track_callsite()) { 56 report_virtual_memory_map(baseline); 57 report_callsites(baseline); 58 } 59 _outputer.done(); 60 } 61 62 void BaselineReporter::report_summaries(const MemBaseline& baseline) { 63 _outputer.start_category_summary(); 64 MEMFLAGS type; 65 66 for (int index = 0; index < NUMBER_OF_MEMORY_TYPE; index ++) { 67 type = MemBaseline::MemType2NameMap[index]._flag; 68 _outputer.category_summary(type, 69 amount_in_current_scale(baseline.reserved_amount(type)), 70 amount_in_current_scale(baseline.committed_amount(type)), 71 amount_in_current_scale(baseline.malloc_amount(type)), 72 baseline.malloc_count(type), 73 amount_in_current_scale(baseline.arena_amount(type)), 74 baseline.arena_count(type)); 75 } 76 77 _outputer.done_category_summary(); 78 } 79 80 void BaselineReporter::report_virtual_memory_map(const MemBaseline& baseline) { 81 _outputer.start_virtual_memory_map(); 82 MemBaseline* pBL = const_cast<MemBaseline*>(&baseline); 83 MemPointerArrayIteratorImpl itr = MemPointerArrayIteratorImpl(pBL->_vm_map); 84 VMMemRegionEx* rgn = (VMMemRegionEx*)itr.current(); 85 while (rgn != NULL) { 86 if (rgn->is_reserved_region()) { 87 _outputer.reserved_memory_region(FLAGS_TO_MEMORY_TYPE(rgn->flags()), 88 rgn->base(), rgn->base() + rgn->size(), amount_in_current_scale(rgn->size()), rgn->pc()); 89 } else { 90 _outputer.committed_memory_region(rgn->base(), rgn->base() + rgn->size(), 91 amount_in_current_scale(rgn->size()), rgn->pc()); 92 } 93 rgn = (VMMemRegionEx*)itr.next(); 94 } 95 96 _outputer.done_virtual_memory_map(); 97 } 98 99 void BaselineReporter::report_callsites(const MemBaseline& baseline) { 100 _outputer.start_callsite(); 101 MemBaseline* pBL = const_cast<MemBaseline*>(&baseline); 102 103 pBL->_malloc_cs->sort((FN_SORT)MemBaseline::bl_malloc_sort_by_size); 104 pBL->_vm_cs->sort((FN_SORT)MemBaseline::bl_vm_sort_by_size); 105 106 // walk malloc callsites 107 MemPointerArrayIteratorImpl malloc_itr(pBL->_malloc_cs); 108 MallocCallsitePointer* malloc_callsite = 109 (MallocCallsitePointer*)malloc_itr.current(); 110 while (malloc_callsite != NULL) { 111 _outputer.malloc_callsite(malloc_callsite->addr(), 112 amount_in_current_scale(malloc_callsite->amount()), malloc_callsite->count()); 113 malloc_callsite = (MallocCallsitePointer*)malloc_itr.next(); 114 } 115 116 // walk virtual memory callsite 117 MemPointerArrayIteratorImpl vm_itr(pBL->_vm_cs); 118 VMCallsitePointer* vm_callsite = (VMCallsitePointer*)vm_itr.current(); 119 while (vm_callsite != NULL) { 120 _outputer.virtual_memory_callsite(vm_callsite->addr(), 121 amount_in_current_scale(vm_callsite->reserved_amount()), 122 amount_in_current_scale(vm_callsite->committed_amount())); 123 vm_callsite = (VMCallsitePointer*)vm_itr.next(); 124 } 125 pBL->_malloc_cs->sort((FN_SORT)MemBaseline::bl_malloc_sort_by_pc); 126 pBL->_vm_cs->sort((FN_SORT)MemBaseline::bl_vm_sort_by_pc); 127 _outputer.done_callsite(); 128 } 129 130 void BaselineReporter::diff_baselines(const MemBaseline& cur, const MemBaseline& prev, 131 bool summary_only) { 132 assert(MemTracker::is_on(), "Native memory tracking is off"); 133 _outputer.start(scale()); 134 size_t total_reserved = cur.total_malloc_amount() + cur.total_reserved_amount(); 135 size_t total_committed = cur.total_malloc_amount() + cur.total_committed_amount(); 136 137 _outputer.diff_total_usage( 138 amount_in_current_scale(total_reserved), amount_in_current_scale(total_committed), 139 diff_in_current_scale(total_reserved, (prev.total_malloc_amount() + prev.total_reserved_amount())), 140 diff_in_current_scale(total_committed, (prev.total_committed_amount() + prev.total_malloc_amount()))); 141 142 _outputer.diff_num_of_classes(cur.number_of_classes(), 143 diff(cur.number_of_classes(), prev.number_of_classes())); 144 _outputer.diff_num_of_threads(cur.number_of_threads(), 145 diff(cur.number_of_threads(), prev.number_of_threads())); 146 147 diff_summaries(cur, prev); 148 if (!summary_only && MemTracker::track_callsite()) { 149 diff_callsites(cur, prev); 150 } 151 _outputer.done(); 152 } 153 154 void BaselineReporter::diff_summaries(const MemBaseline& cur, const MemBaseline& prev) { 155 _outputer.start_category_summary(); 156 MEMFLAGS type; 157 158 for (int index = 0; index < NUMBER_OF_MEMORY_TYPE; index ++) { 159 type = MemBaseline::MemType2NameMap[index]._flag; 160 _outputer.diff_category_summary(type, 161 amount_in_current_scale(cur.reserved_amount(type)), 162 amount_in_current_scale(cur.committed_amount(type)), 163 amount_in_current_scale(cur.malloc_amount(type)), 164 cur.malloc_count(type), 165 amount_in_current_scale(cur.arena_amount(type)), 166 cur.arena_count(type), 167 diff_in_current_scale(cur.reserved_amount(type), prev.reserved_amount(type)), 168 diff_in_current_scale(cur.committed_amount(type), prev.committed_amount(type)), 169 diff_in_current_scale(cur.malloc_amount(type), prev.malloc_amount(type)), 170 diff(cur.malloc_count(type), prev.malloc_count(type)), 171 diff_in_current_scale(cur.arena_amount(type), prev.arena_amount(type)), 172 diff(cur.arena_count(type), prev.arena_count(type))); 173 } 174 175 _outputer.done_category_summary(); 176 } 177 178 void BaselineReporter::diff_callsites(const MemBaseline& cur, const MemBaseline& prev) { 179 _outputer.start_callsite(); 180 MemBaseline* pBL_cur = const_cast<MemBaseline*>(&cur); 181 MemBaseline* pBL_prev = const_cast<MemBaseline*>(&prev); 182 183 // walk malloc callsites 184 MemPointerArrayIteratorImpl cur_malloc_itr(pBL_cur->_malloc_cs); 185 MemPointerArrayIteratorImpl prev_malloc_itr(pBL_prev->_malloc_cs); 186 187 MallocCallsitePointer* cur_malloc_callsite = 188 (MallocCallsitePointer*)cur_malloc_itr.current(); 189 MallocCallsitePointer* prev_malloc_callsite = 190 (MallocCallsitePointer*)prev_malloc_itr.current(); 191 192 while (cur_malloc_callsite != NULL || prev_malloc_callsite != NULL) { 193 if (prev_malloc_callsite == NULL) { 194 assert(cur_malloc_callsite != NULL, "sanity check"); 195 // this is a new callsite 196 _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(), 197 amount_in_current_scale(cur_malloc_callsite->amount()), 198 cur_malloc_callsite->count(), 199 diff_in_current_scale(cur_malloc_callsite->amount(), 0), 200 diff(cur_malloc_callsite->count(), 0)); 201 cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next(); 202 } else if (cur_malloc_callsite == NULL) { 203 assert(prev_malloc_callsite != NULL, "Sanity check"); 204 // this callsite is already gone 205 _outputer.diff_malloc_callsite(prev_malloc_callsite->addr(), 206 0, 0, 207 diff_in_current_scale(0, prev_malloc_callsite->amount()), 208 diff(0, prev_malloc_callsite->count())); 209 prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next(); 210 } else { 211 assert(cur_malloc_callsite != NULL, "Sanity check"); 212 assert(prev_malloc_callsite != NULL, "Sanity check"); 213 if (cur_malloc_callsite->addr() < prev_malloc_callsite->addr()) { 214 // this is a new callsite 215 _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(), 216 amount_in_current_scale(cur_malloc_callsite->amount()), 217 cur_malloc_callsite->count(), 218 diff_in_current_scale(cur_malloc_callsite->amount(), 0), 219 diff(cur_malloc_callsite->count(), 0)); 220 cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next(); 221 } else if (cur_malloc_callsite->addr() > prev_malloc_callsite->addr()) { 222 // this callsite is already gone 223 _outputer.diff_malloc_callsite(prev_malloc_callsite->addr(), 224 0, 0, 225 diff_in_current_scale(0, prev_malloc_callsite->amount()), 226 diff(0, prev_malloc_callsite->count())); 227 prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next(); 228 } else { 229 // the same callsite 230 _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(), 231 amount_in_current_scale(cur_malloc_callsite->amount()), 232 cur_malloc_callsite->count(), 233 diff_in_current_scale(cur_malloc_callsite->amount(), prev_malloc_callsite->amount()), 234 diff(cur_malloc_callsite->count(), prev_malloc_callsite->count())); 235 cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next(); 236 prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next(); 237 } 238 } 239 } 240 241 // walk virtual memory callsite 242 MemPointerArrayIteratorImpl cur_vm_itr(pBL_cur->_vm_cs); 243 MemPointerArrayIteratorImpl prev_vm_itr(pBL_prev->_vm_cs); 244 VMCallsitePointer* cur_vm_callsite = (VMCallsitePointer*)cur_vm_itr.current(); 245 VMCallsitePointer* prev_vm_callsite = (VMCallsitePointer*)prev_vm_itr.current(); 246 while (cur_vm_callsite != NULL || prev_vm_callsite != NULL) { 247 if (prev_vm_callsite == NULL || cur_vm_callsite->addr() < prev_vm_callsite->addr()) { 248 // this is a new callsite 249 _outputer.diff_virtual_memory_callsite(cur_vm_callsite->addr(), 250 amount_in_current_scale(cur_vm_callsite->reserved_amount()), 251 amount_in_current_scale(cur_vm_callsite->committed_amount()), 252 diff_in_current_scale(cur_vm_callsite->reserved_amount(), 0), 253 diff_in_current_scale(cur_vm_callsite->committed_amount(), 0)); 254 cur_vm_callsite = (VMCallsitePointer*)cur_vm_itr.next(); 255 } else if (cur_vm_callsite == NULL || cur_vm_callsite->addr() > prev_vm_callsite->addr()) { 256 // this callsite is already gone 257 _outputer.diff_virtual_memory_callsite(prev_vm_callsite->addr(), 258 amount_in_current_scale(0), 259 amount_in_current_scale(0), 260 diff_in_current_scale(0, prev_vm_callsite->reserved_amount()), 261 diff_in_current_scale(0, prev_vm_callsite->committed_amount())); 262 prev_vm_callsite = (VMCallsitePointer*)prev_vm_itr.next(); 263 } else { // the same callsite 264 _outputer.diff_virtual_memory_callsite(cur_vm_callsite->addr(), 265 amount_in_current_scale(cur_vm_callsite->reserved_amount()), 266 amount_in_current_scale(cur_vm_callsite->committed_amount()), 267 diff_in_current_scale(cur_vm_callsite->reserved_amount(), prev_vm_callsite->reserved_amount()), 268 diff_in_current_scale(cur_vm_callsite->committed_amount(), prev_vm_callsite->committed_amount())); 269 cur_vm_callsite = (VMCallsitePointer*)cur_vm_itr.next(); 270 prev_vm_callsite = (VMCallsitePointer*)prev_vm_itr.next(); 271 } 272 } 273 274 _outputer.done_callsite(); 275 } 276 277 size_t BaselineReporter::amount_in_current_scale(size_t amt) const { 278 return (size_t)(((float)amt/(float)_scale) + 0.5); 279 } 280 281 int BaselineReporter::diff_in_current_scale(size_t value1, size_t value2) const { 282 return (int)(((float)value1 - (float)value2)/((float)_scale) + 0.5); 283 } 284 285 int BaselineReporter::diff(size_t value1, size_t value2) const { 286 return ((int)value1 - (int)value2); 287 } 288 289 void BaselineTTYOutputer::start(size_t scale, bool report_diff) { 290 _scale = scale; 291 _output->print_cr(" "); 292 _output->print_cr("Native Memory Tracking:"); 293 _output->print_cr(" "); 294 } 295 296 void BaselineTTYOutputer::done() { 297 298 } 299 300 void BaselineTTYOutputer::total_usage(size_t total_reserved, size_t total_committed) { 301 const char* unit = memory_unit(_scale); 302 _output->print_cr("Total: reserved=%d%s, committed=%d%s", 303 total_reserved, unit, total_committed, unit); 304 } 305 306 void BaselineTTYOutputer::start_category_summary() { 307 _output->print_cr(" "); 308 } 309 310 /** 311 * report a summary of memory type 312 */ 313 void BaselineTTYOutputer::category_summary(MEMFLAGS type, 314 size_t reserved_amt, size_t committed_amt, size_t malloc_amt, 315 size_t malloc_count, size_t arena_amt, size_t arena_count) { 316 317 // we report mtThreadStack under mtThread category 318 if (type == mtThreadStack) { 319 assert(malloc_amt == 0 && malloc_count == 0 && arena_amt == 0, 320 "Just check"); 321 _thread_stack_reserved = reserved_amt; 322 _thread_stack_committed = committed_amt; 323 } else { 324 const char* unit = memory_unit(_scale); 325 size_t total_reserved = (reserved_amt + malloc_amt + arena_amt); 326 size_t total_committed = (committed_amt + malloc_amt + arena_amt); 327 if (type == mtThread) { 328 total_reserved += _thread_stack_reserved; 329 total_committed += _thread_stack_committed; 330 } 331 332 if (total_reserved > 0) { 333 _output->print_cr("-%26s (reserved=%d%s, committed=%d%s)", 334 MemBaseline::type2name(type), total_reserved, unit, 335 total_committed, unit); 336 337 if (type == mtClass) { 338 _output->print_cr("%27s (classes #%d)", " ", _num_of_classes); 339 } else if (type == mtThread) { 340 _output->print_cr("%27s (thread #%d)", " ", _num_of_threads); 341 _output->print_cr("%27s (stack: reserved=%d%s, committed=%d%s)", " ", 342 _thread_stack_reserved, unit, _thread_stack_committed, unit); 343 } 344 345 if (malloc_amt > 0) { 346 if (type != mtChunk) { 347 _output->print_cr("%27s (malloc=%d%s, #%d)", " ", malloc_amt, unit, 348 malloc_count); 349 } else { 350 _output->print_cr("%27s (malloc=%d%s)", " ", malloc_amt, unit); 351 } 352 } 353 354 if (reserved_amt > 0) { 355 _output->print_cr("%27s (mmap: reserved=%d%s, committed=%d%s)", 356 " ", reserved_amt, unit, committed_amt, unit); 357 } 358 359 if (arena_amt > 0) { 360 _output->print_cr("%27s (arena=%d%s, #%d)", " ", arena_amt, unit, arena_count); 361 } 362 363 _output->print_cr(" "); 364 } 365 } 366 } 367 368 void BaselineTTYOutputer::done_category_summary() { 369 _output->print_cr(" "); 370 } 371 372 373 void BaselineTTYOutputer::start_virtual_memory_map() { 374 _output->print_cr("Virtual memory map:"); 375 } 376 377 void BaselineTTYOutputer::reserved_memory_region(MEMFLAGS type, address base, address end, 378 size_t size, address pc) { 379 const char* unit = memory_unit(_scale); 380 char buf[128]; 381 int offset; 382 _output->print_cr(" "); 383 _output->print_cr("[" PTR_FORMAT " - " PTR_FORMAT "] reserved %d%s for %s", base, end, size, unit, 384 MemBaseline::type2name(type)); 385 if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) { 386 _output->print_cr("\t\tfrom [%s+0x%x]", buf, offset); 387 } 388 } 389 390 void BaselineTTYOutputer::committed_memory_region(address base, address end, size_t size, address pc) { 391 const char* unit = memory_unit(_scale); 392 char buf[128]; 393 int offset; 394 _output->print("\t[" PTR_FORMAT " - " PTR_FORMAT "] committed %d%s", base, end, size, unit); 395 if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) { 396 _output->print_cr(" from [%s+0x%x]", buf, offset); 397 } 398 } 399 400 void BaselineTTYOutputer::done_virtual_memory_map() { 401 _output->print_cr(" "); 402 } 403 404 405 406 void BaselineTTYOutputer::start_callsite() { 407 _output->print_cr("Details:"); 408 _output->print_cr(" "); 409 } 410 411 void BaselineTTYOutputer::done_callsite() { 412 _output->print_cr(" "); 413 } 414 415 void BaselineTTYOutputer::malloc_callsite(address pc, size_t malloc_amt, 416 size_t malloc_count) { 417 if (malloc_amt > 0) { 418 const char* unit = memory_unit(_scale); 419 char buf[128]; 420 int offset; 421 if (pc == 0) { 422 _output->print("[BOOTSTRAP]%18s", " "); 423 } else if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) { 424 _output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset); 425 _output->print("%28s", " "); 426 } else { 427 _output->print("[" PTR_FORMAT "]%18s", pc, " "); 428 } 429 430 _output->print_cr("(malloc=%d%s #%d)", malloc_amt, unit, malloc_count); 431 _output->print_cr(" "); 432 } 433 } 434 435 void BaselineTTYOutputer::virtual_memory_callsite(address pc, size_t reserved_amt, 436 size_t committed_amt) { 437 if (reserved_amt > 0) { 438 const char* unit = memory_unit(_scale); 439 char buf[128]; 440 int offset; 441 if (pc == 0) { 442 _output->print("[BOOTSTRAP]%18s", " "); 443 } else if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) { 444 _output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset); 445 _output->print("%28s", " "); 446 } else { 447 _output->print("[" PTR_FORMAT "]%18s", pc, " "); 448 } 449 450 _output->print_cr("(mmap: reserved=%d%s, committed=%d%s)", 451 reserved_amt, unit, committed_amt, unit); 452 _output->print_cr(" "); 453 } 454 } 455 456 void BaselineTTYOutputer::diff_total_usage(size_t total_reserved, 457 size_t total_committed, int reserved_diff, int committed_diff) { 458 const char* unit = memory_unit(_scale); 459 _output->print_cr("Total: reserved=%d%s %+d%s, committed=%d%s %+d%s", 460 total_reserved, unit, reserved_diff, unit, total_committed, unit, 461 committed_diff, unit); 462 } 463 464 void BaselineTTYOutputer::diff_category_summary(MEMFLAGS type, 465 size_t cur_reserved_amt, size_t cur_committed_amt, 466 size_t cur_malloc_amt, size_t cur_malloc_count, 467 size_t cur_arena_amt, size_t cur_arena_count, 468 int reserved_diff, int committed_diff, int malloc_diff, 469 int malloc_count_diff, int arena_diff, int arena_count_diff) { 470 471 if (type == mtThreadStack) { 472 assert(cur_malloc_amt == 0 && cur_malloc_count == 0 && 473 cur_arena_amt == 0, "Just check"); 474 _thread_stack_reserved = cur_reserved_amt; 475 _thread_stack_committed = cur_committed_amt; 476 _thread_stack_reserved_diff = reserved_diff; 477 _thread_stack_committed_diff = committed_diff; 478 } else { 479 const char* unit = memory_unit(_scale); 480 size_t total_reserved = (cur_reserved_amt + cur_malloc_amt + cur_arena_amt); 481 // nothing to report in this category 482 if (total_reserved == 0) { 483 return; 484 } 485 int diff_reserved = (reserved_diff + malloc_diff + arena_diff); 486 487 // category summary 488 _output->print("-%26s (reserved=%d%s", MemBaseline::type2name(type), 489 total_reserved, unit); 490 491 if (diff_reserved != 0) { 492 _output->print(" %+d%s", diff_reserved, unit); 493 } 494 495 size_t total_committed = cur_committed_amt + cur_malloc_amt + cur_arena_amt; 496 _output->print(", committed=%d%s", total_committed, unit); 497 498 int total_committed_diff = committed_diff + malloc_diff + arena_diff; 499 if (total_committed_diff != 0) { 500 _output->print(" %+d%s", total_committed_diff, unit); 501 } 502 503 _output->print_cr(")"); 504 505 // special cases 506 if (type == mtClass) { 507 _output->print("%27s (classes #%d", " ", _num_of_classes); 508 if (_num_of_classes_diff != 0) { 509 _output->print(" %+d", _num_of_classes_diff); 510 } 511 _output->print_cr(")"); 512 } else if (type == mtThread) { 513 // thread count 514 _output->print("%27s (thread #%d", " ", _num_of_threads); 515 if (_num_of_threads_diff != 0) { 516 _output->print_cr(" %+d)", _num_of_threads_diff); 517 } else { 518 _output->print_cr(")"); 519 } 520 _output->print("%27s (stack: reserved=%d%s", " ", _thread_stack_reserved, unit); 521 if (_thread_stack_reserved_diff != 0) { 522 _output->print(" %+d%s", _thread_stack_reserved_diff, unit); 523 } 524 525 _output->print(", committed=%d%s", _thread_stack_committed, unit); 526 if (_thread_stack_committed_diff != 0) { 527 _output->print(" %+d%s",_thread_stack_committed_diff, unit); 528 } 529 530 _output->print_cr(")"); 531 } 532 533 // malloc'd memory 534 if (cur_malloc_amt > 0) { 535 _output->print("%27s (malloc=%d%s", " ", cur_malloc_amt, unit); 536 if (malloc_diff != 0) { 537 _output->print(" %+d%s", malloc_diff, unit); 538 } 539 if (type != mtChunk) { 540 _output->print(", #%d", cur_malloc_count); 541 if (malloc_count_diff) { 542 _output->print(" %+d", malloc_count_diff); 543 } 544 } 545 _output->print_cr(")"); 546 } 547 548 // mmap'd memory 549 if (cur_reserved_amt > 0) { 550 _output->print("%27s (mmap: reserved=%d%s", " ", cur_reserved_amt, unit); 551 if (reserved_diff != 0) { 552 _output->print(" %+d%s", reserved_diff, unit); 553 } 554 555 _output->print(", committed=%d%s", cur_committed_amt, unit); 556 if (committed_diff != 0) { 557 _output->print(" %+d%s", committed_diff, unit); 558 } 559 _output->print_cr(")"); 560 } 561 562 // arena memory 563 if (cur_arena_amt > 0) { 564 _output->print("%27s (arena=%d%s", " ", cur_arena_amt, unit); 565 if (arena_diff != 0) { 566 _output->print(" %+d%s", arena_diff, unit); 567 } 568 _output->print(", #%d", cur_arena_count); 569 if (arena_count_diff != 0) { 570 _output->print(" %+d", arena_count_diff); 571 } 572 _output->print_cr(")"); 573 } 574 575 _output->print_cr(" "); 576 } 577 } 578 579 void BaselineTTYOutputer::diff_malloc_callsite(address pc, 580 size_t cur_malloc_amt, size_t cur_malloc_count, 581 int malloc_diff, int malloc_count_diff) { 582 if (malloc_diff != 0) { 583 const char* unit = memory_unit(_scale); 584 char buf[128]; 585 int offset; 586 if (pc == 0) { 587 _output->print_cr("[BOOTSTRAP]%18s", " "); 588 } else { 589 if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) { 590 _output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset); 591 _output->print("%28s", " "); 592 } else { 593 _output->print("[" PTR_FORMAT "]%18s", pc, " "); 594 } 595 } 596 597 _output->print("(malloc=%d%s", cur_malloc_amt, unit); 598 if (malloc_diff != 0) { 599 _output->print(" %+d%s", malloc_diff, unit); 600 } 601 _output->print(", #%d", cur_malloc_count); 602 if (malloc_count_diff != 0) { 603 _output->print(" %+d", malloc_count_diff); 604 } 605 _output->print_cr(")"); 606 _output->print_cr(" "); 607 } 608 } 609 610 void BaselineTTYOutputer::diff_virtual_memory_callsite(address pc, 611 size_t cur_reserved_amt, size_t cur_committed_amt, 612 int reserved_diff, int committed_diff) { 613 if (reserved_diff != 0 || committed_diff != 0) { 614 const char* unit = memory_unit(_scale); 615 char buf[64]; 616 int offset; 617 if (pc == 0) { 618 _output->print_cr("[BOOSTRAP]%18s", " "); 619 } else { 620 if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) { 621 _output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset); 622 _output->print("%28s", " "); 623 } else { 624 _output->print("[" PTR_FORMAT "]%18s", pc, " "); 625 } 626 } 627 628 _output->print("(mmap: reserved=%d%s", cur_reserved_amt, unit); 629 if (reserved_diff != 0) { 630 _output->print(" %+d%s", reserved_diff, unit); 631 } 632 _output->print(", committed=%d%s", cur_committed_amt, unit); 633 if (committed_diff != 0) { 634 _output->print(" %+d%s", committed_diff, unit); 635 } 636 _output->print_cr(")"); 637 _output->print_cr(" "); 638 } 639 }