1.1 --- a/src/share/vm/services/memSnapshot.cpp Thu Oct 25 16:33:40 2012 -0400 1.2 +++ b/src/share/vm/services/memSnapshot.cpp Mon Nov 05 15:30:22 2012 -0500 1.3 @@ -31,6 +31,69 @@ 1.4 #include "services/memSnapshot.hpp" 1.5 #include "services/memTracker.hpp" 1.6 1.7 +#ifdef ASSERT 1.8 + 1.9 +void decode_pointer_record(MemPointerRecord* rec) { 1.10 + tty->print("Pointer: [" PTR_FORMAT " - " PTR_FORMAT "] size = %d bytes", rec->addr(), 1.11 + rec->addr() + rec->size(), (int)rec->size()); 1.12 + tty->print(" type = %s", MemBaseline::type2name(FLAGS_TO_MEMORY_TYPE(rec->flags()))); 1.13 + if (rec->is_vm_pointer()) { 1.14 + if (rec->is_allocation_record()) { 1.15 + tty->print_cr(" (reserve)"); 1.16 + } else if (rec->is_commit_record()) { 1.17 + tty->print_cr(" (commit)"); 1.18 + } else if (rec->is_uncommit_record()) { 1.19 + tty->print_cr(" (uncommit)"); 1.20 + } else if (rec->is_deallocation_record()) { 1.21 + tty->print_cr(" (release)"); 1.22 + } else { 1.23 + tty->print_cr(" (tag)"); 1.24 + } 1.25 + } else { 1.26 + if (rec->is_arena_size_record()) { 1.27 + tty->print_cr(" (arena size)"); 1.28 + } else if (rec->is_allocation_record()) { 1.29 + tty->print_cr(" (malloc)"); 1.30 + } else { 1.31 + tty->print_cr(" (free)"); 1.32 + } 1.33 + } 1.34 + if (MemTracker::track_callsite()) { 1.35 + char buf[1024]; 1.36 + address pc = ((MemPointerRecordEx*)rec)->pc(); 1.37 + if (pc != NULL && os::dll_address_to_function_name(pc, buf, sizeof(buf), NULL)) { 1.38 + tty->print_cr("\tfrom %s", buf); 1.39 + } else { 1.40 + tty->print_cr("\tcould not decode pc = " PTR_FORMAT "", pc); 1.41 + } 1.42 + } 1.43 +} 1.44 + 1.45 +void decode_vm_region_record(VMMemRegion* rec) { 1.46 + tty->print("VM Region [" PTR_FORMAT " - " PTR_FORMAT "]", rec->addr(), 1.47 + rec->addr() + rec->size()); 1.48 + tty->print(" type = %s", MemBaseline::type2name(FLAGS_TO_MEMORY_TYPE(rec->flags()))); 1.49 + if (rec->is_allocation_record()) { 1.50 + tty->print_cr(" (reserved)"); 1.51 + } else if (rec->is_commit_record()) { 1.52 + tty->print_cr(" (committed)"); 1.53 + } else { 1.54 + ShouldNotReachHere(); 1.55 + } 1.56 + if (MemTracker::track_callsite()) { 1.57 + char buf[1024]; 1.58 + address pc = ((VMMemRegionEx*)rec)->pc(); 1.59 + if (pc != NULL && os::dll_address_to_function_name(pc, buf, sizeof(buf), NULL)) { 1.60 + tty->print_cr("\tfrom %s", buf); 1.61 + } else { 1.62 + tty->print_cr("\tcould not decode pc = " PTR_FORMAT "", pc); 1.63 + } 1.64 + 1.65 + } 1.66 +} 1.67 + 1.68 +#endif 1.69 + 1.70 1.71 bool VMMemPointerIterator::insert_record(MemPointerRecord* rec) { 1.72 VMMemRegionEx new_rec; 1.73 @@ -73,52 +136,61 @@ 1.74 return true; 1.75 } 1.76 assert(cur->base() > rec->addr(), "Just check: locate()"); 1.77 - assert(rec->addr() + rec->size() <= cur->base(), "Can not overlap"); 1.78 + assert(!cur->overlaps_region(rec), "overlapping reserved regions"); 1.79 return insert_record(rec); 1.80 } 1.81 1.82 // we do consolidate committed regions 1.83 bool VMMemPointerIterator::add_committed_region(MemPointerRecord* rec) { 1.84 assert(rec->is_commit_record(), "Sanity check"); 1.85 - VMMemRegion* cur; 1.86 - cur = (VMMemRegion*)current(); 1.87 - assert(cur->is_reserved_region() && cur->contains_region(rec), 1.88 + VMMemRegion* reserved_rgn = (VMMemRegion*)current(); 1.89 + assert(reserved_rgn->is_reserved_region() && reserved_rgn->contains_region(rec), 1.90 "Sanity check"); 1.91 1.92 // thread's native stack is always marked as "committed", ignore 1.93 // the "commit" operation for creating stack guard pages 1.94 - if (FLAGS_TO_MEMORY_TYPE(cur->flags()) == mtThreadStack && 1.95 + if (FLAGS_TO_MEMORY_TYPE(reserved_rgn->flags()) == mtThreadStack && 1.96 FLAGS_TO_MEMORY_TYPE(rec->flags()) != mtThreadStack) { 1.97 return true; 1.98 } 1.99 1.100 - cur = (VMMemRegion*)next(); 1.101 - while (cur != NULL && cur->is_committed_region()) { 1.102 + // if the reserved region has any committed regions 1.103 + VMMemRegion* committed_rgn = (VMMemRegion*)next(); 1.104 + while (committed_rgn != NULL && committed_rgn->is_committed_region()) { 1.105 // duplicated commit records 1.106 - if(cur->contains_region(rec)) { 1.107 + if(committed_rgn->contains_region(rec)) { 1.108 return true; 1.109 - } 1.110 - if (cur->base() > rec->addr()) { 1.111 - // committed regions can not overlap 1.112 - assert(rec->addr() + rec->size() <= cur->base(), "Can not overlap"); 1.113 - if (rec->addr() + rec->size() == cur->base()) { 1.114 - cur->expand_region(rec->addr(), rec->size()); 1.115 - return true; 1.116 + } else if (committed_rgn->overlaps_region(rec)) { 1.117 + // overlaps front part 1.118 + if (rec->addr() < committed_rgn->addr()) { 1.119 + committed_rgn->expand_region(rec->addr(), 1.120 + committed_rgn->addr() - rec->addr()); 1.121 } else { 1.122 - return insert_record(rec); 1.123 + // overlaps tail part 1.124 + address committed_rgn_end = committed_rgn->addr() + 1.125 + committed_rgn->size(); 1.126 + assert(committed_rgn_end < rec->addr() + rec->size(), 1.127 + "overlap tail part"); 1.128 + committed_rgn->expand_region(committed_rgn_end, 1.129 + (rec->addr() + rec->size()) - committed_rgn_end); 1.130 } 1.131 - } else if (cur->base() + cur->size() == rec->addr()) { 1.132 - cur->expand_region(rec->addr(), rec->size()); 1.133 + } else if (committed_rgn->base() + committed_rgn->size() == rec->addr()) { 1.134 + // adjunct each other 1.135 + committed_rgn->expand_region(rec->addr(), rec->size()); 1.136 VMMemRegion* next_reg = (VMMemRegion*)next(); 1.137 // see if we can consolidate next committed region 1.138 if (next_reg != NULL && next_reg->is_committed_region() && 1.139 - next_reg->base() == cur->base() + cur->size()) { 1.140 - cur->expand_region(next_reg->base(), next_reg->size()); 1.141 + next_reg->base() == committed_rgn->base() + committed_rgn->size()) { 1.142 + committed_rgn->expand_region(next_reg->base(), next_reg->size()); 1.143 + // delete merged region 1.144 remove(); 1.145 } 1.146 return true; 1.147 + } else if (committed_rgn->base() > rec->addr()) { 1.148 + // found the location, insert this committed region 1.149 + return insert_record(rec); 1.150 } 1.151 - cur = (VMMemRegion*)next(); 1.152 + committed_rgn = (VMMemRegion*)next(); 1.153 } 1.154 return insert_record(rec); 1.155 }