src/share/vm/services/memSnapshot.hpp

changeset 4193
716c64bda5ba
parent 4053
33143ee07800
child 4274
fb3190e77d3c
     1.1 --- a/src/share/vm/services/memSnapshot.hpp	Thu Oct 18 13:09:47 2012 -0400
     1.2 +++ b/src/share/vm/services/memSnapshot.hpp	Fri Oct 19 21:40:07 2012 -0400
     1.3 @@ -111,33 +111,41 @@
     1.4        MemPointerIterator(arr) {
     1.5    }
     1.6  
     1.7 -  // locate an existing record that contains specified address, or
     1.8 -  // the record, where the record with specified address, should
     1.9 -  // be inserted.
    1.10 -  // virtual memory record array is sorted in address order, so
    1.11 -  // binary search is performed
    1.12 +  // locate an existing reserved memory region that contains specified address,
    1.13 +  // or the reserved region just above this address, where the incoming
    1.14 +  // reserved region should be inserted.
    1.15    virtual MemPointer* locate(address addr) {
    1.16 -    int index_low = 0;
    1.17 -    int index_high = _array->length();
    1.18 -    int index_mid = (index_high + index_low) / 2;
    1.19 -    int r = 1;
    1.20 -    while (index_low < index_high && (r = compare(index_mid, addr)) != 0) {
    1.21 -      if (r > 0) {
    1.22 -        index_high = index_mid;
    1.23 -      } else {
    1.24 -        index_low = index_mid;
    1.25 +    reset();
    1.26 +    VMMemRegion* reg = (VMMemRegion*)current();
    1.27 +    while (reg != NULL) {
    1.28 +      if (reg->is_reserved_region()) {
    1.29 +        if (reg->contains_address(addr) || addr < reg->base()) {
    1.30 +          return reg;
    1.31        }
    1.32 -      index_mid = (index_high + index_low) / 2;
    1.33      }
    1.34 -    if (r == 0) {
    1.35 -      // update current location
    1.36 -      _pos = index_mid;
    1.37 -      return _array->at(index_mid);
    1.38 -    } else {
    1.39 +      reg = (VMMemRegion*)next();
    1.40 +    }
    1.41        return NULL;
    1.42      }
    1.43 -  }
    1.44  
    1.45 +  // following methods update virtual memory in the context
    1.46 +  // of 'current' position, which is properly positioned by
    1.47 +  // callers via locate method.
    1.48 +  bool add_reserved_region(MemPointerRecord* rec);
    1.49 +  bool add_committed_region(MemPointerRecord* rec);
    1.50 +  bool remove_uncommitted_region(MemPointerRecord* rec);
    1.51 +  bool remove_released_region(MemPointerRecord* rec);
    1.52 +
    1.53 +  // split a reserved region to create a new memory region with specified base and size
    1.54 +  bool split_reserved_region(VMMemRegion* rgn, address new_rgn_addr, size_t new_rgn_size);
    1.55 + private:
    1.56 +  bool insert_record(MemPointerRecord* rec);
    1.57 +  bool insert_record_after(MemPointerRecord* rec);
    1.58 +
    1.59 +  bool insert_reserved_region(MemPointerRecord* rec);
    1.60 +
    1.61 +  // reset current position
    1.62 +  inline void reset() { _pos = 0; }
    1.63  #ifdef ASSERT
    1.64    virtual bool is_dup_pointer(const MemPointer* ptr1,
    1.65      const MemPointer* ptr2) const {
    1.66 @@ -154,32 +162,17 @@
    1.67             (p1->flags() & MemPointerRecord::tag_masks) == MemPointerRecord::tag_release;
    1.68    }
    1.69  #endif
    1.70 -  // compare if an address falls into a memory region,
    1.71 -  // return 0, if the address falls into a memory region at specified index
    1.72 -  // return 1, if memory region pointed by specified index is higher than the address
    1.73 -  // return -1, if memory region pointed by specified index is lower than the address
    1.74 -  int compare(int index, address addr) const {
    1.75 -    VMMemRegion* r = (VMMemRegion*)_array->at(index);
    1.76 -    assert(r->is_reserve_record(), "Sanity check");
    1.77 -    if (r->addr() > addr) {
    1.78 -      return 1;
    1.79 -    } else if (r->addr() + r->reserved_size() <= addr) {
    1.80 -      return -1;
    1.81 -    } else {
    1.82 -      return 0;
    1.83 -    }
    1.84 -  }
    1.85  };
    1.86  
    1.87  class MallocRecordIterator : public MemPointerArrayIterator {
    1.88 - private:
    1.89 + protected:
    1.90    MemPointerArrayIteratorImpl  _itr;
    1.91  
    1.92   public:
    1.93    MallocRecordIterator(MemPointerArray* arr) : _itr(arr) {
    1.94    }
    1.95  
    1.96 -  MemPointer* current() const {
    1.97 +  virtual MemPointer* current() const {
    1.98      MemPointerRecord* cur = (MemPointerRecord*)_itr.current();
    1.99      assert(cur == NULL || !cur->is_vm_pointer(), "seek error");
   1.100      MemPointerRecord* next = (MemPointerRecord*)_itr.peek_next();
   1.101 @@ -194,7 +187,7 @@
   1.102      }
   1.103    }
   1.104  
   1.105 -  MemPointer* next() {
   1.106 +  virtual MemPointer* next() {
   1.107      MemPointerRecord* cur = (MemPointerRecord*)_itr.current();
   1.108      assert(cur == NULL || !cur->is_vm_pointer(), "Sanity check");
   1.109      MemPointerRecord* next = (MemPointerRecord*)_itr.next();
   1.110 @@ -214,6 +207,63 @@
   1.111    bool insert_after(MemPointer* ptr) { ShouldNotReachHere(); return false; }
   1.112  };
   1.113  
   1.114 +// collapse duplicated records. Eliminating duplicated records here, is much
   1.115 +// cheaper than during promotion phase. However, it does have limitation - it
   1.116 +// can only eliminate duplicated records within the generation, there are
   1.117 +// still chances seeing duplicated records during promotion.
   1.118 +// We want to use the record with higher sequence number, because it has
   1.119 +// more accurate callsite pc.
   1.120 +class VMRecordIterator : public MallocRecordIterator {
   1.121 + public:
   1.122 +  VMRecordIterator(MemPointerArray* arr) : MallocRecordIterator(arr) {
   1.123 +    MemPointerRecord* cur = (MemPointerRecord*)_itr.current();
   1.124 +    MemPointerRecord* next = (MemPointerRecord*)_itr.peek_next();
   1.125 +    while (next != NULL) {
   1.126 +      assert(cur != NULL, "Sanity check");
   1.127 +      assert(((SeqMemPointerRecord*)next)->seq() > ((SeqMemPointerRecord*)cur)->seq(),
   1.128 +        "pre-sort order");
   1.129 +
   1.130 +      if (is_duplicated_record(cur, next)) {
   1.131 +        _itr.next();
   1.132 +        next = (MemPointerRecord*)_itr.peek_next();
   1.133 +      } else {
   1.134 +        break;
   1.135 +      }
   1.136 +    }
   1.137 +  }
   1.138 +
   1.139 +  virtual MemPointer* current() const {
   1.140 +    return _itr.current();
   1.141 +  }
   1.142 +
   1.143 +  // get next record, but skip the duplicated records
   1.144 +  virtual MemPointer* next() {
   1.145 +    MemPointerRecord* cur = (MemPointerRecord*)_itr.next();
   1.146 +    MemPointerRecord* next = (MemPointerRecord*)_itr.peek_next();
   1.147 +    while (next != NULL) {
   1.148 +      assert(cur != NULL, "Sanity check");
   1.149 +      assert(((SeqMemPointerRecord*)next)->seq() > ((SeqMemPointerRecord*)cur)->seq(),
   1.150 +        "pre-sort order");
   1.151 +
   1.152 +      if (is_duplicated_record(cur, next)) {
   1.153 +        _itr.next();
   1.154 +        cur = next;
   1.155 +        next = (MemPointerRecord*)_itr.peek_next();
   1.156 +      } else {
   1.157 +        break;
   1.158 +      }
   1.159 +    }
   1.160 +    return cur;
   1.161 +  }
   1.162 +
   1.163 + private:
   1.164 +  bool is_duplicated_record(MemPointerRecord* p1, MemPointerRecord* p2) const {
   1.165 +    bool ret = (p1->addr() == p2->addr() && p1->size() == p2->size() && p1->flags() == p2->flags());
   1.166 +    assert(!(ret && FLAGS_TO_MEMORY_TYPE(p1->flags()) == mtThreadStack), "dup on stack record");
   1.167 +    return ret;
   1.168 +  }
   1.169 +};
   1.170 +
   1.171  class StagingArea : public _ValueObj {
   1.172   private:
   1.173    MemPointerArray*   _malloc_data;
   1.174 @@ -233,7 +283,8 @@
   1.175      return MallocRecordIterator(malloc_data());
   1.176    }
   1.177  
   1.178 -  MemPointerArrayIteratorImpl virtual_memory_record_walker();
   1.179 +  VMRecordIterator virtual_memory_record_walker();
   1.180 +
   1.181    bool init();
   1.182    void clear() {
   1.183      assert(_malloc_data != NULL && _vm_data != NULL, "Just check");
   1.184 @@ -293,6 +344,8 @@
   1.185    NOT_PRODUCT(void check_staging_data();)
   1.186    NOT_PRODUCT(void check_malloc_pointers();)
   1.187    NOT_PRODUCT(bool has_allocation_record(address addr);)
   1.188 +  // dump all virtual memory pointers in snapshot
   1.189 +  DEBUG_ONLY( void dump_all_vm_pointers();)
   1.190  
   1.191   private:
   1.192     // copy pointer data from src to dest
   1.193 @@ -302,5 +355,4 @@
   1.194     bool promote_virtual_memory_records(MemPointerArrayIterator* itr);
   1.195  };
   1.196  
   1.197 -
   1.198  #endif // SHARE_VM_SERVICES_MEM_SNAPSHOT_HPP

mercurial