src/share/vm/services/memReporter.cpp

changeset 7074
833b0f92429a
parent 6680
78bbf4d43a14
child 7535
7ae4e26cb1e0
child 9053
da59531e1fdf
     1.1 --- a/src/share/vm/services/memReporter.cpp	Wed Aug 27 09:36:55 2014 +0200
     1.2 +++ b/src/share/vm/services/memReporter.cpp	Wed Aug 27 08:19:12 2014 -0400
     1.3 @@ -22,618 +22,595 @@
     1.4   *
     1.5   */
     1.6  #include "precompiled.hpp"
     1.7 -#include "classfile/systemDictionary.hpp"
     1.8 -#include "runtime/os.hpp"
     1.9 +
    1.10 +#include "memory/allocation.hpp"
    1.11 +#include "services/mallocTracker.hpp"
    1.12  #include "services/memReporter.hpp"
    1.13 -#include "services/memPtrArray.hpp"
    1.14 -#include "services/memTracker.hpp"
    1.15 +#include "services/virtualMemoryTracker.hpp"
    1.16 +#include "utilities/globalDefinitions.hpp"
    1.17  
    1.18 -PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
    1.19 -
    1.20 -const char* BaselineOutputer::memory_unit(size_t scale) {
    1.21 -  switch(scale) {
    1.22 -    case K: return "KB";
    1.23 -    case M: return "MB";
    1.24 -    case G: return "GB";
    1.25 -  }
    1.26 -  ShouldNotReachHere();
    1.27 -  return NULL;
    1.28 +size_t MemReporterBase::reserved_total(const MallocMemory* malloc, const VirtualMemory* vm) const {
    1.29 +  return malloc->malloc_size() + malloc->arena_size() + vm->reserved();
    1.30  }
    1.31  
    1.32 -
    1.33 -void BaselineReporter::report_baseline(const MemBaseline& baseline, bool summary_only) {
    1.34 -  assert(MemTracker::is_on(), "Native memory tracking is off");
    1.35 -  _outputer.start(scale());
    1.36 -  _outputer.total_usage(
    1.37 -    amount_in_current_scale(baseline.total_malloc_amount() + baseline.total_reserved_amount()),
    1.38 -    amount_in_current_scale(baseline.total_malloc_amount() + baseline.total_committed_amount()));
    1.39 -
    1.40 -  _outputer.num_of_classes(baseline.number_of_classes());
    1.41 -  _outputer.num_of_threads(baseline.number_of_threads());
    1.42 -
    1.43 -  report_summaries(baseline);
    1.44 -  if (!summary_only && MemTracker::track_callsite()) {
    1.45 -    report_virtual_memory_map(baseline);
    1.46 -    report_callsites(baseline);
    1.47 -  }
    1.48 -  _outputer.done();
    1.49 +size_t MemReporterBase::committed_total(const MallocMemory* malloc, const VirtualMemory* vm) const {
    1.50 +  return malloc->malloc_size() + malloc->arena_size() + vm->committed();
    1.51  }
    1.52  
    1.53 -void BaselineReporter::report_summaries(const MemBaseline& baseline) {
    1.54 -  _outputer.start_category_summary();
    1.55 -  MEMFLAGS type;
    1.56 +void MemReporterBase::print_total(size_t reserved, size_t committed) const {
    1.57 +  const char* scale = current_scale();
    1.58 +  output()->print("reserved=" SIZE_FORMAT "%s, committed=" SIZE_FORMAT "%s",
    1.59 +    amount_in_current_scale(reserved), scale, amount_in_current_scale(committed), scale);
    1.60 +}
    1.61  
    1.62 -  for (int index = 0; index < NUMBER_OF_MEMORY_TYPE; index ++) {
    1.63 -    type = MemBaseline::MemType2NameMap[index]._flag;
    1.64 -    _outputer.category_summary(type,
    1.65 -      amount_in_current_scale(baseline.reserved_amount(type)),
    1.66 -      amount_in_current_scale(baseline.committed_amount(type)),
    1.67 -      amount_in_current_scale(baseline.malloc_amount(type)),
    1.68 -      baseline.malloc_count(type),
    1.69 -      amount_in_current_scale(baseline.arena_amount(type)),
    1.70 -      baseline.arena_count(type));
    1.71 +void MemReporterBase::print_malloc(size_t amount, size_t count) const {
    1.72 +  const char* scale = current_scale();
    1.73 +  outputStream* out = output();
    1.74 +  out->print("(malloc=" SIZE_FORMAT "%s",
    1.75 +    amount_in_current_scale(amount), scale);
    1.76 +
    1.77 +  if (count > 0) {
    1.78 +    out->print(" #" SIZE_FORMAT "", count);
    1.79    }
    1.80  
    1.81 -  _outputer.done_category_summary();
    1.82 +  out->print(")");
    1.83  }
    1.84  
    1.85 -void BaselineReporter::report_virtual_memory_map(const MemBaseline& baseline) {
    1.86 -  _outputer.start_virtual_memory_map();
    1.87 -  MemBaseline* pBL = const_cast<MemBaseline*>(&baseline);
    1.88 -  MemPointerArrayIteratorImpl itr = MemPointerArrayIteratorImpl(pBL->_vm_map);
    1.89 -  VMMemRegionEx* rgn = (VMMemRegionEx*)itr.current();
    1.90 -  while (rgn != NULL) {
    1.91 -    if (rgn->is_reserved_region()) {
    1.92 -      _outputer.reserved_memory_region(FLAGS_TO_MEMORY_TYPE(rgn->flags()),
    1.93 -        rgn->base(), rgn->base() + rgn->size(), amount_in_current_scale(rgn->size()), rgn->pc());
    1.94 -    } else {
    1.95 -      _outputer.committed_memory_region(rgn->base(), rgn->base() + rgn->size(),
    1.96 -        amount_in_current_scale(rgn->size()), rgn->pc());
    1.97 -    }
    1.98 -    rgn = (VMMemRegionEx*)itr.next();
    1.99 +void MemReporterBase::print_virtual_memory(size_t reserved, size_t committed) const {
   1.100 +  const char* scale = current_scale();
   1.101 +  output()->print("(mmap: reserved=" SIZE_FORMAT "%s, committed=" SIZE_FORMAT "%s)",
   1.102 +    amount_in_current_scale(reserved), scale, amount_in_current_scale(committed), scale);
   1.103 +}
   1.104 +
   1.105 +void MemReporterBase::print_malloc_line(size_t amount, size_t count) const {
   1.106 +  output()->print("%28s", " ");
   1.107 +  print_malloc(amount, count);
   1.108 +  output()->print_cr(" ");
   1.109 +}
   1.110 +
   1.111 +void MemReporterBase::print_virtual_memory_line(size_t reserved, size_t committed) const {
   1.112 +  output()->print("%28s", " ");
   1.113 +  print_virtual_memory(reserved, committed);
   1.114 +  output()->print_cr(" ");
   1.115 +}
   1.116 +
   1.117 +void MemReporterBase::print_arena_line(size_t amount, size_t count) const {
   1.118 +  const char* scale = current_scale();
   1.119 +  output()->print_cr("%27s (arena=" SIZE_FORMAT "%s #" SIZE_FORMAT ")", " ",
   1.120 +    amount_in_current_scale(amount), scale, count);
   1.121 +}
   1.122 +
   1.123 +void MemReporterBase::print_virtual_memory_region(const char* type, address base, size_t size) const {
   1.124 +  const char* scale = current_scale();
   1.125 +  output()->print("[" PTR_FORMAT " - " PTR_FORMAT "] %s " SIZE_FORMAT "%s",
   1.126 +    p2i(base), p2i(base + size), type, amount_in_current_scale(size), scale);
   1.127 +}
   1.128 +
   1.129 +
   1.130 +void MemSummaryReporter::report() {
   1.131 +  const char* scale = current_scale();
   1.132 +  outputStream* out = output();
   1.133 +  size_t total_reserved_amount = _malloc_snapshot->total() +
   1.134 +    _vm_snapshot->total_reserved();
   1.135 +  size_t total_committed_amount = _malloc_snapshot->total() +
   1.136 +    _vm_snapshot->total_committed();
   1.137 +
   1.138 +  // Overall total
   1.139 +  out->print_cr("\nNative Memory Tracking:\n");
   1.140 +  out->print("Total: ");
   1.141 +  print_total(total_reserved_amount, total_committed_amount);
   1.142 +  out->print("\n");
   1.143 +
   1.144 +  // Summary by memory type
   1.145 +  for (int index = 0; index < mt_number_of_types; index ++) {
   1.146 +    MEMFLAGS flag = NMTUtil::index_to_flag(index);
   1.147 +    // thread stack is reported as part of thread category
   1.148 +    if (flag == mtThreadStack) continue;
   1.149 +    MallocMemory* malloc_memory = _malloc_snapshot->by_type(flag);
   1.150 +    VirtualMemory* virtual_memory = _vm_snapshot->by_type(flag);
   1.151 +
   1.152 +    report_summary_of_type(flag, malloc_memory, virtual_memory);
   1.153 +  }
   1.154 +}
   1.155 +
   1.156 +void MemSummaryReporter::report_summary_of_type(MEMFLAGS flag,
   1.157 +  MallocMemory*  malloc_memory, VirtualMemory* virtual_memory) {
   1.158 +
   1.159 +  size_t reserved_amount  = reserved_total (malloc_memory, virtual_memory);
   1.160 +  size_t committed_amount = committed_total(malloc_memory, virtual_memory);
   1.161 +
   1.162 +  // Count thread's native stack in "Thread" category
   1.163 +  if (flag == mtThread) {
   1.164 +    const VirtualMemory* thread_stack_usage =
   1.165 +      (const VirtualMemory*)_vm_snapshot->by_type(mtThreadStack);
   1.166 +    reserved_amount  += thread_stack_usage->reserved();
   1.167 +    committed_amount += thread_stack_usage->committed();
   1.168 +  } else if (flag == mtNMT) {
   1.169 +    // Count malloc headers in "NMT" category
   1.170 +    reserved_amount  += _malloc_snapshot->malloc_overhead()->size();
   1.171 +    committed_amount += _malloc_snapshot->malloc_overhead()->size();
   1.172    }
   1.173  
   1.174 -  _outputer.done_virtual_memory_map();
   1.175 +  if (amount_in_current_scale(reserved_amount) > 0) {
   1.176 +    outputStream* out   = output();
   1.177 +    const char*   scale = current_scale();
   1.178 +    out->print("-%26s (", NMTUtil::flag_to_name(flag));
   1.179 +    print_total(reserved_amount, committed_amount);
   1.180 +    out->print_cr(")");
   1.181 +
   1.182 +    if (flag == mtClass) {
   1.183 +      // report class count
   1.184 +      out->print_cr("%27s (classes #" SIZE_FORMAT ")", " ", _class_count);
   1.185 +    } else if (flag == mtThread) {
   1.186 +      // report thread count
   1.187 +      out->print_cr("%27s (thread #" SIZE_FORMAT ")", " ", _malloc_snapshot->thread_count());
   1.188 +      const VirtualMemory* thread_stack_usage =
   1.189 +       _vm_snapshot->by_type(mtThreadStack);
   1.190 +      out->print("%27s (stack: ", " ");
   1.191 +      print_total(thread_stack_usage->reserved(), thread_stack_usage->committed());
   1.192 +      out->print_cr(")");
   1.193 +    }
   1.194 +
   1.195 +     // report malloc'd memory
   1.196 +    if (amount_in_current_scale(malloc_memory->malloc_size()) > 0) {
   1.197 +      // We don't know how many arena chunks are in used, so don't report the count
   1.198 +      size_t count = (flag == mtChunk) ? 0 : malloc_memory->malloc_count();
   1.199 +      print_malloc_line(malloc_memory->malloc_size(), count);
   1.200 +    }
   1.201 +
   1.202 +    if (amount_in_current_scale(virtual_memory->reserved()) > 0) {
   1.203 +      print_virtual_memory_line(virtual_memory->reserved(), virtual_memory->committed());
   1.204 +    }
   1.205 +
   1.206 +    if (amount_in_current_scale(malloc_memory->arena_size()) > 0) {
   1.207 +      print_arena_line(malloc_memory->arena_size(), malloc_memory->arena_count());
   1.208 +    }
   1.209 +
   1.210 +    if (flag == mtNMT &&
   1.211 +      amount_in_current_scale(_malloc_snapshot->malloc_overhead()->size()) > 0) {
   1.212 +      out->print_cr("%27s (tracking overhead=" SIZE_FORMAT "%s)", " ",
   1.213 +        amount_in_current_scale(_malloc_snapshot->malloc_overhead()->size()), scale);
   1.214 +    }
   1.215 +
   1.216 +    out->print_cr(" ");
   1.217 +  }
   1.218  }
   1.219  
   1.220 -void BaselineReporter::report_callsites(const MemBaseline& baseline) {
   1.221 -  _outputer.start_callsite();
   1.222 -  MemBaseline* pBL = const_cast<MemBaseline*>(&baseline);
   1.223 +void MemDetailReporter::report_detail() {
   1.224 +  // Start detail report
   1.225 +  outputStream* out = output();
   1.226 +  out->print_cr("Details:\n");
   1.227  
   1.228 -  pBL->_malloc_cs->sort((FN_SORT)MemBaseline::bl_malloc_sort_by_size);
   1.229 -  pBL->_vm_cs->sort((FN_SORT)MemBaseline::bl_vm_sort_by_size);
   1.230 +  report_malloc_sites();
   1.231 +  report_virtual_memory_allocation_sites();
   1.232 +}
   1.233  
   1.234 -  // walk malloc callsites
   1.235 -  MemPointerArrayIteratorImpl malloc_itr(pBL->_malloc_cs);
   1.236 -  MallocCallsitePointer*      malloc_callsite =
   1.237 -                  (MallocCallsitePointer*)malloc_itr.current();
   1.238 -  while (malloc_callsite != NULL) {
   1.239 -    _outputer.malloc_callsite(malloc_callsite->addr(),
   1.240 -        amount_in_current_scale(malloc_callsite->amount()), malloc_callsite->count());
   1.241 -    malloc_callsite = (MallocCallsitePointer*)malloc_itr.next();
   1.242 +void MemDetailReporter::report_malloc_sites() {
   1.243 +  MallocSiteIterator         malloc_itr = _baseline.malloc_sites(MemBaseline::by_size);
   1.244 +  if (malloc_itr.is_empty()) return;
   1.245 +
   1.246 +  outputStream* out = output();
   1.247 +
   1.248 +  const MallocSite* malloc_site;
   1.249 +  while ((malloc_site = malloc_itr.next()) != NULL) {
   1.250 +    // Don't report if size is too small
   1.251 +    if (amount_in_current_scale(malloc_site->size()) == 0)
   1.252 +      continue;
   1.253 +
   1.254 +    const NativeCallStack* stack = malloc_site->call_stack();
   1.255 +    stack->print_on(out);
   1.256 +    out->print("%29s", " ");
   1.257 +    print_malloc(malloc_site->size(), malloc_site->count());
   1.258 +    out->print_cr("\n");
   1.259 +  }
   1.260 +}
   1.261 +
   1.262 +void MemDetailReporter::report_virtual_memory_allocation_sites()  {
   1.263 +  VirtualMemorySiteIterator  virtual_memory_itr =
   1.264 +    _baseline.virtual_memory_sites(MemBaseline::by_size);
   1.265 +
   1.266 +  if (virtual_memory_itr.is_empty()) return;
   1.267 +
   1.268 +  outputStream* out = output();
   1.269 +  const VirtualMemoryAllocationSite*  virtual_memory_site;
   1.270 +
   1.271 +  while ((virtual_memory_site = virtual_memory_itr.next()) != NULL) {
   1.272 +    // Don't report if size is too small
   1.273 +    if (amount_in_current_scale(virtual_memory_site->reserved()) == 0)
   1.274 +      continue;
   1.275 +
   1.276 +    const NativeCallStack* stack = virtual_memory_site->call_stack();
   1.277 +    stack->print_on(out);
   1.278 +    out->print("%28s (", " ");
   1.279 +    print_total(virtual_memory_site->reserved(), virtual_memory_site->committed());
   1.280 +    out->print_cr(")\n");
   1.281 +  }
   1.282 +}
   1.283 +
   1.284 +
   1.285 +void MemDetailReporter::report_virtual_memory_map() {
   1.286 +  // Virtual memory map always in base address order
   1.287 +  VirtualMemoryAllocationIterator itr = _baseline.virtual_memory_allocations();
   1.288 +  const ReservedMemoryRegion* rgn;
   1.289 +
   1.290 +  output()->print_cr("Virtual memory map:");
   1.291 +  while ((rgn = itr.next()) != NULL) {
   1.292 +    report_virtual_memory_region(rgn);
   1.293 +  }
   1.294 +}
   1.295 +
   1.296 +void MemDetailReporter::report_virtual_memory_region(const ReservedMemoryRegion* reserved_rgn) {
   1.297 +  assert(reserved_rgn != NULL, "NULL pointer");
   1.298 +
   1.299 +  // Don't report if size is too small
   1.300 +  if (amount_in_current_scale(reserved_rgn->size()) == 0) return;
   1.301 +
   1.302 +  outputStream* out = output();
   1.303 +  const char* scale = current_scale();
   1.304 +  const NativeCallStack*  stack = reserved_rgn->call_stack();
   1.305 +  bool all_committed = reserved_rgn->all_committed();
   1.306 +  const char* region_type = (all_committed ? "reserved and committed" : "reserved");
   1.307 +  out->print_cr(" ");
   1.308 +  print_virtual_memory_region(region_type, reserved_rgn->base(), reserved_rgn->size());
   1.309 +  out->print(" for %s", NMTUtil::flag_to_name(reserved_rgn->flag()));
   1.310 +  if (stack->is_empty()) {
   1.311 +    out->print_cr(" ");
   1.312 +  } else {
   1.313 +    out->print_cr(" from");
   1.314 +    stack->print_on(out, 4);
   1.315    }
   1.316  
   1.317 -  // walk virtual memory callsite
   1.318 -  MemPointerArrayIteratorImpl vm_itr(pBL->_vm_cs);
   1.319 -  VMCallsitePointer*          vm_callsite = (VMCallsitePointer*)vm_itr.current();
   1.320 -  while (vm_callsite != NULL) {
   1.321 -    _outputer.virtual_memory_callsite(vm_callsite->addr(),
   1.322 -      amount_in_current_scale(vm_callsite->reserved_amount()),
   1.323 -      amount_in_current_scale(vm_callsite->committed_amount()));
   1.324 -    vm_callsite = (VMCallsitePointer*)vm_itr.next();
   1.325 -  }
   1.326 -  pBL->_malloc_cs->sort((FN_SORT)MemBaseline::bl_malloc_sort_by_pc);
   1.327 -  pBL->_vm_cs->sort((FN_SORT)MemBaseline::bl_vm_sort_by_pc);
   1.328 -  _outputer.done_callsite();
   1.329 -}
   1.330 +  if (all_committed) return;
   1.331  
   1.332 -void BaselineReporter::diff_baselines(const MemBaseline& cur, const MemBaseline& prev,
   1.333 -  bool summary_only) {
   1.334 -  assert(MemTracker::is_on(), "Native memory tracking is off");
   1.335 -  _outputer.start(scale());
   1.336 -  size_t total_reserved = cur.total_malloc_amount() + cur.total_reserved_amount();
   1.337 -  size_t total_committed = cur.total_malloc_amount() + cur.total_committed_amount();
   1.338 -
   1.339 -  _outputer.diff_total_usage(
   1.340 -    amount_in_current_scale(total_reserved), amount_in_current_scale(total_committed),
   1.341 -    diff_in_current_scale(total_reserved,  (prev.total_malloc_amount() + prev.total_reserved_amount())),
   1.342 -    diff_in_current_scale(total_committed, (prev.total_committed_amount() + prev.total_malloc_amount())));
   1.343 -
   1.344 -  _outputer.diff_num_of_classes(cur.number_of_classes(),
   1.345 -       diff(cur.number_of_classes(), prev.number_of_classes()));
   1.346 -  _outputer.diff_num_of_threads(cur.number_of_threads(),
   1.347 -       diff(cur.number_of_threads(), prev.number_of_threads()));
   1.348 -
   1.349 -  diff_summaries(cur, prev);
   1.350 -  if (!summary_only && MemTracker::track_callsite()) {
   1.351 -    diff_callsites(cur, prev);
   1.352 -  }
   1.353 -  _outputer.done();
   1.354 -}
   1.355 -
   1.356 -void BaselineReporter::diff_summaries(const MemBaseline& cur, const MemBaseline& prev) {
   1.357 -  _outputer.start_category_summary();
   1.358 -  MEMFLAGS type;
   1.359 -
   1.360 -  for (int index = 0; index < NUMBER_OF_MEMORY_TYPE; index ++) {
   1.361 -    type = MemBaseline::MemType2NameMap[index]._flag;
   1.362 -    _outputer.diff_category_summary(type,
   1.363 -      amount_in_current_scale(cur.reserved_amount(type)),
   1.364 -      amount_in_current_scale(cur.committed_amount(type)),
   1.365 -      amount_in_current_scale(cur.malloc_amount(type)),
   1.366 -      cur.malloc_count(type),
   1.367 -      amount_in_current_scale(cur.arena_amount(type)),
   1.368 -      cur.arena_count(type),
   1.369 -      diff_in_current_scale(cur.reserved_amount(type), prev.reserved_amount(type)),
   1.370 -      diff_in_current_scale(cur.committed_amount(type), prev.committed_amount(type)),
   1.371 -      diff_in_current_scale(cur.malloc_amount(type), prev.malloc_amount(type)),
   1.372 -      diff(cur.malloc_count(type), prev.malloc_count(type)),
   1.373 -      diff_in_current_scale(cur.arena_amount(type), prev.arena_amount(type)),
   1.374 -      diff(cur.arena_count(type), prev.arena_count(type)));
   1.375 -  }
   1.376 -
   1.377 -  _outputer.done_category_summary();
   1.378 -}
   1.379 -
   1.380 -void BaselineReporter::diff_callsites(const MemBaseline& cur, const MemBaseline& prev) {
   1.381 -  _outputer.start_callsite();
   1.382 -  MemBaseline* pBL_cur = const_cast<MemBaseline*>(&cur);
   1.383 -  MemBaseline* pBL_prev = const_cast<MemBaseline*>(&prev);
   1.384 -
   1.385 -  // walk malloc callsites
   1.386 -  MemPointerArrayIteratorImpl cur_malloc_itr(pBL_cur->_malloc_cs);
   1.387 -  MemPointerArrayIteratorImpl prev_malloc_itr(pBL_prev->_malloc_cs);
   1.388 -
   1.389 -  MallocCallsitePointer*      cur_malloc_callsite =
   1.390 -                  (MallocCallsitePointer*)cur_malloc_itr.current();
   1.391 -  MallocCallsitePointer*      prev_malloc_callsite =
   1.392 -                  (MallocCallsitePointer*)prev_malloc_itr.current();
   1.393 -
   1.394 -  while (cur_malloc_callsite != NULL || prev_malloc_callsite != NULL) {
   1.395 -    if (prev_malloc_callsite == NULL) {
   1.396 -      assert(cur_malloc_callsite != NULL, "sanity check");
   1.397 -      // this is a new callsite
   1.398 -      _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(),
   1.399 -        amount_in_current_scale(cur_malloc_callsite->amount()),
   1.400 -        cur_malloc_callsite->count(),
   1.401 -        diff_in_current_scale(cur_malloc_callsite->amount(), 0),
   1.402 -        diff(cur_malloc_callsite->count(), 0));
   1.403 -      cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next();
   1.404 -    } else if (cur_malloc_callsite == NULL) {
   1.405 -      assert(prev_malloc_callsite != NULL, "Sanity check");
   1.406 -      // this callsite is already gone
   1.407 -      _outputer.diff_malloc_callsite(prev_malloc_callsite->addr(),
   1.408 -        0, 0,
   1.409 -        diff_in_current_scale(0, prev_malloc_callsite->amount()),
   1.410 -        diff(0, prev_malloc_callsite->count()));
   1.411 -      prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next();
   1.412 +  CommittedRegionIterator itr = reserved_rgn->iterate_committed_regions();
   1.413 +  const CommittedMemoryRegion* committed_rgn;
   1.414 +  while ((committed_rgn = itr.next()) != NULL) {
   1.415 +    // Don't report if size is too small
   1.416 +    if (amount_in_current_scale(committed_rgn->size()) == 0) continue;
   1.417 +    stack = committed_rgn->call_stack();
   1.418 +    out->print("\n\t");
   1.419 +    print_virtual_memory_region("committed", committed_rgn->base(), committed_rgn->size());
   1.420 +    if (stack->is_empty()) {
   1.421 +      out->print_cr(" ");
   1.422      } else {
   1.423 -      assert(cur_malloc_callsite  != NULL,  "Sanity check");
   1.424 -      assert(prev_malloc_callsite != NULL,  "Sanity check");
   1.425 -      if (cur_malloc_callsite->addr() < prev_malloc_callsite->addr()) {
   1.426 -        // this is a new callsite
   1.427 -        _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(),
   1.428 -          amount_in_current_scale(cur_malloc_callsite->amount()),
   1.429 -          cur_malloc_callsite->count(),
   1.430 -          diff_in_current_scale(cur_malloc_callsite->amount(), 0),
   1.431 -          diff(cur_malloc_callsite->count(), 0));
   1.432 -          cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next();
   1.433 -      } else if (cur_malloc_callsite->addr() > prev_malloc_callsite->addr()) {
   1.434 -        // this callsite is already gone
   1.435 -        _outputer.diff_malloc_callsite(prev_malloc_callsite->addr(),
   1.436 -          0, 0,
   1.437 -          diff_in_current_scale(0, prev_malloc_callsite->amount()),
   1.438 -          diff(0, prev_malloc_callsite->count()));
   1.439 -        prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next();
   1.440 -      } else {
   1.441 -        // the same callsite
   1.442 -        _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(),
   1.443 -          amount_in_current_scale(cur_malloc_callsite->amount()),
   1.444 -          cur_malloc_callsite->count(),
   1.445 -          diff_in_current_scale(cur_malloc_callsite->amount(), prev_malloc_callsite->amount()),
   1.446 -          diff(cur_malloc_callsite->count(), prev_malloc_callsite->count()));
   1.447 -        cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next();
   1.448 -        prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next();
   1.449 -      }
   1.450 -    }
   1.451 -  }
   1.452 -
   1.453 -  // walk virtual memory callsite
   1.454 -  MemPointerArrayIteratorImpl cur_vm_itr(pBL_cur->_vm_cs);
   1.455 -  MemPointerArrayIteratorImpl prev_vm_itr(pBL_prev->_vm_cs);
   1.456 -  VMCallsitePointer*          cur_vm_callsite = (VMCallsitePointer*)cur_vm_itr.current();
   1.457 -  VMCallsitePointer*          prev_vm_callsite = (VMCallsitePointer*)prev_vm_itr.current();
   1.458 -  while (cur_vm_callsite != NULL || prev_vm_callsite != NULL) {
   1.459 -    if (prev_vm_callsite == NULL || cur_vm_callsite->addr() < prev_vm_callsite->addr()) {
   1.460 -      // this is a new callsite
   1.461 -      _outputer.diff_virtual_memory_callsite(cur_vm_callsite->addr(),
   1.462 -        amount_in_current_scale(cur_vm_callsite->reserved_amount()),
   1.463 -        amount_in_current_scale(cur_vm_callsite->committed_amount()),
   1.464 -        diff_in_current_scale(cur_vm_callsite->reserved_amount(), 0),
   1.465 -        diff_in_current_scale(cur_vm_callsite->committed_amount(), 0));
   1.466 -      cur_vm_callsite = (VMCallsitePointer*)cur_vm_itr.next();
   1.467 -    } else if (cur_vm_callsite == NULL || cur_vm_callsite->addr() > prev_vm_callsite->addr()) {
   1.468 -      // this callsite is already gone
   1.469 -      _outputer.diff_virtual_memory_callsite(prev_vm_callsite->addr(),
   1.470 -        amount_in_current_scale(0),
   1.471 -        amount_in_current_scale(0),
   1.472 -        diff_in_current_scale(0, prev_vm_callsite->reserved_amount()),
   1.473 -        diff_in_current_scale(0, prev_vm_callsite->committed_amount()));
   1.474 -      prev_vm_callsite = (VMCallsitePointer*)prev_vm_itr.next();
   1.475 -    } else { // the same callsite
   1.476 -      _outputer.diff_virtual_memory_callsite(cur_vm_callsite->addr(),
   1.477 -        amount_in_current_scale(cur_vm_callsite->reserved_amount()),
   1.478 -        amount_in_current_scale(cur_vm_callsite->committed_amount()),
   1.479 -        diff_in_current_scale(cur_vm_callsite->reserved_amount(), prev_vm_callsite->reserved_amount()),
   1.480 -        diff_in_current_scale(cur_vm_callsite->committed_amount(), prev_vm_callsite->committed_amount()));
   1.481 -      cur_vm_callsite  = (VMCallsitePointer*)cur_vm_itr.next();
   1.482 -      prev_vm_callsite = (VMCallsitePointer*)prev_vm_itr.next();
   1.483 -    }
   1.484 -  }
   1.485 -
   1.486 -  _outputer.done_callsite();
   1.487 -}
   1.488 -
   1.489 -size_t BaselineReporter::amount_in_current_scale(size_t amt) const {
   1.490 -  return (size_t)(((float)amt/(float)_scale) + 0.5);
   1.491 -}
   1.492 -
   1.493 -int BaselineReporter::diff_in_current_scale(size_t value1, size_t value2) const {
   1.494 -  return (int)(((float)value1 - (float)value2)/((float)_scale) + 0.5);
   1.495 -}
   1.496 -
   1.497 -int BaselineReporter::diff(size_t value1, size_t value2) const {
   1.498 -  return ((int)value1 - (int)value2);
   1.499 -}
   1.500 -
   1.501 -void BaselineTTYOutputer::start(size_t scale, bool report_diff) {
   1.502 -  _scale = scale;
   1.503 -  _output->print_cr(" ");
   1.504 -  _output->print_cr("Native Memory Tracking:");
   1.505 -  _output->print_cr(" ");
   1.506 -}
   1.507 -
   1.508 -void BaselineTTYOutputer::done() {
   1.509 -
   1.510 -}
   1.511 -
   1.512 -void BaselineTTYOutputer::total_usage(size_t total_reserved, size_t total_committed) {
   1.513 -  const char* unit = memory_unit(_scale);
   1.514 -  _output->print_cr("Total:  reserved=%d%s,  committed=%d%s",
   1.515 -    total_reserved, unit, total_committed, unit);
   1.516 -}
   1.517 -
   1.518 -void BaselineTTYOutputer::start_category_summary() {
   1.519 -  _output->print_cr(" ");
   1.520 -}
   1.521 -
   1.522 -/**
   1.523 - * report a summary of memory type
   1.524 - */
   1.525 -void BaselineTTYOutputer::category_summary(MEMFLAGS type,
   1.526 -  size_t reserved_amt, size_t committed_amt, size_t malloc_amt,
   1.527 -  size_t malloc_count, size_t arena_amt, size_t arena_count) {
   1.528 -
   1.529 -  // we report mtThreadStack under mtThread category
   1.530 -  if (type == mtThreadStack) {
   1.531 -    assert(malloc_amt == 0 && malloc_count == 0 && arena_amt == 0,
   1.532 -      "Just check");
   1.533 -    _thread_stack_reserved = reserved_amt;
   1.534 -    _thread_stack_committed = committed_amt;
   1.535 -  } else {
   1.536 -    const char* unit = memory_unit(_scale);
   1.537 -    size_t total_reserved = (reserved_amt + malloc_amt + arena_amt);
   1.538 -    size_t total_committed = (committed_amt + malloc_amt + arena_amt);
   1.539 -    if (type == mtThread) {
   1.540 -      total_reserved += _thread_stack_reserved;
   1.541 -      total_committed += _thread_stack_committed;
   1.542 -    }
   1.543 -
   1.544 -    if (total_reserved > 0) {
   1.545 -      _output->print_cr("-%26s (reserved=%d%s, committed=%d%s)",
   1.546 -        MemBaseline::type2name(type), total_reserved, unit,
   1.547 -        total_committed, unit);
   1.548 -
   1.549 -      if (type == mtClass) {
   1.550 -        _output->print_cr("%27s (classes #%d)", " ", _num_of_classes);
   1.551 -      } else if (type == mtThread) {
   1.552 -        _output->print_cr("%27s (thread #%d)", " ", _num_of_threads);
   1.553 -        _output->print_cr("%27s (stack: reserved=%d%s, committed=%d%s)", " ",
   1.554 -          _thread_stack_reserved, unit, _thread_stack_committed, unit);
   1.555 -      }
   1.556 -
   1.557 -      if (malloc_amt > 0) {
   1.558 -        if (type != mtChunk) {
   1.559 -          _output->print_cr("%27s (malloc=%d%s, #%d)", " ", malloc_amt, unit,
   1.560 -            malloc_count);
   1.561 -        } else {
   1.562 -          _output->print_cr("%27s (malloc=%d%s)", " ", malloc_amt, unit);
   1.563 -        }
   1.564 -      }
   1.565 -
   1.566 -      if (reserved_amt > 0) {
   1.567 -        _output->print_cr("%27s (mmap: reserved=%d%s, committed=%d%s)",
   1.568 -          " ", reserved_amt, unit, committed_amt, unit);
   1.569 -      }
   1.570 -
   1.571 -      if (arena_amt > 0) {
   1.572 -        _output->print_cr("%27s (arena=%d%s, #%d)", " ", arena_amt, unit, arena_count);
   1.573 -      }
   1.574 -
   1.575 -      _output->print_cr(" ");
   1.576 +      out->print_cr(" from");
   1.577 +      stack->print_on(out, 12);
   1.578      }
   1.579    }
   1.580  }
   1.581  
   1.582 -void BaselineTTYOutputer::done_category_summary() {
   1.583 -  _output->print_cr(" ");
   1.584 -}
   1.585 +void MemSummaryDiffReporter::report_diff() {
   1.586 +  const char* scale = current_scale();
   1.587 +  outputStream* out = output();
   1.588 +  out->print_cr("\nNative Memory Tracking:\n");
   1.589  
   1.590 +  // Overall diff
   1.591 +  out->print("Total: ");
   1.592 +  print_virtual_memory_diff(_current_baseline.total_reserved_memory(),
   1.593 +    _current_baseline.total_committed_memory(), _early_baseline.total_reserved_memory(),
   1.594 +    _early_baseline.total_committed_memory());
   1.595  
   1.596 -void BaselineTTYOutputer::start_virtual_memory_map() {
   1.597 -  _output->print_cr("Virtual memory map:");
   1.598 -}
   1.599 +  out->print_cr("\n");
   1.600  
   1.601 -void BaselineTTYOutputer::reserved_memory_region(MEMFLAGS type, address base, address end,
   1.602 -                                                 size_t size, address pc) {
   1.603 -  const char* unit = memory_unit(_scale);
   1.604 -  char buf[128];
   1.605 -  int  offset;
   1.606 -  _output->print_cr(" ");
   1.607 -  _output->print_cr("[" PTR_FORMAT " - " PTR_FORMAT "] reserved %d%s for %s", base, end, size, unit,
   1.608 -            MemBaseline::type2name(type));
   1.609 -  if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) {
   1.610 -      _output->print_cr("\t\tfrom [%s+0x%x]", buf, offset);
   1.611 +  // Summary diff by memory type
   1.612 +  for (int index = 0; index < mt_number_of_types; index ++) {
   1.613 +    MEMFLAGS flag = NMTUtil::index_to_flag(index);
   1.614 +    // thread stack is reported as part of thread category
   1.615 +    if (flag == mtThreadStack) continue;
   1.616 +    diff_summary_of_type(flag, _early_baseline.malloc_memory(flag),
   1.617 +      _early_baseline.virtual_memory(flag), _current_baseline.malloc_memory(flag),
   1.618 +      _current_baseline.virtual_memory(flag));
   1.619    }
   1.620  }
   1.621  
   1.622 -void BaselineTTYOutputer::committed_memory_region(address base, address end, size_t size, address pc) {
   1.623 -  const char* unit = memory_unit(_scale);
   1.624 -  char buf[128];
   1.625 -  int  offset;
   1.626 -  _output->print("\t[" PTR_FORMAT " - " PTR_FORMAT "] committed %d%s", base, end, size, unit);
   1.627 -  if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) {
   1.628 -      _output->print_cr(" from [%s+0x%x]", buf, offset);
   1.629 +void MemSummaryDiffReporter::print_malloc_diff(size_t current_amount, size_t current_count,
   1.630 +    size_t early_amount, size_t early_count) const {
   1.631 +  const char* scale = current_scale();
   1.632 +  outputStream* out = output();
   1.633 +
   1.634 +  out->print("malloc=" SIZE_FORMAT "%s", amount_in_current_scale(current_amount), scale);
   1.635 +  long amount_diff = diff_in_current_scale(current_amount, early_amount);
   1.636 +  if (amount_diff != 0) {
   1.637 +    out->print(" %+ld%s", amount_diff, scale);
   1.638 +  }
   1.639 +  if (current_count > 0) {
   1.640 +    out->print(" #" SIZE_FORMAT "", current_count);
   1.641 +    if (current_count != early_count) {
   1.642 +      out->print(" %+d", (int)(current_count - early_count));
   1.643 +    }
   1.644    }
   1.645  }
   1.646  
   1.647 -void BaselineTTYOutputer::done_virtual_memory_map() {
   1.648 -  _output->print_cr(" ");
   1.649 -}
   1.650 +void MemSummaryDiffReporter::print_arena_diff(size_t current_amount, size_t current_count,
   1.651 +  size_t early_amount, size_t early_count) const {
   1.652 +  const char* scale = current_scale();
   1.653 +  outputStream* out = output();
   1.654 +  out->print("arena=" SIZE_FORMAT "%s", amount_in_current_scale(current_amount), scale);
   1.655 +  if (diff_in_current_scale(current_amount, early_amount) != 0) {
   1.656 +    out->print(" %+ld", diff_in_current_scale(current_amount, early_amount));
   1.657 +  }
   1.658  
   1.659 -
   1.660 -
   1.661 -void BaselineTTYOutputer::start_callsite() {
   1.662 -  _output->print_cr("Details:");
   1.663 -  _output->print_cr(" ");
   1.664 -}
   1.665 -
   1.666 -void BaselineTTYOutputer::done_callsite() {
   1.667 -  _output->print_cr(" ");
   1.668 -}
   1.669 -
   1.670 -void BaselineTTYOutputer::malloc_callsite(address pc, size_t malloc_amt,
   1.671 -  size_t malloc_count) {
   1.672 -  if (malloc_amt > 0) {
   1.673 -    const char* unit = memory_unit(_scale);
   1.674 -    char buf[128];
   1.675 -    int  offset;
   1.676 -    if (pc == 0) {
   1.677 -      _output->print("[BOOTSTRAP]%18s", " ");
   1.678 -    } else if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) {
   1.679 -      _output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset);
   1.680 -      _output->print("%28s", " ");
   1.681 -    } else {
   1.682 -      _output->print("[" PTR_FORMAT "]%18s", pc, " ");
   1.683 -    }
   1.684 -
   1.685 -    _output->print_cr("(malloc=%d%s #%d)", malloc_amt, unit, malloc_count);
   1.686 -    _output->print_cr(" ");
   1.687 +  out->print(" #" SIZE_FORMAT "", current_count);
   1.688 +  if (current_count != early_count) {
   1.689 +    out->print(" %+d", (int)(current_count - early_count));
   1.690    }
   1.691  }
   1.692  
   1.693 -void BaselineTTYOutputer::virtual_memory_callsite(address pc, size_t reserved_amt,
   1.694 -  size_t committed_amt) {
   1.695 -  if (reserved_amt > 0) {
   1.696 -    const char* unit = memory_unit(_scale);
   1.697 -    char buf[128];
   1.698 -    int  offset;
   1.699 -    if (pc == 0) {
   1.700 -      _output->print("[BOOTSTRAP]%18s", " ");
   1.701 -    } else if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) {
   1.702 -      _output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset);
   1.703 -      _output->print("%28s", " ");
   1.704 -    } else {
   1.705 -      _output->print("[" PTR_FORMAT "]%18s", pc, " ");
   1.706 -    }
   1.707 +void MemSummaryDiffReporter::print_virtual_memory_diff(size_t current_reserved, size_t current_committed,
   1.708 +    size_t early_reserved, size_t early_committed) const {
   1.709 +  const char* scale = current_scale();
   1.710 +  outputStream* out = output();
   1.711 +  out->print("reserved=" SIZE_FORMAT "%s", amount_in_current_scale(current_reserved), scale);
   1.712 +  long reserved_diff = diff_in_current_scale(current_reserved, early_reserved);
   1.713 +  if (reserved_diff != 0) {
   1.714 +    out->print(" %+ld%s", reserved_diff, scale);
   1.715 +  }
   1.716  
   1.717 -    _output->print_cr("(mmap: reserved=%d%s, committed=%d%s)",
   1.718 -      reserved_amt, unit, committed_amt, unit);
   1.719 -    _output->print_cr(" ");
   1.720 +  out->print(", committed=" SIZE_FORMAT "%s", amount_in_current_scale(current_committed), scale);
   1.721 +  long committed_diff = diff_in_current_scale(current_committed, early_committed);
   1.722 +  if (committed_diff != 0) {
   1.723 +    out->print(" %+ld%s", committed_diff, scale);
   1.724    }
   1.725  }
   1.726  
   1.727 -void BaselineTTYOutputer::diff_total_usage(size_t total_reserved,
   1.728 -  size_t total_committed, int reserved_diff, int committed_diff) {
   1.729 -  const char* unit = memory_unit(_scale);
   1.730 -  _output->print_cr("Total:  reserved=%d%s  %+d%s, committed=%d%s %+d%s",
   1.731 -    total_reserved, unit, reserved_diff, unit, total_committed, unit,
   1.732 -    committed_diff, unit);
   1.733 -}
   1.734  
   1.735 -void BaselineTTYOutputer::diff_category_summary(MEMFLAGS type,
   1.736 -  size_t cur_reserved_amt, size_t cur_committed_amt,
   1.737 -  size_t cur_malloc_amt, size_t cur_malloc_count,
   1.738 -  size_t cur_arena_amt, size_t cur_arena_count,
   1.739 -  int reserved_diff, int committed_diff, int malloc_diff,
   1.740 -  int malloc_count_diff, int arena_diff, int arena_count_diff) {
   1.741 +void MemSummaryDiffReporter::diff_summary_of_type(MEMFLAGS flag, const MallocMemory* early_malloc,
   1.742 +  const VirtualMemory* early_vm, const MallocMemory* current_malloc,
   1.743 +  const VirtualMemory* current_vm) const {
   1.744  
   1.745 -  if (type == mtThreadStack) {
   1.746 -    assert(cur_malloc_amt == 0 && cur_malloc_count == 0 &&
   1.747 -      cur_arena_amt == 0, "Just check");
   1.748 -    _thread_stack_reserved = cur_reserved_amt;
   1.749 -    _thread_stack_committed = cur_committed_amt;
   1.750 -    _thread_stack_reserved_diff = reserved_diff;
   1.751 -    _thread_stack_committed_diff = committed_diff;
   1.752 -  } else {
   1.753 -    const char* unit = memory_unit(_scale);
   1.754 -    size_t total_reserved = (cur_reserved_amt + cur_malloc_amt + cur_arena_amt);
   1.755 -    // nothing to report in this category
   1.756 -    if (total_reserved == 0) {
   1.757 -      return;
   1.758 -    }
   1.759 -    int    diff_reserved = (reserved_diff + malloc_diff + arena_diff);
   1.760 +  outputStream* out = output();
   1.761 +  const char* scale = current_scale();
   1.762  
   1.763 -    // category summary
   1.764 -    _output->print("-%26s (reserved=%d%s", MemBaseline::type2name(type),
   1.765 -      total_reserved, unit);
   1.766 +  // Total reserved and committed memory in current baseline
   1.767 +  size_t current_reserved_amount  = reserved_total (current_malloc, current_vm);
   1.768 +  size_t current_committed_amount = committed_total(current_malloc, current_vm);
   1.769  
   1.770 -    if (diff_reserved != 0) {
   1.771 -      _output->print(" %+d%s", diff_reserved, unit);
   1.772 +  // Total reserved and committed memory in early baseline
   1.773 +  size_t early_reserved_amount  = reserved_total(early_malloc, early_vm);
   1.774 +  size_t early_committed_amount = committed_total(early_malloc, early_vm);
   1.775 +
   1.776 +  // Adjust virtual memory total
   1.777 +  if (flag == mtThread) {
   1.778 +    const VirtualMemory* early_thread_stack_usage =
   1.779 +      _early_baseline.virtual_memory(mtThreadStack);
   1.780 +    const VirtualMemory* current_thread_stack_usage =
   1.781 +      _current_baseline.virtual_memory(mtThreadStack);
   1.782 +
   1.783 +    early_reserved_amount  += early_thread_stack_usage->reserved();
   1.784 +    early_committed_amount += early_thread_stack_usage->committed();
   1.785 +
   1.786 +    current_reserved_amount  += current_thread_stack_usage->reserved();
   1.787 +    current_committed_amount += current_thread_stack_usage->committed();
   1.788 +  } else if (flag == mtNMT) {
   1.789 +    early_reserved_amount  += _early_baseline.malloc_tracking_overhead();
   1.790 +    early_committed_amount += _early_baseline.malloc_tracking_overhead();
   1.791 +
   1.792 +    current_reserved_amount  += _current_baseline.malloc_tracking_overhead();
   1.793 +    current_committed_amount += _current_baseline.malloc_tracking_overhead();
   1.794 +  }
   1.795 +
   1.796 +  if (amount_in_current_scale(current_reserved_amount) > 0 ||
   1.797 +      diff_in_current_scale(current_reserved_amount, early_reserved_amount) != 0) {
   1.798 +
   1.799 +    // print summary line
   1.800 +    out->print("-%26s (", NMTUtil::flag_to_name(flag));
   1.801 +    print_virtual_memory_diff(current_reserved_amount, current_committed_amount,
   1.802 +      early_reserved_amount, early_committed_amount);
   1.803 +    out->print_cr(")");
   1.804 +
   1.805 +    // detail lines
   1.806 +    if (flag == mtClass) {
   1.807 +      // report class count
   1.808 +      out->print("%27s (classes #" SIZE_FORMAT "", " ", _current_baseline.class_count());
   1.809 +      int class_count_diff = (int)(_current_baseline.class_count() -
   1.810 +        _early_baseline.class_count());
   1.811 +      if (_current_baseline.class_count() != _early_baseline.class_count()) {
   1.812 +        out->print(" %+d", (int)(_current_baseline.class_count() - _early_baseline.class_count()));
   1.813 +      }
   1.814 +      out->print_cr(")");
   1.815 +    } else if (flag == mtThread) {
   1.816 +      // report thread count
   1.817 +      out->print("%27s (thread #" SIZE_FORMAT "", " ", _current_baseline.thread_count());
   1.818 +      int thread_count_diff = (int)(_current_baseline.thread_count() -
   1.819 +          _early_baseline.thread_count());
   1.820 +      if (thread_count_diff != 0) {
   1.821 +        out->print(" %+d", thread_count_diff);
   1.822 +      }
   1.823 +      out->print_cr(")");
   1.824 +
   1.825 +      // report thread stack
   1.826 +      const VirtualMemory* current_thread_stack =
   1.827 +          _current_baseline.virtual_memory(mtThreadStack);
   1.828 +      const VirtualMemory* early_thread_stack =
   1.829 +        _early_baseline.virtual_memory(mtThreadStack);
   1.830 +
   1.831 +      out->print("%27s (stack: ", " ");
   1.832 +      print_virtual_memory_diff(current_thread_stack->reserved(), current_thread_stack->committed(),
   1.833 +        early_thread_stack->reserved(), early_thread_stack->committed());
   1.834 +      out->print_cr(")");
   1.835      }
   1.836  
   1.837 -    size_t total_committed = cur_committed_amt + cur_malloc_amt + cur_arena_amt;
   1.838 -    _output->print(", committed=%d%s", total_committed, unit);
   1.839 -
   1.840 -    int total_committed_diff = committed_diff + malloc_diff + arena_diff;
   1.841 -    if (total_committed_diff != 0) {
   1.842 -      _output->print(" %+d%s", total_committed_diff, unit);
   1.843 +    // Report malloc'd memory
   1.844 +    size_t current_malloc_amount = current_malloc->malloc_size();
   1.845 +    size_t early_malloc_amount   = early_malloc->malloc_size();
   1.846 +    if (amount_in_current_scale(current_malloc_amount) > 0 ||
   1.847 +        diff_in_current_scale(current_malloc_amount, early_malloc_amount) != 0) {
   1.848 +      out->print("%28s(", " ");
   1.849 +      print_malloc_diff(current_malloc_amount, (flag == mtChunk) ? 0 : current_malloc->malloc_count(),
   1.850 +        early_malloc_amount, early_malloc->malloc_count());
   1.851 +      out->print_cr(")");
   1.852      }
   1.853  
   1.854 -    _output->print_cr(")");
   1.855 -
   1.856 -    // special cases
   1.857 -    if (type == mtClass) {
   1.858 -      _output->print("%27s (classes #%d", " ", _num_of_classes);
   1.859 -      if (_num_of_classes_diff != 0) {
   1.860 -        _output->print(" %+d", _num_of_classes_diff);
   1.861 -      }
   1.862 -      _output->print_cr(")");
   1.863 -    } else if (type == mtThread) {
   1.864 -      // thread count
   1.865 -      _output->print("%27s (thread #%d", " ", _num_of_threads);
   1.866 -      if (_num_of_threads_diff != 0) {
   1.867 -        _output->print_cr(" %+d)", _num_of_threads_diff);
   1.868 -      } else {
   1.869 -        _output->print_cr(")");
   1.870 -      }
   1.871 -      _output->print("%27s (stack: reserved=%d%s", " ", _thread_stack_reserved, unit);
   1.872 -      if (_thread_stack_reserved_diff != 0) {
   1.873 -        _output->print(" %+d%s", _thread_stack_reserved_diff, unit);
   1.874 -      }
   1.875 -
   1.876 -      _output->print(", committed=%d%s", _thread_stack_committed, unit);
   1.877 -      if (_thread_stack_committed_diff != 0) {
   1.878 -        _output->print(" %+d%s",_thread_stack_committed_diff, unit);
   1.879 -      }
   1.880 -
   1.881 -      _output->print_cr(")");
   1.882 +    // Report virtual memory
   1.883 +    if (amount_in_current_scale(current_vm->reserved()) > 0 ||
   1.884 +        diff_in_current_scale(current_vm->reserved(), early_vm->reserved()) != 0) {
   1.885 +      out->print("%27s (mmap: ", " ");
   1.886 +      print_virtual_memory_diff(current_vm->reserved(), current_vm->committed(),
   1.887 +        early_vm->reserved(), early_vm->committed());
   1.888 +      out->print_cr(")");
   1.889      }
   1.890  
   1.891 -    // malloc'd memory
   1.892 -    if (cur_malloc_amt > 0) {
   1.893 -      _output->print("%27s (malloc=%d%s", " ", cur_malloc_amt, unit);
   1.894 -      if (malloc_diff != 0) {
   1.895 -        _output->print(" %+d%s", malloc_diff, unit);
   1.896 -      }
   1.897 -      if (type != mtChunk) {
   1.898 -        _output->print(", #%d", cur_malloc_count);
   1.899 -        if (malloc_count_diff) {
   1.900 -          _output->print(" %+d", malloc_count_diff);
   1.901 -        }
   1.902 -      }
   1.903 -      _output->print_cr(")");
   1.904 +    // Report arena memory
   1.905 +    if (amount_in_current_scale(current_malloc->arena_size()) > 0 ||
   1.906 +        diff_in_current_scale(current_malloc->arena_size(), early_malloc->arena_size()) != 0) {
   1.907 +      out->print("%28s(", " ");
   1.908 +      print_arena_diff(current_malloc->arena_size(), current_malloc->arena_count(),
   1.909 +        early_malloc->arena_size(), early_malloc->arena_count());
   1.910 +      out->print_cr(")");
   1.911      }
   1.912  
   1.913 -    // mmap'd memory
   1.914 -    if (cur_reserved_amt > 0) {
   1.915 -      _output->print("%27s (mmap: reserved=%d%s", " ", cur_reserved_amt, unit);
   1.916 -      if (reserved_diff != 0) {
   1.917 -        _output->print(" %+d%s", reserved_diff, unit);
   1.918 +    // Report native memory tracking overhead
   1.919 +    if (flag == mtNMT) {
   1.920 +      size_t current_tracking_overhead = amount_in_current_scale(_current_baseline.malloc_tracking_overhead());
   1.921 +      size_t early_tracking_overhead   = amount_in_current_scale(_early_baseline.malloc_tracking_overhead());
   1.922 +
   1.923 +      out->print("%27s (tracking overhead=" SIZE_FORMAT "%s", " ",
   1.924 +        amount_in_current_scale(_current_baseline.malloc_tracking_overhead()), scale);
   1.925 +
   1.926 +      long overhead_diff = diff_in_current_scale(_current_baseline.malloc_tracking_overhead(),
   1.927 +           _early_baseline.malloc_tracking_overhead());
   1.928 +      if (overhead_diff != 0) {
   1.929 +        out->print(" %+ld%s", overhead_diff, scale);
   1.930        }
   1.931 -
   1.932 -      _output->print(", committed=%d%s", cur_committed_amt, unit);
   1.933 -      if (committed_diff != 0) {
   1.934 -        _output->print(" %+d%s", committed_diff, unit);
   1.935 -      }
   1.936 -      _output->print_cr(")");
   1.937 +      out->print_cr(")");
   1.938      }
   1.939 -
   1.940 -    // arena memory
   1.941 -    if (cur_arena_amt > 0) {
   1.942 -      _output->print("%27s (arena=%d%s", " ", cur_arena_amt, unit);
   1.943 -      if (arena_diff != 0) {
   1.944 -        _output->print(" %+d%s", arena_diff, unit);
   1.945 -      }
   1.946 -      _output->print(", #%d", cur_arena_count);
   1.947 -      if (arena_count_diff != 0) {
   1.948 -        _output->print(" %+d", arena_count_diff);
   1.949 -      }
   1.950 -      _output->print_cr(")");
   1.951 -    }
   1.952 -
   1.953 -    _output->print_cr(" ");
   1.954 +    out->print_cr(" ");
   1.955    }
   1.956  }
   1.957  
   1.958 -void BaselineTTYOutputer::diff_malloc_callsite(address pc,
   1.959 -    size_t cur_malloc_amt, size_t cur_malloc_count,
   1.960 -    int malloc_diff, int malloc_count_diff) {
   1.961 -  if (malloc_diff != 0) {
   1.962 -    const char* unit = memory_unit(_scale);
   1.963 -    char buf[128];
   1.964 -    int  offset;
   1.965 -    if (pc == 0) {
   1.966 -      _output->print_cr("[BOOTSTRAP]%18s", " ");
   1.967 +void MemDetailDiffReporter::report_diff() {
   1.968 +  MemSummaryDiffReporter::report_diff();
   1.969 +  diff_malloc_sites();
   1.970 +  diff_virtual_memory_sites();
   1.971 +}
   1.972 +
   1.973 +void MemDetailDiffReporter::diff_malloc_sites() const {
   1.974 +  MallocSiteIterator early_itr = _early_baseline.malloc_sites(MemBaseline::by_site);
   1.975 +  MallocSiteIterator current_itr = _current_baseline.malloc_sites(MemBaseline::by_site);
   1.976 +
   1.977 +  const MallocSite* early_site   = early_itr.next();
   1.978 +  const MallocSite* current_site = current_itr.next();
   1.979 +
   1.980 +  while (early_site != NULL || current_site != NULL) {
   1.981 +    if (early_site == NULL) {
   1.982 +      new_malloc_site(current_site);
   1.983 +      current_site = current_itr.next();
   1.984 +    } else if (current_site == NULL) {
   1.985 +      old_malloc_site(early_site);
   1.986 +      early_site = early_itr.next();
   1.987      } else {
   1.988 -      if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) {
   1.989 -        _output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset);
   1.990 -        _output->print("%28s", " ");
   1.991 +      int compVal = current_site->call_stack()->compare(*early_site->call_stack());
   1.992 +      if (compVal < 0) {
   1.993 +        new_malloc_site(current_site);
   1.994 +        current_site = current_itr.next();
   1.995 +      } else if (compVal > 0) {
   1.996 +        old_malloc_site(early_site);
   1.997 +        early_site = early_itr.next();
   1.998        } else {
   1.999 -        _output->print("[" PTR_FORMAT "]%18s", pc, " ");
  1.1000 +        diff_malloc_site(early_site, current_site);
  1.1001 +        early_site   = early_itr.next();
  1.1002 +        current_site = current_itr.next();
  1.1003        }
  1.1004      }
  1.1005 -
  1.1006 -    _output->print("(malloc=%d%s", cur_malloc_amt, unit);
  1.1007 -    if (malloc_diff != 0) {
  1.1008 -      _output->print(" %+d%s", malloc_diff, unit);
  1.1009 -    }
  1.1010 -    _output->print(", #%d", cur_malloc_count);
  1.1011 -    if (malloc_count_diff != 0) {
  1.1012 -      _output->print(" %+d", malloc_count_diff);
  1.1013 -    }
  1.1014 -    _output->print_cr(")");
  1.1015 -    _output->print_cr(" ");
  1.1016    }
  1.1017  }
  1.1018  
  1.1019 -void BaselineTTYOutputer::diff_virtual_memory_callsite(address pc,
  1.1020 -    size_t cur_reserved_amt, size_t cur_committed_amt,
  1.1021 -    int reserved_diff, int committed_diff) {
  1.1022 -  if (reserved_diff != 0 || committed_diff != 0) {
  1.1023 -    const char* unit = memory_unit(_scale);
  1.1024 -    char buf[64];
  1.1025 -    int  offset;
  1.1026 -    if (pc == 0) {
  1.1027 -      _output->print_cr("[BOOSTRAP]%18s", " ");
  1.1028 +void MemDetailDiffReporter::diff_virtual_memory_sites() const {
  1.1029 +  VirtualMemorySiteIterator early_itr = _early_baseline.virtual_memory_sites(MemBaseline::by_site);
  1.1030 +  VirtualMemorySiteIterator current_itr = _current_baseline.virtual_memory_sites(MemBaseline::by_site);
  1.1031 +
  1.1032 +  const VirtualMemoryAllocationSite* early_site   = early_itr.next();
  1.1033 +  const VirtualMemoryAllocationSite* current_site = current_itr.next();
  1.1034 +
  1.1035 +  while (early_site != NULL || current_site != NULL) {
  1.1036 +    if (early_site == NULL) {
  1.1037 +      new_virtual_memory_site(current_site);
  1.1038 +      current_site = current_itr.next();
  1.1039 +    } else if (current_site == NULL) {
  1.1040 +      old_virtual_memory_site(early_site);
  1.1041 +      early_site = early_itr.next();
  1.1042      } else {
  1.1043 -      if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) {
  1.1044 -        _output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset);
  1.1045 -        _output->print("%28s", " ");
  1.1046 +      int compVal = current_site->call_stack()->compare(*early_site->call_stack());
  1.1047 +      if (compVal < 0) {
  1.1048 +        new_virtual_memory_site(current_site);
  1.1049 +        current_site = current_itr.next();
  1.1050 +      } else if (compVal > 0) {
  1.1051 +        old_virtual_memory_site(early_site);
  1.1052 +        early_site = early_itr.next();
  1.1053        } else {
  1.1054 -        _output->print("[" PTR_FORMAT "]%18s", pc, " ");
  1.1055 +        diff_virtual_memory_site(early_site, current_site);
  1.1056 +        early_site   = early_itr.next();
  1.1057 +        current_site = current_itr.next();
  1.1058        }
  1.1059      }
  1.1060 -
  1.1061 -    _output->print("(mmap: reserved=%d%s", cur_reserved_amt, unit);
  1.1062 -    if (reserved_diff != 0) {
  1.1063 -      _output->print(" %+d%s", reserved_diff, unit);
  1.1064 -    }
  1.1065 -    _output->print(", committed=%d%s", cur_committed_amt, unit);
  1.1066 -    if (committed_diff != 0) {
  1.1067 -      _output->print(" %+d%s", committed_diff, unit);
  1.1068 -    }
  1.1069 -    _output->print_cr(")");
  1.1070 -    _output->print_cr(" ");
  1.1071    }
  1.1072  }
  1.1073 +
  1.1074 +
  1.1075 +void MemDetailDiffReporter::new_malloc_site(const MallocSite* malloc_site) const {
  1.1076 +  diff_malloc_site(malloc_site->call_stack(), malloc_site->size(), malloc_site->count(),
  1.1077 +    0, 0);
  1.1078 +}
  1.1079 +
  1.1080 +void MemDetailDiffReporter::old_malloc_site(const MallocSite* malloc_site) const {
  1.1081 +  diff_malloc_site(malloc_site->call_stack(), 0, 0, malloc_site->size(),
  1.1082 +    malloc_site->count());
  1.1083 +}
  1.1084 +
  1.1085 +void MemDetailDiffReporter::diff_malloc_site(const MallocSite* early,
  1.1086 +  const MallocSite* current)  const {
  1.1087 +  diff_malloc_site(current->call_stack(), current->size(), current->count(),
  1.1088 +    early->size(), early->count());
  1.1089 +}
  1.1090 +
  1.1091 +void MemDetailDiffReporter::diff_malloc_site(const NativeCallStack* stack, size_t current_size,
  1.1092 +  size_t current_count, size_t early_size, size_t early_count) const {
  1.1093 +  outputStream* out = output();
  1.1094 +
  1.1095 +  assert(stack != NULL, "NULL stack");
  1.1096 +
  1.1097 +  if (diff_in_current_scale(current_size, early_size) == 0) {
  1.1098 +      return;
  1.1099 +  }
  1.1100 +
  1.1101 +  stack->print_on(out);
  1.1102 +  out->print("%28s (", " ");
  1.1103 +  print_malloc_diff(current_size, current_count,
  1.1104 +    early_size, early_count);
  1.1105 +
  1.1106 +  out->print_cr(")\n");
  1.1107 +}
  1.1108 +
  1.1109 +
  1.1110 +void MemDetailDiffReporter::new_virtual_memory_site(const VirtualMemoryAllocationSite* site) const {
  1.1111 +  diff_virtual_memory_site(site->call_stack(), site->reserved(), site->committed(), 0, 0);
  1.1112 +}
  1.1113 +
  1.1114 +void MemDetailDiffReporter::old_virtual_memory_site(const VirtualMemoryAllocationSite* site) const {
  1.1115 +  diff_virtual_memory_site(site->call_stack(), 0, 0, site->reserved(), site->committed());
  1.1116 +}
  1.1117 +
  1.1118 +void MemDetailDiffReporter::diff_virtual_memory_site(const VirtualMemoryAllocationSite* early,
  1.1119 +  const VirtualMemoryAllocationSite* current) const {
  1.1120 +  diff_virtual_memory_site(current->call_stack(), current->reserved(), current->committed(),
  1.1121 +    early->reserved(), early->committed());
  1.1122 +}
  1.1123 +
  1.1124 +void MemDetailDiffReporter::diff_virtual_memory_site(const NativeCallStack* stack, size_t current_reserved,
  1.1125 +  size_t current_committed, size_t early_reserved, size_t early_committed) const  {
  1.1126 +  outputStream* out = output();
  1.1127 +
  1.1128 +  // no change
  1.1129 +  if (diff_in_current_scale(current_reserved, early_reserved) == 0 &&
  1.1130 +      diff_in_current_scale(current_committed, early_committed) == 0) {
  1.1131 +    return;
  1.1132 +  }
  1.1133 +
  1.1134 +  stack->print_on(out);
  1.1135 +  out->print("%28s (mmap: ", " ");
  1.1136 +  print_virtual_memory_diff(current_reserved, current_committed,
  1.1137 +    early_reserved, early_committed);
  1.1138 +
  1.1139 +  out->print_cr(")\n");
  1.1140 + }
  1.1141 +

mercurial