src/share/vm/services/memSnapshot.hpp

changeset 7074
833b0f92429a
parent 7073
4d3a43351904
child 7075
ac12996df59b
     1.1 --- a/src/share/vm/services/memSnapshot.hpp	Wed Aug 27 09:36:55 2014 +0200
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,408 +0,0 @@
     1.4 -/*
     1.5 - * Copyright (c) 2012, 2013, 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 -#ifndef SHARE_VM_SERVICES_MEM_SNAPSHOT_HPP
    1.29 -#define SHARE_VM_SERVICES_MEM_SNAPSHOT_HPP
    1.30 -
    1.31 -#include "memory/allocation.hpp"
    1.32 -#include "runtime/mutex.hpp"
    1.33 -#include "runtime/mutexLocker.hpp"
    1.34 -#include "services/memBaseline.hpp"
    1.35 -#include "services/memPtrArray.hpp"
    1.36 -
    1.37 -// Snapshot pointer array iterator
    1.38 -
    1.39 -// The pointer array contains malloc-ed pointers
    1.40 -class MemPointerIterator : public MemPointerArrayIteratorImpl {
    1.41 - public:
    1.42 -  MemPointerIterator(MemPointerArray* arr):
    1.43 -    MemPointerArrayIteratorImpl(arr) {
    1.44 -    assert(arr != NULL, "null array");
    1.45 -  }
    1.46 -
    1.47 -#ifdef ASSERT
    1.48 -  virtual bool is_dup_pointer(const MemPointer* ptr1,
    1.49 -    const MemPointer* ptr2) const {
    1.50 -    MemPointerRecord* p1 = (MemPointerRecord*)ptr1;
    1.51 -    MemPointerRecord* p2 = (MemPointerRecord*)ptr2;
    1.52 -
    1.53 -    if (p1->addr() != p2->addr()) return false;
    1.54 -    if ((p1->flags() & MemPointerRecord::tag_masks) !=
    1.55 -        (p2->flags() & MemPointerRecord::tag_masks)) {
    1.56 -      return false;
    1.57 -    }
    1.58 -    // we do see multiple commit/uncommit on the same memory, it is ok
    1.59 -    return (p1->flags() & MemPointerRecord::tag_masks) == MemPointerRecord::tag_alloc ||
    1.60 -           (p1->flags() & MemPointerRecord::tag_masks) == MemPointerRecord::tag_release;
    1.61 -  }
    1.62 -
    1.63 -  virtual bool insert(MemPointer* ptr) {
    1.64 -    if (_pos > 0) {
    1.65 -      MemPointer* p1 = (MemPointer*)ptr;
    1.66 -      MemPointer* p2 = (MemPointer*)_array->at(_pos - 1);
    1.67 -      assert(!is_dup_pointer(p1, p2),
    1.68 -        err_msg("duplicated pointer, flag = [%x]", (unsigned int)((MemPointerRecord*)p1)->flags()));
    1.69 -    }
    1.70 -     if (_pos < _array->length() -1) {
    1.71 -      MemPointer* p1 = (MemPointer*)ptr;
    1.72 -      MemPointer* p2 = (MemPointer*)_array->at(_pos + 1);
    1.73 -      assert(!is_dup_pointer(p1, p2),
    1.74 -        err_msg("duplicated pointer, flag = [%x]", (unsigned int)((MemPointerRecord*)p1)->flags()));
    1.75 -     }
    1.76 -    return _array->insert_at(ptr, _pos);
    1.77 -  }
    1.78 -
    1.79 -  virtual bool insert_after(MemPointer* ptr) {
    1.80 -    if (_pos > 0) {
    1.81 -      MemPointer* p1 = (MemPointer*)ptr;
    1.82 -      MemPointer* p2 = (MemPointer*)_array->at(_pos - 1);
    1.83 -      assert(!is_dup_pointer(p1, p2),
    1.84 -        err_msg("duplicated pointer, flag = [%x]", (unsigned int)((MemPointerRecord*)p1)->flags()));
    1.85 -    }
    1.86 -    if (_pos < _array->length() - 1) {
    1.87 -      MemPointer* p1 = (MemPointer*)ptr;
    1.88 -      MemPointer* p2 = (MemPointer*)_array->at(_pos + 1);
    1.89 -
    1.90 -      assert(!is_dup_pointer(p1, p2),
    1.91 -        err_msg("duplicated pointer, flag = [%x]", (unsigned int)((MemPointerRecord*)p1)->flags()));
    1.92 -     }
    1.93 -    if (_array->insert_at(ptr, _pos + 1)) {
    1.94 -      _pos ++;
    1.95 -      return true;
    1.96 -    }
    1.97 -    return false;
    1.98 -  }
    1.99 -#endif
   1.100 -
   1.101 -  virtual MemPointer* locate(address addr) {
   1.102 -    MemPointer* cur = current();
   1.103 -    while (cur != NULL && cur->addr() < addr) {
   1.104 -      cur = next();
   1.105 -    }
   1.106 -    return cur;
   1.107 -  }
   1.108 -};
   1.109 -
   1.110 -class VMMemPointerIterator : public MemPointerIterator {
   1.111 - public:
   1.112 -  VMMemPointerIterator(MemPointerArray* arr):
   1.113 -      MemPointerIterator(arr) {
   1.114 -  }
   1.115 -
   1.116 -  // locate an existing reserved memory region that contains specified address,
   1.117 -  // or the reserved region just above this address, where the incoming
   1.118 -  // reserved region should be inserted.
   1.119 -  virtual MemPointer* locate(address addr) {
   1.120 -    reset();
   1.121 -    VMMemRegion* reg = (VMMemRegion*)current();
   1.122 -    while (reg != NULL) {
   1.123 -      if (reg->is_reserved_region()) {
   1.124 -        if (reg->contains_address(addr) || addr < reg->base()) {
   1.125 -          return reg;
   1.126 -      }
   1.127 -    }
   1.128 -      reg = (VMMemRegion*)next();
   1.129 -    }
   1.130 -      return NULL;
   1.131 -    }
   1.132 -
   1.133 -  // following methods update virtual memory in the context
   1.134 -  // of 'current' position, which is properly positioned by
   1.135 -  // callers via locate method.
   1.136 -  bool add_reserved_region(MemPointerRecord* rec);
   1.137 -  bool add_committed_region(MemPointerRecord* rec);
   1.138 -  bool remove_uncommitted_region(MemPointerRecord* rec);
   1.139 -  bool remove_released_region(MemPointerRecord* rec);
   1.140 -
   1.141 -  // split a reserved region to create a new memory region with specified base and size
   1.142 -  bool split_reserved_region(VMMemRegion* rgn, address new_rgn_addr, size_t new_rgn_size);
   1.143 - private:
   1.144 -  bool insert_record(MemPointerRecord* rec);
   1.145 -  bool insert_record_after(MemPointerRecord* rec);
   1.146 -
   1.147 -  bool insert_reserved_region(MemPointerRecord* rec);
   1.148 -
   1.149 -  // reset current position
   1.150 -  inline void reset() { _pos = 0; }
   1.151 -#ifdef ASSERT
   1.152 -  // check integrity of records on current reserved memory region.
   1.153 -  bool check_reserved_region() {
   1.154 -    VMMemRegion* reserved_region = (VMMemRegion*)current();
   1.155 -    assert(reserved_region != NULL && reserved_region->is_reserved_region(),
   1.156 -          "Sanity check");
   1.157 -    // all committed regions that follow current reserved region, should all
   1.158 -    // belong to the reserved region.
   1.159 -    VMMemRegion* next_region = (VMMemRegion*)next();
   1.160 -    for (; next_region != NULL && next_region->is_committed_region();
   1.161 -         next_region = (VMMemRegion*)next() ) {
   1.162 -      if(!reserved_region->contains_region(next_region)) {
   1.163 -        return false;
   1.164 -      }
   1.165 -    }
   1.166 -    return true;
   1.167 -  }
   1.168 -
   1.169 -  virtual bool is_dup_pointer(const MemPointer* ptr1,
   1.170 -    const MemPointer* ptr2) const {
   1.171 -    VMMemRegion* p1 = (VMMemRegion*)ptr1;
   1.172 -    VMMemRegion* p2 = (VMMemRegion*)ptr2;
   1.173 -
   1.174 -    if (p1->addr() != p2->addr()) return false;
   1.175 -    if ((p1->flags() & MemPointerRecord::tag_masks) !=
   1.176 -        (p2->flags() & MemPointerRecord::tag_masks)) {
   1.177 -      return false;
   1.178 -    }
   1.179 -    // we do see multiple commit/uncommit on the same memory, it is ok
   1.180 -    return (p1->flags() & MemPointerRecord::tag_masks) == MemPointerRecord::tag_alloc ||
   1.181 -           (p1->flags() & MemPointerRecord::tag_masks) == MemPointerRecord::tag_release;
   1.182 -  }
   1.183 -#endif
   1.184 -};
   1.185 -
   1.186 -class MallocRecordIterator : public MemPointerArrayIterator {
   1.187 - private:
   1.188 -  MemPointerArrayIteratorImpl  _itr;
   1.189 -
   1.190 -
   1.191 -
   1.192 - public:
   1.193 -  MallocRecordIterator(MemPointerArray* arr) : _itr(arr) {
   1.194 -  }
   1.195 -
   1.196 -  virtual MemPointer* current() const {
   1.197 -#ifdef ASSERT
   1.198 -    MemPointer* cur_rec = _itr.current();
   1.199 -    if (cur_rec != NULL) {
   1.200 -      MemPointer* prev_rec = _itr.peek_prev();
   1.201 -      MemPointer* next_rec = _itr.peek_next();
   1.202 -      assert(prev_rec == NULL || prev_rec->addr() < cur_rec->addr(), "Sorting order");
   1.203 -      assert(next_rec == NULL || next_rec->addr() > cur_rec->addr(), "Sorting order");
   1.204 -    }
   1.205 -#endif
   1.206 -    return _itr.current();
   1.207 -  }
   1.208 -  virtual MemPointer* next() {
   1.209 -    MemPointerRecord* next_rec = (MemPointerRecord*)_itr.next();
   1.210 -    // arena memory record is a special case, which we have to compare
   1.211 -    // sequence number against its associated arena record.
   1.212 -    if (next_rec != NULL && next_rec->is_arena_memory_record()) {
   1.213 -      MemPointerRecord* prev_rec = (MemPointerRecord*)_itr.peek_prev();
   1.214 -      // if there is an associated arena record, it has to be previous
   1.215 -      // record because of sorting order (by address) - NMT generates a pseudo address
   1.216 -      // for arena's size record by offsetting arena's address, that guarantees
   1.217 -      // the order of arena record and it's size record.
   1.218 -      if (prev_rec != NULL && prev_rec->is_arena_record() &&
   1.219 -        next_rec->is_memory_record_of_arena(prev_rec)) {
   1.220 -        if (prev_rec->seq() > next_rec->seq()) {
   1.221 -          // Skip this arena memory record
   1.222 -          // Two scenarios:
   1.223 -          //   - if the arena record is an allocation record, this early
   1.224 -          //     size record must be leftover by previous arena,
   1.225 -          //     and the last size record should have size = 0.
   1.226 -          //   - if the arena record is a deallocation record, this
   1.227 -          //     size record should be its cleanup record, which should
   1.228 -          //     also have size = 0. In other world, arena alway reset
   1.229 -          //     its size before gone (see Arena's destructor)
   1.230 -          assert(next_rec->size() == 0, "size not reset");
   1.231 -          return _itr.next();
   1.232 -        } else {
   1.233 -          assert(prev_rec->is_allocation_record(),
   1.234 -            "Arena size record ahead of allocation record");
   1.235 -        }
   1.236 -      }
   1.237 -    }
   1.238 -    return next_rec;
   1.239 -  }
   1.240 -
   1.241 -  MemPointer* peek_next() const      { ShouldNotReachHere(); return NULL; }
   1.242 -  MemPointer* peek_prev() const      { ShouldNotReachHere(); return NULL; }
   1.243 -  void remove()                      { ShouldNotReachHere(); }
   1.244 -  bool insert(MemPointer* ptr)       { ShouldNotReachHere(); return false; }
   1.245 -  bool insert_after(MemPointer* ptr) { ShouldNotReachHere(); return false; }
   1.246 -};
   1.247 -
   1.248 -// collapse duplicated records. Eliminating duplicated records here, is much
   1.249 -// cheaper than during promotion phase. However, it does have limitation - it
   1.250 -// can only eliminate duplicated records within the generation, there are
   1.251 -// still chances seeing duplicated records during promotion.
   1.252 -// We want to use the record with higher sequence number, because it has
   1.253 -// more accurate callsite pc.
   1.254 -class VMRecordIterator : public MemPointerArrayIterator {
   1.255 - private:
   1.256 -  MemPointerArrayIteratorImpl  _itr;
   1.257 -
   1.258 - public:
   1.259 -  VMRecordIterator(MemPointerArray* arr) : _itr(arr) {
   1.260 -    MemPointerRecord* cur = (MemPointerRecord*)_itr.current();
   1.261 -    MemPointerRecord* next = (MemPointerRecord*)_itr.peek_next();
   1.262 -    while (next != NULL) {
   1.263 -      assert(cur != NULL, "Sanity check");
   1.264 -      assert(((SeqMemPointerRecord*)next)->seq() > ((SeqMemPointerRecord*)cur)->seq(),
   1.265 -        "pre-sort order");
   1.266 -
   1.267 -      if (is_duplicated_record(cur, next)) {
   1.268 -        _itr.next();
   1.269 -        next = (MemPointerRecord*)_itr.peek_next();
   1.270 -      } else {
   1.271 -        break;
   1.272 -      }
   1.273 -    }
   1.274 -  }
   1.275 -
   1.276 -  virtual MemPointer* current() const {
   1.277 -    return _itr.current();
   1.278 -  }
   1.279 -
   1.280 -  // get next record, but skip the duplicated records
   1.281 -  virtual MemPointer* next() {
   1.282 -    MemPointerRecord* cur = (MemPointerRecord*)_itr.next();
   1.283 -    MemPointerRecord* next = (MemPointerRecord*)_itr.peek_next();
   1.284 -    while (next != NULL) {
   1.285 -      assert(cur != NULL, "Sanity check");
   1.286 -      assert(((SeqMemPointerRecord*)next)->seq() > ((SeqMemPointerRecord*)cur)->seq(),
   1.287 -        "pre-sort order");
   1.288 -
   1.289 -      if (is_duplicated_record(cur, next)) {
   1.290 -        _itr.next();
   1.291 -        cur = next;
   1.292 -        next = (MemPointerRecord*)_itr.peek_next();
   1.293 -      } else {
   1.294 -        break;
   1.295 -      }
   1.296 -    }
   1.297 -    return cur;
   1.298 -  }
   1.299 -
   1.300 -  MemPointer* peek_next() const      { ShouldNotReachHere(); return NULL; }
   1.301 -  MemPointer* peek_prev() const      { ShouldNotReachHere(); return NULL; }
   1.302 -  void remove()                      { ShouldNotReachHere(); }
   1.303 -  bool insert(MemPointer* ptr)       { ShouldNotReachHere(); return false; }
   1.304 -  bool insert_after(MemPointer* ptr) { ShouldNotReachHere(); return false; }
   1.305 -
   1.306 - private:
   1.307 -  bool is_duplicated_record(MemPointerRecord* p1, MemPointerRecord* p2) const {
   1.308 -    bool ret = (p1->addr() == p2->addr() && p1->size() == p2->size() && p1->flags() == p2->flags());
   1.309 -    assert(!(ret && FLAGS_TO_MEMORY_TYPE(p1->flags()) == mtThreadStack), "dup on stack record");
   1.310 -    return ret;
   1.311 -  }
   1.312 -};
   1.313 -
   1.314 -class StagingArea VALUE_OBJ_CLASS_SPEC {
   1.315 - private:
   1.316 -  MemPointerArray*   _malloc_data;
   1.317 -  MemPointerArray*   _vm_data;
   1.318 -
   1.319 - public:
   1.320 -  StagingArea() : _malloc_data(NULL), _vm_data(NULL) {
   1.321 -    init();
   1.322 -  }
   1.323 -
   1.324 -  ~StagingArea() {
   1.325 -    if (_malloc_data != NULL) delete _malloc_data;
   1.326 -    if (_vm_data != NULL) delete _vm_data;
   1.327 -  }
   1.328 -
   1.329 -  MallocRecordIterator malloc_record_walker() {
   1.330 -    return MallocRecordIterator(malloc_data());
   1.331 -  }
   1.332 -
   1.333 -  VMRecordIterator virtual_memory_record_walker();
   1.334 -
   1.335 -  bool init();
   1.336 -  void clear() {
   1.337 -    assert(_malloc_data != NULL && _vm_data != NULL, "Just check");
   1.338 -    _malloc_data->shrink();
   1.339 -    _malloc_data->clear();
   1.340 -    _vm_data->clear();
   1.341 -  }
   1.342 -
   1.343 -  inline MemPointerArray* malloc_data() { return _malloc_data; }
   1.344 -  inline MemPointerArray* vm_data()     { return _vm_data; }
   1.345 -};
   1.346 -
   1.347 -class MemBaseline;
   1.348 -class MemSnapshot : public CHeapObj<mtNMT> {
   1.349 - private:
   1.350 -  // the following two arrays contain records of all known lived memory blocks
   1.351 -  // live malloc-ed memory pointers
   1.352 -  MemPointerArray*      _alloc_ptrs;
   1.353 -  // live virtual memory pointers
   1.354 -  MemPointerArray*      _vm_ptrs;
   1.355 -
   1.356 -  StagingArea           _staging_area;
   1.357 -
   1.358 -  // the lock to protect this snapshot
   1.359 -  Monitor*              _lock;
   1.360 -
   1.361 -  // the number of instance classes
   1.362 -  int                   _number_of_classes;
   1.363 -
   1.364 -  NOT_PRODUCT(size_t    _untracked_count;)
   1.365 -  friend class MemBaseline;
   1.366 -
   1.367 - public:
   1.368 -  MemSnapshot();
   1.369 -  virtual ~MemSnapshot();
   1.370 -
   1.371 -  // if we are running out of native memory
   1.372 -  bool out_of_memory() {
   1.373 -    return (_alloc_ptrs == NULL ||
   1.374 -      _staging_area.malloc_data() == NULL ||
   1.375 -      _staging_area.vm_data() == NULL ||
   1.376 -      _vm_ptrs == NULL || _lock == NULL ||
   1.377 -      _alloc_ptrs->out_of_memory() ||
   1.378 -      _vm_ptrs->out_of_memory());
   1.379 -  }
   1.380 -
   1.381 -  // merge a per-thread memory recorder into staging area
   1.382 -  bool merge(MemRecorder* rec);
   1.383 -  // promote staged data to snapshot
   1.384 -  bool promote(int number_of_classes);
   1.385 -
   1.386 -  int  number_of_classes() const { return _number_of_classes; }
   1.387 -
   1.388 -  void wait(long timeout) {
   1.389 -    assert(_lock != NULL, "Just check");
   1.390 -    MonitorLockerEx locker(_lock);
   1.391 -    locker.wait(true, timeout);
   1.392 -  }
   1.393 -
   1.394 -  NOT_PRODUCT(void print_snapshot_stats(outputStream* st);)
   1.395 -  NOT_PRODUCT(void check_staging_data();)
   1.396 -  NOT_PRODUCT(void check_malloc_pointers();)
   1.397 -  NOT_PRODUCT(bool has_allocation_record(address addr);)
   1.398 -  // dump all virtual memory pointers in snapshot
   1.399 -  DEBUG_ONLY( void dump_all_vm_pointers();)
   1.400 -
   1.401 - private:
   1.402 -   // copy sequenced pointer from src to dest
   1.403 -   void copy_seq_pointer(MemPointerRecord* dest, const MemPointerRecord* src);
   1.404 -   // assign a sequenced pointer to non-sequenced pointer
   1.405 -   void assign_pointer(MemPointerRecord*dest, const MemPointerRecord* src);
   1.406 -
   1.407 -   bool promote_malloc_records(MemPointerArrayIterator* itr);
   1.408 -   bool promote_virtual_memory_records(MemPointerArrayIterator* itr);
   1.409 -};
   1.410 -
   1.411 -#endif // SHARE_VM_SERVICES_MEM_SNAPSHOT_HPP

mercurial