src/share/vm/services/memSnapshot.cpp

changeset 7074
833b0f92429a
parent 7073
4d3a43351904
child 7075
ac12996df59b
     1.1 --- a/src/share/vm/services/memSnapshot.cpp	Wed Aug 27 09:36:55 2014 +0200
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,748 +0,0 @@
     1.4 -/*
     1.5 - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
     1.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 - *
     1.8 - * This code is free software; you can redistribute it and/or modify it
     1.9 - * under the terms of the GNU General Public License version 2 only, as
    1.10 - * published by the Free Software Foundation.
    1.11 - *
    1.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 - * version 2 for more details (a copy is included in the LICENSE file that
    1.16 - * accompanied this code).
    1.17 - *
    1.18 - * You should have received a copy of the GNU General Public License version
    1.19 - * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 - *
    1.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.23 - * or visit www.oracle.com if you need additional information or have any
    1.24 - * questions.
    1.25 - *
    1.26 - */
    1.27 -
    1.28 -#include "precompiled.hpp"
    1.29 -#include "runtime/mutexLocker.hpp"
    1.30 -#include "utilities/decoder.hpp"
    1.31 -#include "services/memBaseline.hpp"
    1.32 -#include "services/memPtr.hpp"
    1.33 -#include "services/memPtrArray.hpp"
    1.34 -#include "services/memSnapshot.hpp"
    1.35 -#include "services/memTracker.hpp"
    1.36 -
    1.37 -PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
    1.38 -
    1.39 -#ifdef ASSERT
    1.40 -
    1.41 -void decode_pointer_record(MemPointerRecord* rec) {
    1.42 -  tty->print("Pointer: [" PTR_FORMAT " - " PTR_FORMAT  "] size = %d bytes", rec->addr(),
    1.43 -    rec->addr() + rec->size(), (int)rec->size());
    1.44 -  tty->print(" type = %s", MemBaseline::type2name(FLAGS_TO_MEMORY_TYPE(rec->flags())));
    1.45 -  if (rec->is_vm_pointer()) {
    1.46 -    if (rec->is_allocation_record()) {
    1.47 -      tty->print_cr(" (reserve)");
    1.48 -    } else if (rec->is_commit_record()) {
    1.49 -      tty->print_cr(" (commit)");
    1.50 -    } else if (rec->is_uncommit_record()) {
    1.51 -      tty->print_cr(" (uncommit)");
    1.52 -    } else if (rec->is_deallocation_record()) {
    1.53 -      tty->print_cr(" (release)");
    1.54 -    } else {
    1.55 -      tty->print_cr(" (tag)");
    1.56 -    }
    1.57 -  } else {
    1.58 -    if (rec->is_arena_memory_record()) {
    1.59 -      tty->print_cr(" (arena size)");
    1.60 -    } else if (rec->is_allocation_record()) {
    1.61 -      tty->print_cr(" (malloc)");
    1.62 -    } else {
    1.63 -      tty->print_cr(" (free)");
    1.64 -    }
    1.65 -  }
    1.66 -  if (MemTracker::track_callsite()) {
    1.67 -    char buf[1024];
    1.68 -    address pc = ((MemPointerRecordEx*)rec)->pc();
    1.69 -    if (pc != NULL && os::dll_address_to_function_name(pc, buf, sizeof(buf), NULL)) {
    1.70 -      tty->print_cr("\tfrom %s", buf);
    1.71 -    } else {
    1.72 -      tty->print_cr("\tcould not decode pc = " PTR_FORMAT "", pc);
    1.73 -    }
    1.74 -  }
    1.75 -}
    1.76 -
    1.77 -void decode_vm_region_record(VMMemRegion* rec) {
    1.78 -  tty->print("VM Region [" PTR_FORMAT " - " PTR_FORMAT "]", rec->addr(),
    1.79 -    rec->addr() + rec->size());
    1.80 -  tty->print(" type = %s", MemBaseline::type2name(FLAGS_TO_MEMORY_TYPE(rec->flags())));
    1.81 -  if (rec->is_allocation_record()) {
    1.82 -    tty->print_cr(" (reserved)");
    1.83 -  } else if (rec->is_commit_record()) {
    1.84 -    tty->print_cr(" (committed)");
    1.85 -  } else {
    1.86 -    ShouldNotReachHere();
    1.87 -  }
    1.88 -  if (MemTracker::track_callsite()) {
    1.89 -    char buf[1024];
    1.90 -    address pc = ((VMMemRegionEx*)rec)->pc();
    1.91 -    if (pc != NULL && os::dll_address_to_function_name(pc, buf, sizeof(buf), NULL)) {
    1.92 -      tty->print_cr("\tfrom %s", buf);
    1.93 -    } else {
    1.94 -      tty->print_cr("\tcould not decode pc = " PTR_FORMAT "", pc);
    1.95 -    }
    1.96 -
    1.97 -  }
    1.98 -}
    1.99 -
   1.100 -#endif
   1.101 -
   1.102 -
   1.103 -bool VMMemPointerIterator::insert_record(MemPointerRecord* rec) {
   1.104 -  VMMemRegionEx new_rec;
   1.105 -  assert(rec->is_allocation_record() || rec->is_commit_record(),
   1.106 -    "Sanity check");
   1.107 -  if (MemTracker::track_callsite()) {
   1.108 -    new_rec.init((MemPointerRecordEx*)rec);
   1.109 -  } else {
   1.110 -    new_rec.init(rec);
   1.111 -  }
   1.112 -  return insert(&new_rec);
   1.113 -}
   1.114 -
   1.115 -bool VMMemPointerIterator::insert_record_after(MemPointerRecord* rec) {
   1.116 -  VMMemRegionEx new_rec;
   1.117 -  assert(rec->is_allocation_record() || rec->is_commit_record(),
   1.118 -    "Sanity check");
   1.119 -  if (MemTracker::track_callsite()) {
   1.120 -    new_rec.init((MemPointerRecordEx*)rec);
   1.121 -  } else {
   1.122 -    new_rec.init(rec);
   1.123 -  }
   1.124 -  return insert_after(&new_rec);
   1.125 -}
   1.126 -
   1.127 -// we don't consolidate reserved regions, since they may be categorized
   1.128 -// in different types.
   1.129 -bool VMMemPointerIterator::add_reserved_region(MemPointerRecord* rec) {
   1.130 -  assert(rec->is_allocation_record(), "Sanity check");
   1.131 -  VMMemRegion* reserved_region = (VMMemRegion*)current();
   1.132 -
   1.133 -  // we don't have anything yet
   1.134 -  if (reserved_region == NULL) {
   1.135 -    return insert_record(rec);
   1.136 -  }
   1.137 -
   1.138 -  assert(reserved_region->is_reserved_region(), "Sanity check");
   1.139 -  // duplicated records
   1.140 -  if (reserved_region->is_same_region(rec)) {
   1.141 -    return true;
   1.142 -  }
   1.143 -  // Overlapping stack regions indicate that a JNI thread failed to
   1.144 -  // detach from the VM before exiting. This leaks the JavaThread object.
   1.145 -  if (CheckJNICalls)  {
   1.146 -      guarantee(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) != mtThreadStack ||
   1.147 -         !reserved_region->overlaps_region(rec),
   1.148 -         "Attached JNI thread exited without being detached");
   1.149 -  }
   1.150 -  // otherwise, we should not have overlapping reserved regions
   1.151 -  assert(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) == mtThreadStack ||
   1.152 -    reserved_region->base() > rec->addr(), "Just check: locate()");
   1.153 -  assert(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) == mtThreadStack ||
   1.154 -    !reserved_region->overlaps_region(rec), "overlapping reserved regions");
   1.155 -
   1.156 -  return insert_record(rec);
   1.157 -}
   1.158 -
   1.159 -// we do consolidate committed regions
   1.160 -bool VMMemPointerIterator::add_committed_region(MemPointerRecord* rec) {
   1.161 -  assert(rec->is_commit_record(), "Sanity check");
   1.162 -  VMMemRegion* reserved_rgn = (VMMemRegion*)current();
   1.163 -  assert(reserved_rgn->is_reserved_region() && reserved_rgn->contains_region(rec),
   1.164 -    "Sanity check");
   1.165 -
   1.166 -  // thread's native stack is always marked as "committed", ignore
   1.167 -  // the "commit" operation for creating stack guard pages
   1.168 -  if (FLAGS_TO_MEMORY_TYPE(reserved_rgn->flags()) == mtThreadStack &&
   1.169 -      FLAGS_TO_MEMORY_TYPE(rec->flags()) != mtThreadStack) {
   1.170 -    return true;
   1.171 -  }
   1.172 -
   1.173 -  // if the reserved region has any committed regions
   1.174 -  VMMemRegion* committed_rgn  = (VMMemRegion*)next();
   1.175 -  while (committed_rgn != NULL && committed_rgn->is_committed_region()) {
   1.176 -    // duplicated commit records
   1.177 -    if(committed_rgn->contains_region(rec)) {
   1.178 -      return true;
   1.179 -    } else if (committed_rgn->overlaps_region(rec)) {
   1.180 -      // overlaps front part
   1.181 -      if (rec->addr() < committed_rgn->addr()) {
   1.182 -        committed_rgn->expand_region(rec->addr(),
   1.183 -          committed_rgn->addr() - rec->addr());
   1.184 -      } else {
   1.185 -        // overlaps tail part
   1.186 -        address committed_rgn_end = committed_rgn->addr() +
   1.187 -              committed_rgn->size();
   1.188 -        assert(committed_rgn_end < rec->addr() + rec->size(),
   1.189 -             "overlap tail part");
   1.190 -        committed_rgn->expand_region(committed_rgn_end,
   1.191 -          (rec->addr() + rec->size()) - committed_rgn_end);
   1.192 -      }
   1.193 -    } else if (committed_rgn->base() + committed_rgn->size() == rec->addr()) {
   1.194 -      // adjunct each other
   1.195 -      committed_rgn->expand_region(rec->addr(), rec->size());
   1.196 -      VMMemRegion* next_reg = (VMMemRegion*)next();
   1.197 -      // see if we can consolidate next committed region
   1.198 -      if (next_reg != NULL && next_reg->is_committed_region() &&
   1.199 -        next_reg->base() == committed_rgn->base() + committed_rgn->size()) {
   1.200 -          committed_rgn->expand_region(next_reg->base(), next_reg->size());
   1.201 -          // delete merged region
   1.202 -          remove();
   1.203 -      }
   1.204 -      return true;
   1.205 -    } else if (committed_rgn->base() > rec->addr()) {
   1.206 -      // found the location, insert this committed region
   1.207 -      return insert_record(rec);
   1.208 -    }
   1.209 -    committed_rgn = (VMMemRegion*)next();
   1.210 -  }
   1.211 -  return insert_record(rec);
   1.212 -}
   1.213 -
   1.214 -bool VMMemPointerIterator::remove_uncommitted_region(MemPointerRecord* rec) {
   1.215 -  assert(rec->is_uncommit_record(), "sanity check");
   1.216 -  VMMemRegion* cur;
   1.217 -  cur = (VMMemRegion*)current();
   1.218 -  assert(cur->is_reserved_region() && cur->contains_region(rec),
   1.219 -    "Sanity check");
   1.220 -  // thread's native stack is always marked as "committed", ignore
   1.221 -  // the "commit" operation for creating stack guard pages
   1.222 -  if (FLAGS_TO_MEMORY_TYPE(cur->flags()) == mtThreadStack &&
   1.223 -      FLAGS_TO_MEMORY_TYPE(rec->flags()) != mtThreadStack) {
   1.224 -    return true;
   1.225 -  }
   1.226 -
   1.227 -  cur = (VMMemRegion*)next();
   1.228 -  while (cur != NULL && cur->is_committed_region()) {
   1.229 -    // region already uncommitted, must be due to duplicated record
   1.230 -    if (cur->addr() >= rec->addr() + rec->size()) {
   1.231 -      break;
   1.232 -    } else if (cur->contains_region(rec)) {
   1.233 -      // uncommit whole region
   1.234 -      if (cur->is_same_region(rec)) {
   1.235 -        remove();
   1.236 -        break;
   1.237 -      } else if (rec->addr() == cur->addr() ||
   1.238 -        rec->addr() + rec->size() == cur->addr() + cur->size()) {
   1.239 -        // uncommitted from either end of current memory region.
   1.240 -        cur->exclude_region(rec->addr(), rec->size());
   1.241 -        break;
   1.242 -      } else { // split the committed region and release the middle
   1.243 -        address high_addr = cur->addr() + cur->size();
   1.244 -        size_t sz = high_addr - rec->addr();
   1.245 -        cur->exclude_region(rec->addr(), sz);
   1.246 -        sz = high_addr - (rec->addr() + rec->size());
   1.247 -        if (MemTracker::track_callsite()) {
   1.248 -          MemPointerRecordEx tmp(rec->addr() + rec->size(), cur->flags(), sz,
   1.249 -             ((VMMemRegionEx*)cur)->pc());
   1.250 -          return insert_record_after(&tmp);
   1.251 -        } else {
   1.252 -          MemPointerRecord tmp(rec->addr() + rec->size(), cur->flags(), sz);
   1.253 -          return insert_record_after(&tmp);
   1.254 -        }
   1.255 -      }
   1.256 -    }
   1.257 -    cur = (VMMemRegion*)next();
   1.258 -  }
   1.259 -
   1.260 -  // we may not find committed record due to duplicated records
   1.261 -  return true;
   1.262 -}
   1.263 -
   1.264 -bool VMMemPointerIterator::remove_released_region(MemPointerRecord* rec) {
   1.265 -  assert(rec->is_deallocation_record(), "Sanity check");
   1.266 -  VMMemRegion* cur = (VMMemRegion*)current();
   1.267 -  assert(cur->is_reserved_region() && cur->contains_region(rec),
   1.268 -    "Sanity check");
   1.269 -  if (rec->is_same_region(cur)) {
   1.270 -
   1.271 -    // In snapshot, the virtual memory records are sorted in following orders:
   1.272 -    // 1. virtual memory's base address
   1.273 -    // 2. virtual memory reservation record, followed by commit records within this reservation.
   1.274 -    //    The commit records are also in base address order.
   1.275 -    // When a reserved region is released, we want to remove the reservation record and all
   1.276 -    // commit records following it.
   1.277 -#ifdef ASSERT
   1.278 -    address low_addr = cur->addr();
   1.279 -    address high_addr = low_addr + cur->size();
   1.280 -#endif
   1.281 -    // remove virtual memory reservation record
   1.282 -    remove();
   1.283 -    // remove committed regions within above reservation
   1.284 -    VMMemRegion* next_region = (VMMemRegion*)current();
   1.285 -    while (next_region != NULL && next_region->is_committed_region()) {
   1.286 -      assert(next_region->addr() >= low_addr &&
   1.287 -             next_region->addr() + next_region->size() <= high_addr,
   1.288 -            "Range check");
   1.289 -      remove();
   1.290 -      next_region = (VMMemRegion*)current();
   1.291 -    }
   1.292 -  } else if (rec->addr() == cur->addr() ||
   1.293 -    rec->addr() + rec->size() == cur->addr() + cur->size()) {
   1.294 -    // released region is at either end of this region
   1.295 -    cur->exclude_region(rec->addr(), rec->size());
   1.296 -    assert(check_reserved_region(), "Integrity check");
   1.297 -  } else { // split the reserved region and release the middle
   1.298 -    address high_addr = cur->addr() + cur->size();
   1.299 -    size_t sz = high_addr - rec->addr();
   1.300 -    cur->exclude_region(rec->addr(), sz);
   1.301 -    sz = high_addr - rec->addr() - rec->size();
   1.302 -    if (MemTracker::track_callsite()) {
   1.303 -      MemPointerRecordEx tmp(rec->addr() + rec->size(), cur->flags(), sz,
   1.304 -        ((VMMemRegionEx*)cur)->pc());
   1.305 -      bool ret = insert_reserved_region(&tmp);
   1.306 -      assert(!ret || check_reserved_region(), "Integrity check");
   1.307 -      return ret;
   1.308 -    } else {
   1.309 -      MemPointerRecord tmp(rec->addr() + rec->size(), cur->flags(), sz);
   1.310 -      bool ret = insert_reserved_region(&tmp);
   1.311 -      assert(!ret || check_reserved_region(), "Integrity check");
   1.312 -      return ret;
   1.313 -    }
   1.314 -  }
   1.315 -  return true;
   1.316 -}
   1.317 -
   1.318 -bool VMMemPointerIterator::insert_reserved_region(MemPointerRecord* rec) {
   1.319 -  // skip all 'commit' records associated with previous reserved region
   1.320 -  VMMemRegion* p = (VMMemRegion*)next();
   1.321 -  while (p != NULL && p->is_committed_region() &&
   1.322 -         p->base() + p->size() < rec->addr()) {
   1.323 -    p = (VMMemRegion*)next();
   1.324 -  }
   1.325 -  return insert_record(rec);
   1.326 -}
   1.327 -
   1.328 -bool VMMemPointerIterator::split_reserved_region(VMMemRegion* rgn, address new_rgn_addr, size_t new_rgn_size) {
   1.329 -  assert(rgn->contains_region(new_rgn_addr, new_rgn_size), "Not fully contained");
   1.330 -  address pc = (MemTracker::track_callsite() ? ((VMMemRegionEx*)rgn)->pc() : NULL);
   1.331 -  if (rgn->base() == new_rgn_addr) { // new region is at the beginning of the region
   1.332 -    size_t sz = rgn->size() - new_rgn_size;
   1.333 -    // the original region becomes 'new' region
   1.334 -    rgn->exclude_region(new_rgn_addr + new_rgn_size, sz);
   1.335 -     // remaining becomes next region
   1.336 -    MemPointerRecordEx next_rgn(new_rgn_addr + new_rgn_size, rgn->flags(), sz, pc);
   1.337 -    return insert_reserved_region(&next_rgn);
   1.338 -  } else if (rgn->base() + rgn->size() == new_rgn_addr + new_rgn_size) {
   1.339 -    rgn->exclude_region(new_rgn_addr, new_rgn_size);
   1.340 -    MemPointerRecordEx next_rgn(new_rgn_addr, rgn->flags(), new_rgn_size, pc);
   1.341 -    return insert_reserved_region(&next_rgn);
   1.342 -  } else {
   1.343 -    // the orginal region will be split into three
   1.344 -    address rgn_high_addr = rgn->base() + rgn->size();
   1.345 -    // first region
   1.346 -    rgn->exclude_region(new_rgn_addr, (rgn_high_addr - new_rgn_addr));
   1.347 -    // the second region is the new region
   1.348 -    MemPointerRecordEx new_rgn(new_rgn_addr, rgn->flags(), new_rgn_size, pc);
   1.349 -    if (!insert_reserved_region(&new_rgn)) return false;
   1.350 -    // the remaining region
   1.351 -    MemPointerRecordEx rem_rgn(new_rgn_addr + new_rgn_size, rgn->flags(),
   1.352 -      rgn_high_addr - (new_rgn_addr + new_rgn_size), pc);
   1.353 -    return insert_reserved_region(&rem_rgn);
   1.354 -  }
   1.355 -}
   1.356 -
   1.357 -static int sort_in_seq_order(const void* p1, const void* p2) {
   1.358 -  assert(p1 != NULL && p2 != NULL, "Sanity check");
   1.359 -  const MemPointerRecord* mp1 = (MemPointerRecord*)p1;
   1.360 -  const MemPointerRecord* mp2 = (MemPointerRecord*)p2;
   1.361 -  return (mp1->seq() - mp2->seq());
   1.362 -}
   1.363 -
   1.364 -bool StagingArea::init() {
   1.365 -  if (MemTracker::track_callsite()) {
   1.366 -    _malloc_data = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecordEx>();
   1.367 -    _vm_data = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecordEx>();
   1.368 -  } else {
   1.369 -    _malloc_data = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecord>();
   1.370 -    _vm_data = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecord>();
   1.371 -  }
   1.372 -
   1.373 -  if (_malloc_data != NULL && _vm_data != NULL &&
   1.374 -      !_malloc_data->out_of_memory() &&
   1.375 -      !_vm_data->out_of_memory()) {
   1.376 -    return true;
   1.377 -  } else {
   1.378 -    if (_malloc_data != NULL) delete _malloc_data;
   1.379 -    if (_vm_data != NULL) delete _vm_data;
   1.380 -    _malloc_data = NULL;
   1.381 -    _vm_data = NULL;
   1.382 -    return false;
   1.383 -  }
   1.384 -}
   1.385 -
   1.386 -
   1.387 -VMRecordIterator StagingArea::virtual_memory_record_walker() {
   1.388 -  MemPointerArray* arr = vm_data();
   1.389 -  // sort into seq number order
   1.390 -  arr->sort((FN_SORT)sort_in_seq_order);
   1.391 -  return VMRecordIterator(arr);
   1.392 -}
   1.393 -
   1.394 -
   1.395 -MemSnapshot::MemSnapshot() {
   1.396 -  if (MemTracker::track_callsite()) {
   1.397 -    _alloc_ptrs = new (std::nothrow) MemPointerArrayImpl<MemPointerRecordEx>();
   1.398 -    _vm_ptrs = new (std::nothrow)MemPointerArrayImpl<VMMemRegionEx>(64, true);
   1.399 -  } else {
   1.400 -    _alloc_ptrs = new (std::nothrow) MemPointerArrayImpl<MemPointerRecord>();
   1.401 -    _vm_ptrs = new (std::nothrow)MemPointerArrayImpl<VMMemRegion>(64, true);
   1.402 -  }
   1.403 -
   1.404 -  _staging_area.init();
   1.405 -  _lock = new (std::nothrow) Mutex(Monitor::max_nonleaf - 1, "memSnapshotLock");
   1.406 -  NOT_PRODUCT(_untracked_count = 0;)
   1.407 -  _number_of_classes = 0;
   1.408 -}
   1.409 -
   1.410 -MemSnapshot::~MemSnapshot() {
   1.411 -  assert(MemTracker::shutdown_in_progress(), "native memory tracking still on");
   1.412 -  {
   1.413 -    MutexLockerEx locker(_lock);
   1.414 -    if (_alloc_ptrs != NULL) {
   1.415 -      delete _alloc_ptrs;
   1.416 -      _alloc_ptrs = NULL;
   1.417 -    }
   1.418 -
   1.419 -    if (_vm_ptrs != NULL) {
   1.420 -      delete _vm_ptrs;
   1.421 -      _vm_ptrs = NULL;
   1.422 -    }
   1.423 -  }
   1.424 -
   1.425 -  if (_lock != NULL) {
   1.426 -    delete _lock;
   1.427 -    _lock = NULL;
   1.428 -  }
   1.429 -}
   1.430 -
   1.431 -
   1.432 -void MemSnapshot::copy_seq_pointer(MemPointerRecord* dest, const MemPointerRecord* src) {
   1.433 -  assert(dest != NULL && src != NULL, "Just check");
   1.434 -  assert(dest->addr() == src->addr(), "Just check");
   1.435 -  assert(dest->seq() > 0 && src->seq() > 0, "not sequenced");
   1.436 -
   1.437 -  if (MemTracker::track_callsite()) {
   1.438 -    *(SeqMemPointerRecordEx*)dest = *(SeqMemPointerRecordEx*)src;
   1.439 -  } else {
   1.440 -    *(SeqMemPointerRecord*)dest = *(SeqMemPointerRecord*)src;
   1.441 -  }
   1.442 -}
   1.443 -
   1.444 -void MemSnapshot::assign_pointer(MemPointerRecord*dest, const MemPointerRecord* src) {
   1.445 -  assert(src != NULL && dest != NULL, "Just check");
   1.446 -  assert(dest->seq() == 0 && src->seq() >0, "cast away sequence");
   1.447 -
   1.448 -  if (MemTracker::track_callsite()) {
   1.449 -    *(MemPointerRecordEx*)dest = *(MemPointerRecordEx*)src;
   1.450 -  } else {
   1.451 -    *(MemPointerRecord*)dest = *(MemPointerRecord*)src;
   1.452 -  }
   1.453 -}
   1.454 -
   1.455 -// merge a recorder to the staging area
   1.456 -bool MemSnapshot::merge(MemRecorder* rec) {
   1.457 -  assert(rec != NULL && !rec->out_of_memory(), "Just check");
   1.458 -
   1.459 -  SequencedRecordIterator itr(rec->pointer_itr());
   1.460 -
   1.461 -  MutexLockerEx lock(_lock, true);
   1.462 -  MemPointerIterator malloc_staging_itr(_staging_area.malloc_data());
   1.463 -  MemPointerRecord* incoming_rec = (MemPointerRecord*) itr.current();
   1.464 -  MemPointerRecord* matched_rec;
   1.465 -
   1.466 -  while (incoming_rec != NULL) {
   1.467 -    if (incoming_rec->is_vm_pointer()) {
   1.468 -      // we don't do anything with virtual memory records during merge
   1.469 -      if (!_staging_area.vm_data()->append(incoming_rec)) {
   1.470 -        return false;
   1.471 -      }
   1.472 -    } else {
   1.473 -      // locate matched record and/or also position the iterator to proper
   1.474 -      // location for this incoming record.
   1.475 -      matched_rec = (MemPointerRecord*)malloc_staging_itr.locate(incoming_rec->addr());
   1.476 -      // we have not seen this memory block in this generation,
   1.477 -      // so just add to staging area
   1.478 -      if (matched_rec == NULL) {
   1.479 -        if (!malloc_staging_itr.insert(incoming_rec)) {
   1.480 -          return false;
   1.481 -        }
   1.482 -      } else if (incoming_rec->addr() == matched_rec->addr()) {
   1.483 -        // whoever has higher sequence number wins
   1.484 -        if (incoming_rec->seq() > matched_rec->seq()) {
   1.485 -          copy_seq_pointer(matched_rec, incoming_rec);
   1.486 -        }
   1.487 -      } else if (incoming_rec->addr() < matched_rec->addr()) {
   1.488 -        if (!malloc_staging_itr.insert(incoming_rec)) {
   1.489 -          return false;
   1.490 -        }
   1.491 -      } else {
   1.492 -        ShouldNotReachHere();
   1.493 -      }
   1.494 -    }
   1.495 -    incoming_rec = (MemPointerRecord*)itr.next();
   1.496 -  }
   1.497 -  NOT_PRODUCT(void check_staging_data();)
   1.498 -  return true;
   1.499 -}
   1.500 -
   1.501 -
   1.502 -// promote data to next generation
   1.503 -bool MemSnapshot::promote(int number_of_classes) {
   1.504 -  assert(_alloc_ptrs != NULL && _vm_ptrs != NULL, "Just check");
   1.505 -  assert(_staging_area.malloc_data() != NULL && _staging_area.vm_data() != NULL,
   1.506 -         "Just check");
   1.507 -  MutexLockerEx lock(_lock, true);
   1.508 -
   1.509 -  MallocRecordIterator  malloc_itr = _staging_area.malloc_record_walker();
   1.510 -  bool promoted = false;
   1.511 -  if (promote_malloc_records(&malloc_itr)) {
   1.512 -    VMRecordIterator vm_itr = _staging_area.virtual_memory_record_walker();
   1.513 -    if (promote_virtual_memory_records(&vm_itr)) {
   1.514 -      promoted = true;
   1.515 -    }
   1.516 -  }
   1.517 -
   1.518 -  NOT_PRODUCT(check_malloc_pointers();)
   1.519 -  _staging_area.clear();
   1.520 -  _number_of_classes = number_of_classes;
   1.521 -  return promoted;
   1.522 -}
   1.523 -
   1.524 -bool MemSnapshot::promote_malloc_records(MemPointerArrayIterator* itr) {
   1.525 -  MemPointerIterator malloc_snapshot_itr(_alloc_ptrs);
   1.526 -  MemPointerRecord* new_rec = (MemPointerRecord*)itr->current();
   1.527 -  MemPointerRecord* matched_rec;
   1.528 -  while (new_rec != NULL) {
   1.529 -    matched_rec = (MemPointerRecord*)malloc_snapshot_itr.locate(new_rec->addr());
   1.530 -    // found matched memory block
   1.531 -    if (matched_rec != NULL && new_rec->addr() == matched_rec->addr()) {
   1.532 -      // snapshot already contains 'live' records
   1.533 -      assert(matched_rec->is_allocation_record() || matched_rec->is_arena_memory_record(),
   1.534 -             "Sanity check");
   1.535 -      // update block states
   1.536 -      if (new_rec->is_allocation_record()) {
   1.537 -        assign_pointer(matched_rec, new_rec);
   1.538 -      } else if (new_rec->is_arena_memory_record()) {
   1.539 -        if (new_rec->size() == 0) {
   1.540 -          // remove size record once size drops to 0
   1.541 -          malloc_snapshot_itr.remove();
   1.542 -        } else {
   1.543 -          assign_pointer(matched_rec, new_rec);
   1.544 -        }
   1.545 -      } else {
   1.546 -        // a deallocation record
   1.547 -        assert(new_rec->is_deallocation_record(), "Sanity check");
   1.548 -        // an arena record can be followed by a size record, we need to remove both
   1.549 -        if (matched_rec->is_arena_record()) {
   1.550 -          MemPointerRecord* next = (MemPointerRecord*)malloc_snapshot_itr.peek_next();
   1.551 -          if (next != NULL && next->is_arena_memory_record() &&
   1.552 -              next->is_memory_record_of_arena(matched_rec)) {
   1.553 -            malloc_snapshot_itr.remove();
   1.554 -          }
   1.555 -        }
   1.556 -        // the memory is deallocated, remove related record(s)
   1.557 -        malloc_snapshot_itr.remove();
   1.558 -      }
   1.559 -    } else {
   1.560 -      // don't insert size 0 record
   1.561 -      if (new_rec->is_arena_memory_record() && new_rec->size() == 0) {
   1.562 -        new_rec = NULL;
   1.563 -      }
   1.564 -
   1.565 -      if (new_rec != NULL) {
   1.566 -        if  (new_rec->is_allocation_record() || new_rec->is_arena_memory_record()) {
   1.567 -          if (matched_rec != NULL && new_rec->addr() > matched_rec->addr()) {
   1.568 -            if (!malloc_snapshot_itr.insert_after(new_rec)) {
   1.569 -              return false;
   1.570 -            }
   1.571 -          } else {
   1.572 -            if (!malloc_snapshot_itr.insert(new_rec)) {
   1.573 -              return false;
   1.574 -            }
   1.575 -          }
   1.576 -        }
   1.577 -#ifndef PRODUCT
   1.578 -        else if (!has_allocation_record(new_rec->addr())) {
   1.579 -          // NMT can not track some startup memory, which is allocated before NMT is on
   1.580 -          _untracked_count ++;
   1.581 -        }
   1.582 -#endif
   1.583 -      }
   1.584 -    }
   1.585 -    new_rec = (MemPointerRecord*)itr->next();
   1.586 -  }
   1.587 -  return true;
   1.588 -}
   1.589 -
   1.590 -bool MemSnapshot::promote_virtual_memory_records(MemPointerArrayIterator* itr) {
   1.591 -  VMMemPointerIterator vm_snapshot_itr(_vm_ptrs);
   1.592 -  MemPointerRecord* new_rec = (MemPointerRecord*)itr->current();
   1.593 -  VMMemRegion*  reserved_rec;
   1.594 -  while (new_rec != NULL) {
   1.595 -    assert(new_rec->is_vm_pointer(), "Sanity check");
   1.596 -
   1.597 -    // locate a reserved region that contains the specified address, or
   1.598 -    // the nearest reserved region has base address just above the specified
   1.599 -    // address
   1.600 -    reserved_rec = (VMMemRegion*)vm_snapshot_itr.locate(new_rec->addr());
   1.601 -    if (reserved_rec != NULL && reserved_rec->contains_region(new_rec)) {
   1.602 -      // snapshot can only have 'live' records
   1.603 -      assert(reserved_rec->is_reserved_region(), "Sanity check");
   1.604 -      if (new_rec->is_allocation_record()) {
   1.605 -        if (!reserved_rec->is_same_region(new_rec)) {
   1.606 -          // only deal with split a bigger reserved region into smaller regions.
   1.607 -          // So far, CDS is the only use case.
   1.608 -          if (!vm_snapshot_itr.split_reserved_region(reserved_rec, new_rec->addr(), new_rec->size())) {
   1.609 -            return false;
   1.610 -          }
   1.611 -        }
   1.612 -      } else if (new_rec->is_uncommit_record()) {
   1.613 -        if (!vm_snapshot_itr.remove_uncommitted_region(new_rec)) {
   1.614 -          return false;
   1.615 -        }
   1.616 -      } else if (new_rec->is_commit_record()) {
   1.617 -        // insert or expand existing committed region to cover this
   1.618 -        // newly committed region
   1.619 -        if (!vm_snapshot_itr.add_committed_region(new_rec)) {
   1.620 -          return false;
   1.621 -        }
   1.622 -      } else if (new_rec->is_deallocation_record()) {
   1.623 -        // release part or all memory region
   1.624 -        if (!vm_snapshot_itr.remove_released_region(new_rec)) {
   1.625 -          return false;
   1.626 -        }
   1.627 -      } else if (new_rec->is_type_tagging_record()) {
   1.628 -        // tag this reserved virtual memory range to a memory type. Can not re-tag a memory range
   1.629 -        // to different type.
   1.630 -        assert(FLAGS_TO_MEMORY_TYPE(reserved_rec->flags()) == mtNone ||
   1.631 -               FLAGS_TO_MEMORY_TYPE(reserved_rec->flags()) == FLAGS_TO_MEMORY_TYPE(new_rec->flags()),
   1.632 -               "Sanity check");
   1.633 -        reserved_rec->tag(new_rec->flags());
   1.634 -    } else {
   1.635 -        ShouldNotReachHere();
   1.636 -          }
   1.637 -        } else {
   1.638 -      /*
   1.639 -       * The assertion failure indicates mis-matched virtual memory records. The likely
   1.640 -       * scenario is, that some virtual memory operations are not going through os::xxxx_memory()
   1.641 -       * api, which have to be tracked manually. (perfMemory is an example).
   1.642 -      */
   1.643 -      assert(new_rec->is_allocation_record(), "Sanity check");
   1.644 -      if (!vm_snapshot_itr.add_reserved_region(new_rec)) {
   1.645 -            return false;
   1.646 -          }
   1.647 -  }
   1.648 -    new_rec = (MemPointerRecord*)itr->next();
   1.649 -  }
   1.650 -  return true;
   1.651 -}
   1.652 -
   1.653 -#ifndef PRODUCT
   1.654 -void MemSnapshot::print_snapshot_stats(outputStream* st) {
   1.655 -  st->print_cr("Snapshot:");
   1.656 -  st->print_cr("\tMalloced: %d/%d [%5.2f%%]  %dKB", _alloc_ptrs->length(), _alloc_ptrs->capacity(),
   1.657 -    (100.0 * (float)_alloc_ptrs->length()) / (float)_alloc_ptrs->capacity(), _alloc_ptrs->instance_size()/K);
   1.658 -
   1.659 -  st->print_cr("\tVM: %d/%d [%5.2f%%] %dKB", _vm_ptrs->length(), _vm_ptrs->capacity(),
   1.660 -    (100.0 * (float)_vm_ptrs->length()) / (float)_vm_ptrs->capacity(), _vm_ptrs->instance_size()/K);
   1.661 -
   1.662 -  st->print_cr("\tMalloc staging Area:     %d/%d [%5.2f%%] %dKB", _staging_area.malloc_data()->length(),
   1.663 -    _staging_area.malloc_data()->capacity(),
   1.664 -    (100.0 * (float)_staging_area.malloc_data()->length()) / (float)_staging_area.malloc_data()->capacity(),
   1.665 -    _staging_area.malloc_data()->instance_size()/K);
   1.666 -
   1.667 -  st->print_cr("\tVirtual memory staging Area:     %d/%d [%5.2f%%] %dKB", _staging_area.vm_data()->length(),
   1.668 -    _staging_area.vm_data()->capacity(),
   1.669 -    (100.0 * (float)_staging_area.vm_data()->length()) / (float)_staging_area.vm_data()->capacity(),
   1.670 -    _staging_area.vm_data()->instance_size()/K);
   1.671 -
   1.672 -  st->print_cr("\tUntracked allocation: %d", _untracked_count);
   1.673 -}
   1.674 -
   1.675 -void MemSnapshot::check_malloc_pointers() {
   1.676 -  MemPointerArrayIteratorImpl mItr(_alloc_ptrs);
   1.677 -  MemPointerRecord* p = (MemPointerRecord*)mItr.current();
   1.678 -  MemPointerRecord* prev = NULL;
   1.679 -  while (p != NULL) {
   1.680 -    if (prev != NULL) {
   1.681 -      assert(p->addr() >= prev->addr(), "sorting order");
   1.682 -    }
   1.683 -    prev = p;
   1.684 -    p = (MemPointerRecord*)mItr.next();
   1.685 -  }
   1.686 -}
   1.687 -
   1.688 -bool MemSnapshot::has_allocation_record(address addr) {
   1.689 -  MemPointerArrayIteratorImpl itr(_staging_area.malloc_data());
   1.690 -  MemPointerRecord* cur = (MemPointerRecord*)itr.current();
   1.691 -  while (cur != NULL) {
   1.692 -    if (cur->addr() == addr && cur->is_allocation_record()) {
   1.693 -      return true;
   1.694 -    }
   1.695 -    cur = (MemPointerRecord*)itr.next();
   1.696 -  }
   1.697 -  return false;
   1.698 -}
   1.699 -#endif // PRODUCT
   1.700 -
   1.701 -#ifdef ASSERT
   1.702 -void MemSnapshot::check_staging_data() {
   1.703 -  MemPointerArrayIteratorImpl itr(_staging_area.malloc_data());
   1.704 -  MemPointerRecord* cur = (MemPointerRecord*)itr.current();
   1.705 -  MemPointerRecord* next = (MemPointerRecord*)itr.next();
   1.706 -  while (next != NULL) {
   1.707 -    assert((next->addr() > cur->addr()) ||
   1.708 -      ((next->flags() & MemPointerRecord::tag_masks) >
   1.709 -       (cur->flags() & MemPointerRecord::tag_masks)),
   1.710 -       "sorting order");
   1.711 -    cur = next;
   1.712 -    next = (MemPointerRecord*)itr.next();
   1.713 -  }
   1.714 -
   1.715 -  MemPointerArrayIteratorImpl vm_itr(_staging_area.vm_data());
   1.716 -  cur = (MemPointerRecord*)vm_itr.current();
   1.717 -  while (cur != NULL) {
   1.718 -    assert(cur->is_vm_pointer(), "virtual memory pointer only");
   1.719 -    cur = (MemPointerRecord*)vm_itr.next();
   1.720 -  }
   1.721 -}
   1.722 -
   1.723 -void MemSnapshot::dump_all_vm_pointers() {
   1.724 -  MemPointerArrayIteratorImpl itr(_vm_ptrs);
   1.725 -  VMMemRegion* ptr = (VMMemRegion*)itr.current();
   1.726 -  tty->print_cr("dump virtual memory pointers:");
   1.727 -  while (ptr != NULL) {
   1.728 -    if (ptr->is_committed_region()) {
   1.729 -      tty->print("\t");
   1.730 -    }
   1.731 -    tty->print("[" PTR_FORMAT " - " PTR_FORMAT "] [%x]", ptr->addr(),
   1.732 -      (ptr->addr() + ptr->size()), ptr->flags());
   1.733 -
   1.734 -    if (MemTracker::track_callsite()) {
   1.735 -      VMMemRegionEx* ex = (VMMemRegionEx*)ptr;
   1.736 -      if (ex->pc() != NULL) {
   1.737 -        char buf[1024];
   1.738 -        if (os::dll_address_to_function_name(ex->pc(), buf, sizeof(buf), NULL)) {
   1.739 -          tty->print_cr("\t%s", buf);
   1.740 -        } else {
   1.741 -          tty->cr();
   1.742 -        }
   1.743 -      }
   1.744 -    }
   1.745 -
   1.746 -    ptr = (VMMemRegion*)itr.next();
   1.747 -  }
   1.748 -  tty->flush();
   1.749 -}
   1.750 -#endif // ASSERT
   1.751 -

mercurial