53 return 1; 54 } 55 } 56 57 // Sort into allocation site addresses order for baseline comparison 58 int compare_malloc_site(const MallocSite& s1, const MallocSite& s2) { 59 return s1.call_stack()->compare(*s2.call_stack()); 60 } 61 62 63 int compare_virtual_memory_site(const VirtualMemoryAllocationSite& s1, 64 const VirtualMemoryAllocationSite& s2) { 65 return s1.call_stack()->compare(*s2.call_stack()); 66 } 67 68 /* 69 * Walker to walk malloc allocation site table 70 */ 71 class MallocAllocationSiteWalker : public MallocSiteWalker { 72 private: 73 SortedLinkedList<MallocSite, compare_malloc_size, ResourceObj::ARENA> 74 _malloc_sites; 75 size_t _count; 76 77 // Entries in MallocSiteTable with size = 0 and count = 0, 78 // when the malloc site is not longer there. 79 public: 80 MallocAllocationSiteWalker(Arena* arena) : _count(0), _malloc_sites(arena) { 81 } 82 83 inline size_t count() const { return _count; } 84 85 LinkedList<MallocSite>* malloc_sites() { 86 return &_malloc_sites; 87 } 88 89 bool do_malloc_site(const MallocSite* site) { 90 if (site->size() >= MemBaseline::SIZE_THRESHOLD) { 91 if (_malloc_sites.add(*site) != NULL) { 92 _count++; 93 return true; 94 } else { 95 return false; // OOM 96 } 97 } else { 98 // malloc site does not meet threshold, ignore and continue 99 return true; 100 } 101 } 102 }; 103 104 // Compare virtual memory region's base address 105 int compare_virtual_memory_base(const ReservedMemoryRegion& r1, const ReservedMemoryRegion& r2) { 106 return r1.compare(r2); 107 } 108 109 // Walk all virtual memory regions for baselining 110 class VirtualMemoryAllocationWalker : public VirtualMemoryWalker { 111 private: 112 SortedLinkedList<ReservedMemoryRegion, compare_virtual_memory_base, ResourceObj::ARENA> 113 _virtual_memory_regions; 114 size_t _count; 115 116 public: 117 VirtualMemoryAllocationWalker(Arena* a) : _count(0), _virtual_memory_regions(a) { 118 } 119 120 bool do_allocation_site(const ReservedMemoryRegion* rgn) { 121 if (rgn->size() >= MemBaseline::SIZE_THRESHOLD) { 122 if (_virtual_memory_regions.add(*rgn) != NULL) { 123 _count ++; 124 return true; 125 } else { 126 return false; 127 } 128 } 129 return true; 130 } 131 132 LinkedList<ReservedMemoryRegion>* virtual_memory_allocations() { 133 return &_virtual_memory_regions; 134 } 135 }; 136 137 138 bool MemBaseline::baseline_summary() { 139 assert(_malloc_memory_snapshot == NULL, "Malloc baseline not yet reset"); 140 assert(_virtual_memory_snapshot == NULL, "Virtual baseline not yet reset"); 141 142 _malloc_memory_snapshot = new (arena()) MallocMemorySnapshot(); 143 _virtual_memory_snapshot = new (arena()) VirtualMemorySnapshot(); 144 if (_malloc_memory_snapshot == NULL || _virtual_memory_snapshot == NULL) { 145 return false; 146 } 147 MallocMemorySummary::snapshot(_malloc_memory_snapshot); 148 VirtualMemorySummary::snapshot(_virtual_memory_snapshot); 149 return true; 150 } 151 152 bool MemBaseline::baseline_allocation_sites() { 153 assert(arena() != NULL, "Just check"); 154 // Malloc allocation sites 155 MallocAllocationSiteWalker malloc_walker(arena()); 156 if (!MallocSiteTable::walk_malloc_site(&malloc_walker)) { 157 return false; 158 } 159 160 _malloc_sites.set_head(malloc_walker.malloc_sites()->head()); 161 // The malloc sites are collected in size order 162 _malloc_sites_order = by_size; 163 164 // Virtual memory allocation sites 165 VirtualMemoryAllocationWalker virtual_memory_walker(arena()); 166 if (!VirtualMemoryTracker::walk_virtual_memory(&virtual_memory_walker)) { 167 return false; 168 } 169 170 // Virtual memory allocations are collected in call stack order 171 _virtual_memory_allocations.set_head(virtual_memory_walker.virtual_memory_allocations()->head()); 172 173 if (!aggregate_virtual_memory_allocation_sites()) { 174 return false; 175 } 176 // Virtual memory allocation sites are aggregrated in call stack order 177 _virtual_memory_sites_order = by_address; 178 179 return true; 180 } 181 182 bool MemBaseline::baseline(bool summaryOnly) { 183 if (arena() == NULL) { 184 _arena = new (std::nothrow, mtNMT) Arena(mtNMT); 185 if (arena() == NULL) return false; 186 } 187 188 reset(); 189 190 _class_count = InstanceKlass::number_of_instance_classes(); 191 192 if (!baseline_summary()) { 193 return false; 194 } 195 196 _baseline_type = Summary_baselined; 197 198 // baseline details 199 if (!summaryOnly && 200 MemTracker::tracking_level() == NMT_detail) { 201 baseline_allocation_sites(); 202 _baseline_type = Detail_baselined; 203 } 204 205 return true; 206 } 207 208 int compare_allocation_site(const VirtualMemoryAllocationSite& s1, 209 const VirtualMemoryAllocationSite& s2) { 210 return s1.call_stack()->compare(*s2.call_stack()); 211 } 212 213 bool MemBaseline::aggregate_virtual_memory_allocation_sites() { 214 SortedLinkedList<VirtualMemoryAllocationSite, compare_allocation_site, ResourceObj::ARENA> 215 allocation_sites(arena()); 216 217 VirtualMemoryAllocationIterator itr = virtual_memory_allocations(); 218 const ReservedMemoryRegion* rgn; 219 VirtualMemoryAllocationSite* site; 220 while ((rgn = itr.next()) != NULL) { 221 VirtualMemoryAllocationSite tmp(*rgn->call_stack()); 222 site = allocation_sites.find(tmp); 223 if (site == NULL) { 224 LinkedListNode<VirtualMemoryAllocationSite>* node = 225 allocation_sites.add(tmp); 226 if (node == NULL) return false; 227 site = node->data(); 228 } 229 site->reserve_memory(rgn->size()); 230 site->commit_memory(rgn->committed_size()); 231 } 232 233 _virtual_memory_sites.set_head(allocation_sites.head()); 234 return true; 235 } 236 237 MallocSiteIterator MemBaseline::malloc_sites(SortingOrder order) { 238 assert(!_malloc_sites.is_empty(), "Detail baseline?"); 239 switch(order) { 240 case by_size: 241 malloc_sites_to_size_order(); 242 break; 243 case by_site: 244 malloc_sites_to_allocation_site_order(); 245 break; 246 case by_address: 247 default: 248 ShouldNotReachHere(); 249 } 250 return MallocSiteIterator(_malloc_sites.head()); 251 } 252 253 VirtualMemorySiteIterator MemBaseline::virtual_memory_sites(SortingOrder order) { 254 assert(!_virtual_memory_sites.is_empty(), "Detail baseline?"); 255 switch(order) { 256 case by_size: 257 virtual_memory_sites_to_size_order(); 258 break; 259 case by_site: 260 virtual_memory_sites_to_reservation_site_order(); 261 break; 262 case by_address: 263 default: 264 ShouldNotReachHere(); 265 } 266 return VirtualMemorySiteIterator(_virtual_memory_sites.head()); 267 } 268 269 270 // Sorting allocations sites in different orders 271 void MemBaseline::malloc_sites_to_size_order() { 272 if (_malloc_sites_order != by_size) { 273 SortedLinkedList<MallocSite, compare_malloc_size, ResourceObj::ARENA> 274 tmp(arena()); 275 276 // Add malloc sites to sorted linked list to sort into size order 277 tmp.move(&_malloc_sites); 278 _malloc_sites.set_head(tmp.head()); 279 tmp.set_head(NULL); 280 _malloc_sites_order = by_size; 281 } 282 } 283 284 void MemBaseline::malloc_sites_to_allocation_site_order() { 285 if (_malloc_sites_order != by_site) { 286 SortedLinkedList<MallocSite, compare_malloc_site, ResourceObj::ARENA> 287 tmp(arena()); 288 // Add malloc sites to sorted linked list to sort into site (address) order 289 tmp.move(&_malloc_sites); 290 _malloc_sites.set_head(tmp.head()); 291 tmp.set_head(NULL); 292 _malloc_sites_order = by_site; 293 } 294 } 295 296 void MemBaseline::virtual_memory_sites_to_size_order() { 297 if (_virtual_memory_sites_order != by_size) { 298 SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_size, ResourceObj::ARENA> 299 tmp(arena()); 300 301 tmp.move(&_virtual_memory_sites); 302 303 _virtual_memory_sites.set_head(tmp.head()); 304 tmp.set_head(NULL); 305 _virtual_memory_sites_order = by_size; 306 } 307 } 308 309 void MemBaseline::virtual_memory_sites_to_reservation_site_order() { 310 if (_virtual_memory_sites_order != by_size) { 311 SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_site, ResourceObj::ARENA> 312 tmp(arena()); 313 314 tmp.add(&_virtual_memory_sites); 315 316 _virtual_memory_sites.set_head(tmp.head()); 317 tmp.set_head(NULL); 318 319 _virtual_memory_sites_order = by_size; 320 } 321 } 322 | 53 return 1; 54 } 55 } 56 57 // Sort into allocation site addresses order for baseline comparison 58 int compare_malloc_site(const MallocSite& s1, const MallocSite& s2) { 59 return s1.call_stack()->compare(*s2.call_stack()); 60 } 61 62 63 int compare_virtual_memory_site(const VirtualMemoryAllocationSite& s1, 64 const VirtualMemoryAllocationSite& s2) { 65 return s1.call_stack()->compare(*s2.call_stack()); 66 } 67 68 /* 69 * Walker to walk malloc allocation site table 70 */ 71 class MallocAllocationSiteWalker : public MallocSiteWalker { 72 private: 73 SortedLinkedList<MallocSite, compare_malloc_size> _malloc_sites; 74 size_t _count; 75 76 // Entries in MallocSiteTable with size = 0 and count = 0, 77 // when the malloc site is not longer there. 78 public: 79 MallocAllocationSiteWalker() : _count(0) { } 80 81 inline size_t count() const { return _count; } 82 83 LinkedList<MallocSite>* malloc_sites() { 84 return &_malloc_sites; 85 } 86 87 bool do_malloc_site(const MallocSite* site) { 88 if (site->size() >= MemBaseline::SIZE_THRESHOLD) { 89 if (_malloc_sites.add(*site) != NULL) { 90 _count++; 91 return true; 92 } else { 93 return false; // OOM 94 } 95 } else { 96 // malloc site does not meet threshold, ignore and continue 97 return true; 98 } 99 } 100 }; 101 102 // Compare virtual memory region's base address 103 int compare_virtual_memory_base(const ReservedMemoryRegion& r1, const ReservedMemoryRegion& r2) { 104 return r1.compare(r2); 105 } 106 107 // Walk all virtual memory regions for baselining 108 class VirtualMemoryAllocationWalker : public VirtualMemoryWalker { 109 private: 110 SortedLinkedList<ReservedMemoryRegion, compare_virtual_memory_base> 111 _virtual_memory_regions; 112 size_t _count; 113 114 public: 115 VirtualMemoryAllocationWalker() : _count(0) { } 116 117 bool do_allocation_site(const ReservedMemoryRegion* rgn) { 118 if (rgn->size() >= MemBaseline::SIZE_THRESHOLD) { 119 if (_virtual_memory_regions.add(*rgn) != NULL) { 120 _count ++; 121 return true; 122 } else { 123 return false; 124 } 125 } 126 return true; 127 } 128 129 LinkedList<ReservedMemoryRegion>* virtual_memory_allocations() { 130 return &_virtual_memory_regions; 131 } 132 }; 133 134 135 bool MemBaseline::baseline_summary() { 136 MallocMemorySummary::snapshot(&_malloc_memory_snapshot); 137 VirtualMemorySummary::snapshot(&_virtual_memory_snapshot); 138 return true; 139 } 140 141 bool MemBaseline::baseline_allocation_sites() { 142 // Malloc allocation sites 143 MallocAllocationSiteWalker malloc_walker; 144 if (!MallocSiteTable::walk_malloc_site(&malloc_walker)) { 145 return false; 146 } 147 148 _malloc_sites.move(malloc_walker.malloc_sites()); 149 // The malloc sites are collected in size order 150 _malloc_sites_order = by_size; 151 152 // Virtual memory allocation sites 153 VirtualMemoryAllocationWalker virtual_memory_walker; 154 if (!VirtualMemoryTracker::walk_virtual_memory(&virtual_memory_walker)) { 155 return false; 156 } 157 158 // Virtual memory allocations are collected in call stack order 159 _virtual_memory_allocations.move(virtual_memory_walker.virtual_memory_allocations()); 160 161 if (!aggregate_virtual_memory_allocation_sites()) { 162 return false; 163 } 164 // Virtual memory allocation sites are aggregrated in call stack order 165 _virtual_memory_sites_order = by_address; 166 167 return true; 168 } 169 170 bool MemBaseline::baseline(bool summaryOnly) { 171 reset(); 172 173 _class_count = InstanceKlass::number_of_instance_classes(); 174 175 if (!baseline_summary()) { 176 return false; 177 } 178 179 _baseline_type = Summary_baselined; 180 181 // baseline details 182 if (!summaryOnly && 183 MemTracker::tracking_level() == NMT_detail) { 184 baseline_allocation_sites(); 185 _baseline_type = Detail_baselined; 186 } 187 188 return true; 189 } 190 191 int compare_allocation_site(const VirtualMemoryAllocationSite& s1, 192 const VirtualMemoryAllocationSite& s2) { 193 return s1.call_stack()->compare(*s2.call_stack()); 194 } 195 196 bool MemBaseline::aggregate_virtual_memory_allocation_sites() { 197 SortedLinkedList<VirtualMemoryAllocationSite, compare_allocation_site> allocation_sites; 198 199 VirtualMemoryAllocationIterator itr = virtual_memory_allocations(); 200 const ReservedMemoryRegion* rgn; 201 VirtualMemoryAllocationSite* site; 202 while ((rgn = itr.next()) != NULL) { 203 VirtualMemoryAllocationSite tmp(*rgn->call_stack()); 204 site = allocation_sites.find(tmp); 205 if (site == NULL) { 206 LinkedListNode<VirtualMemoryAllocationSite>* node = 207 allocation_sites.add(tmp); 208 if (node == NULL) return false; 209 site = node->data(); 210 } 211 site->reserve_memory(rgn->size()); 212 site->commit_memory(rgn->committed_size()); 213 } 214 215 _virtual_memory_sites.move(&allocation_sites); 216 return true; 217 } 218 219 MallocSiteIterator MemBaseline::malloc_sites(SortingOrder order) { 220 assert(!_malloc_sites.is_empty(), "Not detail baseline"); 221 switch(order) { 222 case by_size: 223 malloc_sites_to_size_order(); 224 break; 225 case by_site: 226 malloc_sites_to_allocation_site_order(); 227 break; 228 case by_address: 229 default: 230 ShouldNotReachHere(); 231 } 232 return MallocSiteIterator(_malloc_sites.head()); 233 } 234 235 VirtualMemorySiteIterator MemBaseline::virtual_memory_sites(SortingOrder order) { 236 assert(!_virtual_memory_sites.is_empty(), "Not detail baseline"); 237 switch(order) { 238 case by_size: 239 virtual_memory_sites_to_size_order(); 240 break; 241 case by_site: 242 virtual_memory_sites_to_reservation_site_order(); 243 break; 244 case by_address: 245 default: 246 ShouldNotReachHere(); 247 } 248 return VirtualMemorySiteIterator(_virtual_memory_sites.head()); 249 } 250 251 252 // Sorting allocations sites in different orders 253 void MemBaseline::malloc_sites_to_size_order() { 254 if (_malloc_sites_order != by_size) { 255 SortedLinkedList<MallocSite, compare_malloc_size> tmp; 256 257 // Add malloc sites to sorted linked list to sort into size order 258 tmp.move(&_malloc_sites); 259 _malloc_sites.set_head(tmp.head()); 260 tmp.set_head(NULL); 261 _malloc_sites_order = by_size; 262 } 263 } 264 265 void MemBaseline::malloc_sites_to_allocation_site_order() { 266 if (_malloc_sites_order != by_site) { 267 SortedLinkedList<MallocSite, compare_malloc_site> tmp; 268 // Add malloc sites to sorted linked list to sort into site (address) order 269 tmp.move(&_malloc_sites); 270 _malloc_sites.set_head(tmp.head()); 271 tmp.set_head(NULL); 272 _malloc_sites_order = by_site; 273 } 274 } 275 276 void MemBaseline::virtual_memory_sites_to_size_order() { 277 if (_virtual_memory_sites_order != by_size) { 278 SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_size> tmp; 279 280 tmp.move(&_virtual_memory_sites); 281 282 _virtual_memory_sites.set_head(tmp.head()); 283 tmp.set_head(NULL); 284 _virtual_memory_sites_order = by_size; 285 } 286 } 287 288 void MemBaseline::virtual_memory_sites_to_reservation_site_order() { 289 if (_virtual_memory_sites_order != by_size) { 290 SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_site> tmp; 291 292 tmp.move(&_virtual_memory_sites); 293 294 _virtual_memory_sites.set_head(tmp.head()); 295 tmp.set_head(NULL); 296 297 _virtual_memory_sites_order = by_size; 298 } 299 } 300 |