Mon, 05 Nov 2012 15:30:22 -0500
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 }