8001591: NMT: assertion failed: assert(rec->addr() + rec->size() <= cur->base()) failed: Can not overlap in memSnapshot.cpp

Mon, 05 Nov 2012 15:30:22 -0500

author
zgu
date
Mon, 05 Nov 2012 15:30:22 -0500
changeset 4248
69ad7823b1ca
parent 4228
e81fbc04a942
child 4249
8940ddc1036f

8001591: NMT: assertion failed: assert(rec->addr() + rec->size() <= cur->base()) failed: Can not overlap in memSnapshot.cpp
Summary: NMT should allow overlapping committed regions as long as they belong to the same reserved region
Reviewed-by: dholmes, coleenp

src/share/vm/services/memPtr.hpp file | annotate | diff | comparison | revisions
src/share/vm/services/memSnapshot.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/services/memPtr.hpp	Thu Oct 25 16:33:40 2012 -0400
     1.2 +++ b/src/share/vm/services/memPtr.hpp	Mon Nov 05 15:30:22 2012 -0500
     1.3 @@ -311,6 +311,17 @@
     1.4    inline bool contains_address(address add) const {
     1.5      return (addr() <= add && addr() + size() > add);
     1.6    }
     1.7 +
     1.8 +  // if this memory region overlaps another region
     1.9 +  inline bool overlaps_region(const MemPointerRecord* other) const {
    1.10 +    assert(other != NULL, "Just check");
    1.11 +    assert(size() > 0 && other->size() > 0, "empty range");
    1.12 +    return contains_address(other->addr()) ||
    1.13 +           contains_address(other->addr() + other->size() - 1) || // exclude end address
    1.14 +           other->contains_address(addr()) ||
    1.15 +           other->contains_address(addr() + size() - 1); // exclude end address
    1.16 +  }
    1.17 +
    1.18  };
    1.19  
    1.20  // MemPointerRecordEx also records callsite pc, from where
     2.1 --- a/src/share/vm/services/memSnapshot.cpp	Thu Oct 25 16:33:40 2012 -0400
     2.2 +++ b/src/share/vm/services/memSnapshot.cpp	Mon Nov 05 15:30:22 2012 -0500
     2.3 @@ -31,6 +31,69 @@
     2.4  #include "services/memSnapshot.hpp"
     2.5  #include "services/memTracker.hpp"
     2.6  
     2.7 +#ifdef ASSERT
     2.8 +
     2.9 +void decode_pointer_record(MemPointerRecord* rec) {
    2.10 +  tty->print("Pointer: [" PTR_FORMAT " - " PTR_FORMAT  "] size = %d bytes", rec->addr(),
    2.11 +    rec->addr() + rec->size(), (int)rec->size());
    2.12 +  tty->print(" type = %s", MemBaseline::type2name(FLAGS_TO_MEMORY_TYPE(rec->flags())));
    2.13 +  if (rec->is_vm_pointer()) {
    2.14 +    if (rec->is_allocation_record()) {
    2.15 +      tty->print_cr(" (reserve)");
    2.16 +    } else if (rec->is_commit_record()) {
    2.17 +      tty->print_cr(" (commit)");
    2.18 +    } else if (rec->is_uncommit_record()) {
    2.19 +      tty->print_cr(" (uncommit)");
    2.20 +    } else if (rec->is_deallocation_record()) {
    2.21 +      tty->print_cr(" (release)");
    2.22 +    } else {
    2.23 +      tty->print_cr(" (tag)");
    2.24 +    }
    2.25 +  } else {
    2.26 +    if (rec->is_arena_size_record()) {
    2.27 +      tty->print_cr(" (arena size)");
    2.28 +    } else if (rec->is_allocation_record()) {
    2.29 +      tty->print_cr(" (malloc)");
    2.30 +    } else {
    2.31 +      tty->print_cr(" (free)");
    2.32 +    }
    2.33 +  }
    2.34 +  if (MemTracker::track_callsite()) {
    2.35 +    char buf[1024];
    2.36 +    address pc = ((MemPointerRecordEx*)rec)->pc();
    2.37 +    if (pc != NULL && os::dll_address_to_function_name(pc, buf, sizeof(buf), NULL)) {
    2.38 +      tty->print_cr("\tfrom %s", buf);
    2.39 +    } else {
    2.40 +      tty->print_cr("\tcould not decode pc = " PTR_FORMAT "", pc);
    2.41 +    }
    2.42 +  }
    2.43 +}
    2.44 +
    2.45 +void decode_vm_region_record(VMMemRegion* rec) {
    2.46 +  tty->print("VM Region [" PTR_FORMAT " - " PTR_FORMAT "]", rec->addr(),
    2.47 +    rec->addr() + rec->size());
    2.48 +  tty->print(" type = %s", MemBaseline::type2name(FLAGS_TO_MEMORY_TYPE(rec->flags())));
    2.49 +  if (rec->is_allocation_record()) {
    2.50 +    tty->print_cr(" (reserved)");
    2.51 +  } else if (rec->is_commit_record()) {
    2.52 +    tty->print_cr(" (committed)");
    2.53 +  } else {
    2.54 +    ShouldNotReachHere();
    2.55 +  }
    2.56 +  if (MemTracker::track_callsite()) {
    2.57 +    char buf[1024];
    2.58 +    address pc = ((VMMemRegionEx*)rec)->pc();
    2.59 +    if (pc != NULL && os::dll_address_to_function_name(pc, buf, sizeof(buf), NULL)) {
    2.60 +      tty->print_cr("\tfrom %s", buf);
    2.61 +    } else {
    2.62 +      tty->print_cr("\tcould not decode pc = " PTR_FORMAT "", pc);
    2.63 +    }
    2.64 +
    2.65 +  }
    2.66 +}
    2.67 +
    2.68 +#endif
    2.69 +
    2.70  
    2.71  bool VMMemPointerIterator::insert_record(MemPointerRecord* rec) {
    2.72    VMMemRegionEx new_rec;
    2.73 @@ -73,52 +136,61 @@
    2.74      return true;
    2.75    }
    2.76    assert(cur->base() > rec->addr(), "Just check: locate()");
    2.77 -  assert(rec->addr() + rec->size() <= cur->base(), "Can not overlap");
    2.78 +  assert(!cur->overlaps_region(rec), "overlapping reserved regions");
    2.79    return insert_record(rec);
    2.80  }
    2.81  
    2.82  // we do consolidate committed regions
    2.83  bool VMMemPointerIterator::add_committed_region(MemPointerRecord* rec) {
    2.84    assert(rec->is_commit_record(), "Sanity check");
    2.85 -  VMMemRegion* cur;
    2.86 -  cur = (VMMemRegion*)current();
    2.87 -  assert(cur->is_reserved_region() && cur->contains_region(rec),
    2.88 +  VMMemRegion* reserved_rgn = (VMMemRegion*)current();
    2.89 +  assert(reserved_rgn->is_reserved_region() && reserved_rgn->contains_region(rec),
    2.90      "Sanity check");
    2.91  
    2.92    // thread's native stack is always marked as "committed", ignore
    2.93    // the "commit" operation for creating stack guard pages
    2.94 -  if (FLAGS_TO_MEMORY_TYPE(cur->flags()) == mtThreadStack &&
    2.95 +  if (FLAGS_TO_MEMORY_TYPE(reserved_rgn->flags()) == mtThreadStack &&
    2.96        FLAGS_TO_MEMORY_TYPE(rec->flags()) != mtThreadStack) {
    2.97      return true;
    2.98    }
    2.99  
   2.100 -  cur = (VMMemRegion*)next();
   2.101 -  while (cur != NULL && cur->is_committed_region()) {
   2.102 +  // if the reserved region has any committed regions
   2.103 +  VMMemRegion* committed_rgn  = (VMMemRegion*)next();
   2.104 +  while (committed_rgn != NULL && committed_rgn->is_committed_region()) {
   2.105      // duplicated commit records
   2.106 -    if(cur->contains_region(rec)) {
   2.107 +    if(committed_rgn->contains_region(rec)) {
   2.108        return true;
   2.109 -    }
   2.110 -    if (cur->base() > rec->addr()) {
   2.111 -      // committed regions can not overlap
   2.112 -      assert(rec->addr() + rec->size() <= cur->base(), "Can not overlap");
   2.113 -      if (rec->addr() + rec->size() == cur->base()) {
   2.114 -        cur->expand_region(rec->addr(), rec->size());
   2.115 -        return true;
   2.116 +    } else if (committed_rgn->overlaps_region(rec)) {
   2.117 +      // overlaps front part
   2.118 +      if (rec->addr() < committed_rgn->addr()) {
   2.119 +        committed_rgn->expand_region(rec->addr(),
   2.120 +          committed_rgn->addr() - rec->addr());
   2.121        } else {
   2.122 -        return insert_record(rec);
   2.123 +        // overlaps tail part
   2.124 +        address committed_rgn_end = committed_rgn->addr() +
   2.125 +              committed_rgn->size();
   2.126 +        assert(committed_rgn_end < rec->addr() + rec->size(),
   2.127 +             "overlap tail part");
   2.128 +        committed_rgn->expand_region(committed_rgn_end,
   2.129 +          (rec->addr() + rec->size()) - committed_rgn_end);
   2.130        }
   2.131 -    } else if (cur->base() + cur->size() == rec->addr()) {
   2.132 -      cur->expand_region(rec->addr(), rec->size());
   2.133 +    } else if (committed_rgn->base() + committed_rgn->size() == rec->addr()) {
   2.134 +      // adjunct each other
   2.135 +      committed_rgn->expand_region(rec->addr(), rec->size());
   2.136        VMMemRegion* next_reg = (VMMemRegion*)next();
   2.137        // see if we can consolidate next committed region
   2.138        if (next_reg != NULL && next_reg->is_committed_region() &&
   2.139 -        next_reg->base() == cur->base() + cur->size()) {
   2.140 -          cur->expand_region(next_reg->base(), next_reg->size());
   2.141 +        next_reg->base() == committed_rgn->base() + committed_rgn->size()) {
   2.142 +          committed_rgn->expand_region(next_reg->base(), next_reg->size());
   2.143 +          // delete merged region
   2.144            remove();
   2.145        }
   2.146        return true;
   2.147 +    } else if (committed_rgn->base() > rec->addr()) {
   2.148 +      // found the location, insert this committed region
   2.149 +      return insert_record(rec);
   2.150      }
   2.151 -    cur = (VMMemRegion*)next();
   2.152 +    committed_rgn = (VMMemRegion*)next();
   2.153    }
   2.154    return insert_record(rec);
   2.155  }

mercurial