1.1 --- a/src/share/vm/services/memSnapshot.cpp Wed Aug 27 09:36:55 2014 +0200 1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 @@ -1,748 +0,0 @@ 1.4 -/* 1.5 - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 - * 1.8 - * This code is free software; you can redistribute it and/or modify it 1.9 - * under the terms of the GNU General Public License version 2 only, as 1.10 - * published by the Free Software Foundation. 1.11 - * 1.12 - * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 - * version 2 for more details (a copy is included in the LICENSE file that 1.16 - * accompanied this code). 1.17 - * 1.18 - * You should have received a copy of the GNU General Public License version 1.19 - * 2 along with this work; if not, write to the Free Software Foundation, 1.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 - * 1.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 - * or visit www.oracle.com if you need additional information or have any 1.24 - * questions. 1.25 - * 1.26 - */ 1.27 - 1.28 -#include "precompiled.hpp" 1.29 -#include "runtime/mutexLocker.hpp" 1.30 -#include "utilities/decoder.hpp" 1.31 -#include "services/memBaseline.hpp" 1.32 -#include "services/memPtr.hpp" 1.33 -#include "services/memPtrArray.hpp" 1.34 -#include "services/memSnapshot.hpp" 1.35 -#include "services/memTracker.hpp" 1.36 - 1.37 -PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC 1.38 - 1.39 -#ifdef ASSERT 1.40 - 1.41 -void decode_pointer_record(MemPointerRecord* rec) { 1.42 - tty->print("Pointer: [" PTR_FORMAT " - " PTR_FORMAT "] size = %d bytes", rec->addr(), 1.43 - rec->addr() + rec->size(), (int)rec->size()); 1.44 - tty->print(" type = %s", MemBaseline::type2name(FLAGS_TO_MEMORY_TYPE(rec->flags()))); 1.45 - if (rec->is_vm_pointer()) { 1.46 - if (rec->is_allocation_record()) { 1.47 - tty->print_cr(" (reserve)"); 1.48 - } else if (rec->is_commit_record()) { 1.49 - tty->print_cr(" (commit)"); 1.50 - } else if (rec->is_uncommit_record()) { 1.51 - tty->print_cr(" (uncommit)"); 1.52 - } else if (rec->is_deallocation_record()) { 1.53 - tty->print_cr(" (release)"); 1.54 - } else { 1.55 - tty->print_cr(" (tag)"); 1.56 - } 1.57 - } else { 1.58 - if (rec->is_arena_memory_record()) { 1.59 - tty->print_cr(" (arena size)"); 1.60 - } else if (rec->is_allocation_record()) { 1.61 - tty->print_cr(" (malloc)"); 1.62 - } else { 1.63 - tty->print_cr(" (free)"); 1.64 - } 1.65 - } 1.66 - if (MemTracker::track_callsite()) { 1.67 - char buf[1024]; 1.68 - address pc = ((MemPointerRecordEx*)rec)->pc(); 1.69 - if (pc != NULL && os::dll_address_to_function_name(pc, buf, sizeof(buf), NULL)) { 1.70 - tty->print_cr("\tfrom %s", buf); 1.71 - } else { 1.72 - tty->print_cr("\tcould not decode pc = " PTR_FORMAT "", pc); 1.73 - } 1.74 - } 1.75 -} 1.76 - 1.77 -void decode_vm_region_record(VMMemRegion* rec) { 1.78 - tty->print("VM Region [" PTR_FORMAT " - " PTR_FORMAT "]", rec->addr(), 1.79 - rec->addr() + rec->size()); 1.80 - tty->print(" type = %s", MemBaseline::type2name(FLAGS_TO_MEMORY_TYPE(rec->flags()))); 1.81 - if (rec->is_allocation_record()) { 1.82 - tty->print_cr(" (reserved)"); 1.83 - } else if (rec->is_commit_record()) { 1.84 - tty->print_cr(" (committed)"); 1.85 - } else { 1.86 - ShouldNotReachHere(); 1.87 - } 1.88 - if (MemTracker::track_callsite()) { 1.89 - char buf[1024]; 1.90 - address pc = ((VMMemRegionEx*)rec)->pc(); 1.91 - if (pc != NULL && os::dll_address_to_function_name(pc, buf, sizeof(buf), NULL)) { 1.92 - tty->print_cr("\tfrom %s", buf); 1.93 - } else { 1.94 - tty->print_cr("\tcould not decode pc = " PTR_FORMAT "", pc); 1.95 - } 1.96 - 1.97 - } 1.98 -} 1.99 - 1.100 -#endif 1.101 - 1.102 - 1.103 -bool VMMemPointerIterator::insert_record(MemPointerRecord* rec) { 1.104 - VMMemRegionEx new_rec; 1.105 - assert(rec->is_allocation_record() || rec->is_commit_record(), 1.106 - "Sanity check"); 1.107 - if (MemTracker::track_callsite()) { 1.108 - new_rec.init((MemPointerRecordEx*)rec); 1.109 - } else { 1.110 - new_rec.init(rec); 1.111 - } 1.112 - return insert(&new_rec); 1.113 -} 1.114 - 1.115 -bool VMMemPointerIterator::insert_record_after(MemPointerRecord* rec) { 1.116 - VMMemRegionEx new_rec; 1.117 - assert(rec->is_allocation_record() || rec->is_commit_record(), 1.118 - "Sanity check"); 1.119 - if (MemTracker::track_callsite()) { 1.120 - new_rec.init((MemPointerRecordEx*)rec); 1.121 - } else { 1.122 - new_rec.init(rec); 1.123 - } 1.124 - return insert_after(&new_rec); 1.125 -} 1.126 - 1.127 -// we don't consolidate reserved regions, since they may be categorized 1.128 -// in different types. 1.129 -bool VMMemPointerIterator::add_reserved_region(MemPointerRecord* rec) { 1.130 - assert(rec->is_allocation_record(), "Sanity check"); 1.131 - VMMemRegion* reserved_region = (VMMemRegion*)current(); 1.132 - 1.133 - // we don't have anything yet 1.134 - if (reserved_region == NULL) { 1.135 - return insert_record(rec); 1.136 - } 1.137 - 1.138 - assert(reserved_region->is_reserved_region(), "Sanity check"); 1.139 - // duplicated records 1.140 - if (reserved_region->is_same_region(rec)) { 1.141 - return true; 1.142 - } 1.143 - // Overlapping stack regions indicate that a JNI thread failed to 1.144 - // detach from the VM before exiting. This leaks the JavaThread object. 1.145 - if (CheckJNICalls) { 1.146 - guarantee(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) != mtThreadStack || 1.147 - !reserved_region->overlaps_region(rec), 1.148 - "Attached JNI thread exited without being detached"); 1.149 - } 1.150 - // otherwise, we should not have overlapping reserved regions 1.151 - assert(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) == mtThreadStack || 1.152 - reserved_region->base() > rec->addr(), "Just check: locate()"); 1.153 - assert(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) == mtThreadStack || 1.154 - !reserved_region->overlaps_region(rec), "overlapping reserved regions"); 1.155 - 1.156 - return insert_record(rec); 1.157 -} 1.158 - 1.159 -// we do consolidate committed regions 1.160 -bool VMMemPointerIterator::add_committed_region(MemPointerRecord* rec) { 1.161 - assert(rec->is_commit_record(), "Sanity check"); 1.162 - VMMemRegion* reserved_rgn = (VMMemRegion*)current(); 1.163 - assert(reserved_rgn->is_reserved_region() && reserved_rgn->contains_region(rec), 1.164 - "Sanity check"); 1.165 - 1.166 - // thread's native stack is always marked as "committed", ignore 1.167 - // the "commit" operation for creating stack guard pages 1.168 - if (FLAGS_TO_MEMORY_TYPE(reserved_rgn->flags()) == mtThreadStack && 1.169 - FLAGS_TO_MEMORY_TYPE(rec->flags()) != mtThreadStack) { 1.170 - return true; 1.171 - } 1.172 - 1.173 - // if the reserved region has any committed regions 1.174 - VMMemRegion* committed_rgn = (VMMemRegion*)next(); 1.175 - while (committed_rgn != NULL && committed_rgn->is_committed_region()) { 1.176 - // duplicated commit records 1.177 - if(committed_rgn->contains_region(rec)) { 1.178 - return true; 1.179 - } else if (committed_rgn->overlaps_region(rec)) { 1.180 - // overlaps front part 1.181 - if (rec->addr() < committed_rgn->addr()) { 1.182 - committed_rgn->expand_region(rec->addr(), 1.183 - committed_rgn->addr() - rec->addr()); 1.184 - } else { 1.185 - // overlaps tail part 1.186 - address committed_rgn_end = committed_rgn->addr() + 1.187 - committed_rgn->size(); 1.188 - assert(committed_rgn_end < rec->addr() + rec->size(), 1.189 - "overlap tail part"); 1.190 - committed_rgn->expand_region(committed_rgn_end, 1.191 - (rec->addr() + rec->size()) - committed_rgn_end); 1.192 - } 1.193 - } else if (committed_rgn->base() + committed_rgn->size() == rec->addr()) { 1.194 - // adjunct each other 1.195 - committed_rgn->expand_region(rec->addr(), rec->size()); 1.196 - VMMemRegion* next_reg = (VMMemRegion*)next(); 1.197 - // see if we can consolidate next committed region 1.198 - if (next_reg != NULL && next_reg->is_committed_region() && 1.199 - next_reg->base() == committed_rgn->base() + committed_rgn->size()) { 1.200 - committed_rgn->expand_region(next_reg->base(), next_reg->size()); 1.201 - // delete merged region 1.202 - remove(); 1.203 - } 1.204 - return true; 1.205 - } else if (committed_rgn->base() > rec->addr()) { 1.206 - // found the location, insert this committed region 1.207 - return insert_record(rec); 1.208 - } 1.209 - committed_rgn = (VMMemRegion*)next(); 1.210 - } 1.211 - return insert_record(rec); 1.212 -} 1.213 - 1.214 -bool VMMemPointerIterator::remove_uncommitted_region(MemPointerRecord* rec) { 1.215 - assert(rec->is_uncommit_record(), "sanity check"); 1.216 - VMMemRegion* cur; 1.217 - cur = (VMMemRegion*)current(); 1.218 - assert(cur->is_reserved_region() && cur->contains_region(rec), 1.219 - "Sanity check"); 1.220 - // thread's native stack is always marked as "committed", ignore 1.221 - // the "commit" operation for creating stack guard pages 1.222 - if (FLAGS_TO_MEMORY_TYPE(cur->flags()) == mtThreadStack && 1.223 - FLAGS_TO_MEMORY_TYPE(rec->flags()) != mtThreadStack) { 1.224 - return true; 1.225 - } 1.226 - 1.227 - cur = (VMMemRegion*)next(); 1.228 - while (cur != NULL && cur->is_committed_region()) { 1.229 - // region already uncommitted, must be due to duplicated record 1.230 - if (cur->addr() >= rec->addr() + rec->size()) { 1.231 - break; 1.232 - } else if (cur->contains_region(rec)) { 1.233 - // uncommit whole region 1.234 - if (cur->is_same_region(rec)) { 1.235 - remove(); 1.236 - break; 1.237 - } else if (rec->addr() == cur->addr() || 1.238 - rec->addr() + rec->size() == cur->addr() + cur->size()) { 1.239 - // uncommitted from either end of current memory region. 1.240 - cur->exclude_region(rec->addr(), rec->size()); 1.241 - break; 1.242 - } else { // split the committed region and release the middle 1.243 - address high_addr = cur->addr() + cur->size(); 1.244 - size_t sz = high_addr - rec->addr(); 1.245 - cur->exclude_region(rec->addr(), sz); 1.246 - sz = high_addr - (rec->addr() + rec->size()); 1.247 - if (MemTracker::track_callsite()) { 1.248 - MemPointerRecordEx tmp(rec->addr() + rec->size(), cur->flags(), sz, 1.249 - ((VMMemRegionEx*)cur)->pc()); 1.250 - return insert_record_after(&tmp); 1.251 - } else { 1.252 - MemPointerRecord tmp(rec->addr() + rec->size(), cur->flags(), sz); 1.253 - return insert_record_after(&tmp); 1.254 - } 1.255 - } 1.256 - } 1.257 - cur = (VMMemRegion*)next(); 1.258 - } 1.259 - 1.260 - // we may not find committed record due to duplicated records 1.261 - return true; 1.262 -} 1.263 - 1.264 -bool VMMemPointerIterator::remove_released_region(MemPointerRecord* rec) { 1.265 - assert(rec->is_deallocation_record(), "Sanity check"); 1.266 - VMMemRegion* cur = (VMMemRegion*)current(); 1.267 - assert(cur->is_reserved_region() && cur->contains_region(rec), 1.268 - "Sanity check"); 1.269 - if (rec->is_same_region(cur)) { 1.270 - 1.271 - // In snapshot, the virtual memory records are sorted in following orders: 1.272 - // 1. virtual memory's base address 1.273 - // 2. virtual memory reservation record, followed by commit records within this reservation. 1.274 - // The commit records are also in base address order. 1.275 - // When a reserved region is released, we want to remove the reservation record and all 1.276 - // commit records following it. 1.277 -#ifdef ASSERT 1.278 - address low_addr = cur->addr(); 1.279 - address high_addr = low_addr + cur->size(); 1.280 -#endif 1.281 - // remove virtual memory reservation record 1.282 - remove(); 1.283 - // remove committed regions within above reservation 1.284 - VMMemRegion* next_region = (VMMemRegion*)current(); 1.285 - while (next_region != NULL && next_region->is_committed_region()) { 1.286 - assert(next_region->addr() >= low_addr && 1.287 - next_region->addr() + next_region->size() <= high_addr, 1.288 - "Range check"); 1.289 - remove(); 1.290 - next_region = (VMMemRegion*)current(); 1.291 - } 1.292 - } else if (rec->addr() == cur->addr() || 1.293 - rec->addr() + rec->size() == cur->addr() + cur->size()) { 1.294 - // released region is at either end of this region 1.295 - cur->exclude_region(rec->addr(), rec->size()); 1.296 - assert(check_reserved_region(), "Integrity check"); 1.297 - } else { // split the reserved region and release the middle 1.298 - address high_addr = cur->addr() + cur->size(); 1.299 - size_t sz = high_addr - rec->addr(); 1.300 - cur->exclude_region(rec->addr(), sz); 1.301 - sz = high_addr - rec->addr() - rec->size(); 1.302 - if (MemTracker::track_callsite()) { 1.303 - MemPointerRecordEx tmp(rec->addr() + rec->size(), cur->flags(), sz, 1.304 - ((VMMemRegionEx*)cur)->pc()); 1.305 - bool ret = insert_reserved_region(&tmp); 1.306 - assert(!ret || check_reserved_region(), "Integrity check"); 1.307 - return ret; 1.308 - } else { 1.309 - MemPointerRecord tmp(rec->addr() + rec->size(), cur->flags(), sz); 1.310 - bool ret = insert_reserved_region(&tmp); 1.311 - assert(!ret || check_reserved_region(), "Integrity check"); 1.312 - return ret; 1.313 - } 1.314 - } 1.315 - return true; 1.316 -} 1.317 - 1.318 -bool VMMemPointerIterator::insert_reserved_region(MemPointerRecord* rec) { 1.319 - // skip all 'commit' records associated with previous reserved region 1.320 - VMMemRegion* p = (VMMemRegion*)next(); 1.321 - while (p != NULL && p->is_committed_region() && 1.322 - p->base() + p->size() < rec->addr()) { 1.323 - p = (VMMemRegion*)next(); 1.324 - } 1.325 - return insert_record(rec); 1.326 -} 1.327 - 1.328 -bool VMMemPointerIterator::split_reserved_region(VMMemRegion* rgn, address new_rgn_addr, size_t new_rgn_size) { 1.329 - assert(rgn->contains_region(new_rgn_addr, new_rgn_size), "Not fully contained"); 1.330 - address pc = (MemTracker::track_callsite() ? ((VMMemRegionEx*)rgn)->pc() : NULL); 1.331 - if (rgn->base() == new_rgn_addr) { // new region is at the beginning of the region 1.332 - size_t sz = rgn->size() - new_rgn_size; 1.333 - // the original region becomes 'new' region 1.334 - rgn->exclude_region(new_rgn_addr + new_rgn_size, sz); 1.335 - // remaining becomes next region 1.336 - MemPointerRecordEx next_rgn(new_rgn_addr + new_rgn_size, rgn->flags(), sz, pc); 1.337 - return insert_reserved_region(&next_rgn); 1.338 - } else if (rgn->base() + rgn->size() == new_rgn_addr + new_rgn_size) { 1.339 - rgn->exclude_region(new_rgn_addr, new_rgn_size); 1.340 - MemPointerRecordEx next_rgn(new_rgn_addr, rgn->flags(), new_rgn_size, pc); 1.341 - return insert_reserved_region(&next_rgn); 1.342 - } else { 1.343 - // the orginal region will be split into three 1.344 - address rgn_high_addr = rgn->base() + rgn->size(); 1.345 - // first region 1.346 - rgn->exclude_region(new_rgn_addr, (rgn_high_addr - new_rgn_addr)); 1.347 - // the second region is the new region 1.348 - MemPointerRecordEx new_rgn(new_rgn_addr, rgn->flags(), new_rgn_size, pc); 1.349 - if (!insert_reserved_region(&new_rgn)) return false; 1.350 - // the remaining region 1.351 - MemPointerRecordEx rem_rgn(new_rgn_addr + new_rgn_size, rgn->flags(), 1.352 - rgn_high_addr - (new_rgn_addr + new_rgn_size), pc); 1.353 - return insert_reserved_region(&rem_rgn); 1.354 - } 1.355 -} 1.356 - 1.357 -static int sort_in_seq_order(const void* p1, const void* p2) { 1.358 - assert(p1 != NULL && p2 != NULL, "Sanity check"); 1.359 - const MemPointerRecord* mp1 = (MemPointerRecord*)p1; 1.360 - const MemPointerRecord* mp2 = (MemPointerRecord*)p2; 1.361 - return (mp1->seq() - mp2->seq()); 1.362 -} 1.363 - 1.364 -bool StagingArea::init() { 1.365 - if (MemTracker::track_callsite()) { 1.366 - _malloc_data = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecordEx>(); 1.367 - _vm_data = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecordEx>(); 1.368 - } else { 1.369 - _malloc_data = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecord>(); 1.370 - _vm_data = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecord>(); 1.371 - } 1.372 - 1.373 - if (_malloc_data != NULL && _vm_data != NULL && 1.374 - !_malloc_data->out_of_memory() && 1.375 - !_vm_data->out_of_memory()) { 1.376 - return true; 1.377 - } else { 1.378 - if (_malloc_data != NULL) delete _malloc_data; 1.379 - if (_vm_data != NULL) delete _vm_data; 1.380 - _malloc_data = NULL; 1.381 - _vm_data = NULL; 1.382 - return false; 1.383 - } 1.384 -} 1.385 - 1.386 - 1.387 -VMRecordIterator StagingArea::virtual_memory_record_walker() { 1.388 - MemPointerArray* arr = vm_data(); 1.389 - // sort into seq number order 1.390 - arr->sort((FN_SORT)sort_in_seq_order); 1.391 - return VMRecordIterator(arr); 1.392 -} 1.393 - 1.394 - 1.395 -MemSnapshot::MemSnapshot() { 1.396 - if (MemTracker::track_callsite()) { 1.397 - _alloc_ptrs = new (std::nothrow) MemPointerArrayImpl<MemPointerRecordEx>(); 1.398 - _vm_ptrs = new (std::nothrow)MemPointerArrayImpl<VMMemRegionEx>(64, true); 1.399 - } else { 1.400 - _alloc_ptrs = new (std::nothrow) MemPointerArrayImpl<MemPointerRecord>(); 1.401 - _vm_ptrs = new (std::nothrow)MemPointerArrayImpl<VMMemRegion>(64, true); 1.402 - } 1.403 - 1.404 - _staging_area.init(); 1.405 - _lock = new (std::nothrow) Mutex(Monitor::max_nonleaf - 1, "memSnapshotLock"); 1.406 - NOT_PRODUCT(_untracked_count = 0;) 1.407 - _number_of_classes = 0; 1.408 -} 1.409 - 1.410 -MemSnapshot::~MemSnapshot() { 1.411 - assert(MemTracker::shutdown_in_progress(), "native memory tracking still on"); 1.412 - { 1.413 - MutexLockerEx locker(_lock); 1.414 - if (_alloc_ptrs != NULL) { 1.415 - delete _alloc_ptrs; 1.416 - _alloc_ptrs = NULL; 1.417 - } 1.418 - 1.419 - if (_vm_ptrs != NULL) { 1.420 - delete _vm_ptrs; 1.421 - _vm_ptrs = NULL; 1.422 - } 1.423 - } 1.424 - 1.425 - if (_lock != NULL) { 1.426 - delete _lock; 1.427 - _lock = NULL; 1.428 - } 1.429 -} 1.430 - 1.431 - 1.432 -void MemSnapshot::copy_seq_pointer(MemPointerRecord* dest, const MemPointerRecord* src) { 1.433 - assert(dest != NULL && src != NULL, "Just check"); 1.434 - assert(dest->addr() == src->addr(), "Just check"); 1.435 - assert(dest->seq() > 0 && src->seq() > 0, "not sequenced"); 1.436 - 1.437 - if (MemTracker::track_callsite()) { 1.438 - *(SeqMemPointerRecordEx*)dest = *(SeqMemPointerRecordEx*)src; 1.439 - } else { 1.440 - *(SeqMemPointerRecord*)dest = *(SeqMemPointerRecord*)src; 1.441 - } 1.442 -} 1.443 - 1.444 -void MemSnapshot::assign_pointer(MemPointerRecord*dest, const MemPointerRecord* src) { 1.445 - assert(src != NULL && dest != NULL, "Just check"); 1.446 - assert(dest->seq() == 0 && src->seq() >0, "cast away sequence"); 1.447 - 1.448 - if (MemTracker::track_callsite()) { 1.449 - *(MemPointerRecordEx*)dest = *(MemPointerRecordEx*)src; 1.450 - } else { 1.451 - *(MemPointerRecord*)dest = *(MemPointerRecord*)src; 1.452 - } 1.453 -} 1.454 - 1.455 -// merge a recorder to the staging area 1.456 -bool MemSnapshot::merge(MemRecorder* rec) { 1.457 - assert(rec != NULL && !rec->out_of_memory(), "Just check"); 1.458 - 1.459 - SequencedRecordIterator itr(rec->pointer_itr()); 1.460 - 1.461 - MutexLockerEx lock(_lock, true); 1.462 - MemPointerIterator malloc_staging_itr(_staging_area.malloc_data()); 1.463 - MemPointerRecord* incoming_rec = (MemPointerRecord*) itr.current(); 1.464 - MemPointerRecord* matched_rec; 1.465 - 1.466 - while (incoming_rec != NULL) { 1.467 - if (incoming_rec->is_vm_pointer()) { 1.468 - // we don't do anything with virtual memory records during merge 1.469 - if (!_staging_area.vm_data()->append(incoming_rec)) { 1.470 - return false; 1.471 - } 1.472 - } else { 1.473 - // locate matched record and/or also position the iterator to proper 1.474 - // location for this incoming record. 1.475 - matched_rec = (MemPointerRecord*)malloc_staging_itr.locate(incoming_rec->addr()); 1.476 - // we have not seen this memory block in this generation, 1.477 - // so just add to staging area 1.478 - if (matched_rec == NULL) { 1.479 - if (!malloc_staging_itr.insert(incoming_rec)) { 1.480 - return false; 1.481 - } 1.482 - } else if (incoming_rec->addr() == matched_rec->addr()) { 1.483 - // whoever has higher sequence number wins 1.484 - if (incoming_rec->seq() > matched_rec->seq()) { 1.485 - copy_seq_pointer(matched_rec, incoming_rec); 1.486 - } 1.487 - } else if (incoming_rec->addr() < matched_rec->addr()) { 1.488 - if (!malloc_staging_itr.insert(incoming_rec)) { 1.489 - return false; 1.490 - } 1.491 - } else { 1.492 - ShouldNotReachHere(); 1.493 - } 1.494 - } 1.495 - incoming_rec = (MemPointerRecord*)itr.next(); 1.496 - } 1.497 - NOT_PRODUCT(void check_staging_data();) 1.498 - return true; 1.499 -} 1.500 - 1.501 - 1.502 -// promote data to next generation 1.503 -bool MemSnapshot::promote(int number_of_classes) { 1.504 - assert(_alloc_ptrs != NULL && _vm_ptrs != NULL, "Just check"); 1.505 - assert(_staging_area.malloc_data() != NULL && _staging_area.vm_data() != NULL, 1.506 - "Just check"); 1.507 - MutexLockerEx lock(_lock, true); 1.508 - 1.509 - MallocRecordIterator malloc_itr = _staging_area.malloc_record_walker(); 1.510 - bool promoted = false; 1.511 - if (promote_malloc_records(&malloc_itr)) { 1.512 - VMRecordIterator vm_itr = _staging_area.virtual_memory_record_walker(); 1.513 - if (promote_virtual_memory_records(&vm_itr)) { 1.514 - promoted = true; 1.515 - } 1.516 - } 1.517 - 1.518 - NOT_PRODUCT(check_malloc_pointers();) 1.519 - _staging_area.clear(); 1.520 - _number_of_classes = number_of_classes; 1.521 - return promoted; 1.522 -} 1.523 - 1.524 -bool MemSnapshot::promote_malloc_records(MemPointerArrayIterator* itr) { 1.525 - MemPointerIterator malloc_snapshot_itr(_alloc_ptrs); 1.526 - MemPointerRecord* new_rec = (MemPointerRecord*)itr->current(); 1.527 - MemPointerRecord* matched_rec; 1.528 - while (new_rec != NULL) { 1.529 - matched_rec = (MemPointerRecord*)malloc_snapshot_itr.locate(new_rec->addr()); 1.530 - // found matched memory block 1.531 - if (matched_rec != NULL && new_rec->addr() == matched_rec->addr()) { 1.532 - // snapshot already contains 'live' records 1.533 - assert(matched_rec->is_allocation_record() || matched_rec->is_arena_memory_record(), 1.534 - "Sanity check"); 1.535 - // update block states 1.536 - if (new_rec->is_allocation_record()) { 1.537 - assign_pointer(matched_rec, new_rec); 1.538 - } else if (new_rec->is_arena_memory_record()) { 1.539 - if (new_rec->size() == 0) { 1.540 - // remove size record once size drops to 0 1.541 - malloc_snapshot_itr.remove(); 1.542 - } else { 1.543 - assign_pointer(matched_rec, new_rec); 1.544 - } 1.545 - } else { 1.546 - // a deallocation record 1.547 - assert(new_rec->is_deallocation_record(), "Sanity check"); 1.548 - // an arena record can be followed by a size record, we need to remove both 1.549 - if (matched_rec->is_arena_record()) { 1.550 - MemPointerRecord* next = (MemPointerRecord*)malloc_snapshot_itr.peek_next(); 1.551 - if (next != NULL && next->is_arena_memory_record() && 1.552 - next->is_memory_record_of_arena(matched_rec)) { 1.553 - malloc_snapshot_itr.remove(); 1.554 - } 1.555 - } 1.556 - // the memory is deallocated, remove related record(s) 1.557 - malloc_snapshot_itr.remove(); 1.558 - } 1.559 - } else { 1.560 - // don't insert size 0 record 1.561 - if (new_rec->is_arena_memory_record() && new_rec->size() == 0) { 1.562 - new_rec = NULL; 1.563 - } 1.564 - 1.565 - if (new_rec != NULL) { 1.566 - if (new_rec->is_allocation_record() || new_rec->is_arena_memory_record()) { 1.567 - if (matched_rec != NULL && new_rec->addr() > matched_rec->addr()) { 1.568 - if (!malloc_snapshot_itr.insert_after(new_rec)) { 1.569 - return false; 1.570 - } 1.571 - } else { 1.572 - if (!malloc_snapshot_itr.insert(new_rec)) { 1.573 - return false; 1.574 - } 1.575 - } 1.576 - } 1.577 -#ifndef PRODUCT 1.578 - else if (!has_allocation_record(new_rec->addr())) { 1.579 - // NMT can not track some startup memory, which is allocated before NMT is on 1.580 - _untracked_count ++; 1.581 - } 1.582 -#endif 1.583 - } 1.584 - } 1.585 - new_rec = (MemPointerRecord*)itr->next(); 1.586 - } 1.587 - return true; 1.588 -} 1.589 - 1.590 -bool MemSnapshot::promote_virtual_memory_records(MemPointerArrayIterator* itr) { 1.591 - VMMemPointerIterator vm_snapshot_itr(_vm_ptrs); 1.592 - MemPointerRecord* new_rec = (MemPointerRecord*)itr->current(); 1.593 - VMMemRegion* reserved_rec; 1.594 - while (new_rec != NULL) { 1.595 - assert(new_rec->is_vm_pointer(), "Sanity check"); 1.596 - 1.597 - // locate a reserved region that contains the specified address, or 1.598 - // the nearest reserved region has base address just above the specified 1.599 - // address 1.600 - reserved_rec = (VMMemRegion*)vm_snapshot_itr.locate(new_rec->addr()); 1.601 - if (reserved_rec != NULL && reserved_rec->contains_region(new_rec)) { 1.602 - // snapshot can only have 'live' records 1.603 - assert(reserved_rec->is_reserved_region(), "Sanity check"); 1.604 - if (new_rec->is_allocation_record()) { 1.605 - if (!reserved_rec->is_same_region(new_rec)) { 1.606 - // only deal with split a bigger reserved region into smaller regions. 1.607 - // So far, CDS is the only use case. 1.608 - if (!vm_snapshot_itr.split_reserved_region(reserved_rec, new_rec->addr(), new_rec->size())) { 1.609 - return false; 1.610 - } 1.611 - } 1.612 - } else if (new_rec->is_uncommit_record()) { 1.613 - if (!vm_snapshot_itr.remove_uncommitted_region(new_rec)) { 1.614 - return false; 1.615 - } 1.616 - } else if (new_rec->is_commit_record()) { 1.617 - // insert or expand existing committed region to cover this 1.618 - // newly committed region 1.619 - if (!vm_snapshot_itr.add_committed_region(new_rec)) { 1.620 - return false; 1.621 - } 1.622 - } else if (new_rec->is_deallocation_record()) { 1.623 - // release part or all memory region 1.624 - if (!vm_snapshot_itr.remove_released_region(new_rec)) { 1.625 - return false; 1.626 - } 1.627 - } else if (new_rec->is_type_tagging_record()) { 1.628 - // tag this reserved virtual memory range to a memory type. Can not re-tag a memory range 1.629 - // to different type. 1.630 - assert(FLAGS_TO_MEMORY_TYPE(reserved_rec->flags()) == mtNone || 1.631 - FLAGS_TO_MEMORY_TYPE(reserved_rec->flags()) == FLAGS_TO_MEMORY_TYPE(new_rec->flags()), 1.632 - "Sanity check"); 1.633 - reserved_rec->tag(new_rec->flags()); 1.634 - } else { 1.635 - ShouldNotReachHere(); 1.636 - } 1.637 - } else { 1.638 - /* 1.639 - * The assertion failure indicates mis-matched virtual memory records. The likely 1.640 - * scenario is, that some virtual memory operations are not going through os::xxxx_memory() 1.641 - * api, which have to be tracked manually. (perfMemory is an example). 1.642 - */ 1.643 - assert(new_rec->is_allocation_record(), "Sanity check"); 1.644 - if (!vm_snapshot_itr.add_reserved_region(new_rec)) { 1.645 - return false; 1.646 - } 1.647 - } 1.648 - new_rec = (MemPointerRecord*)itr->next(); 1.649 - } 1.650 - return true; 1.651 -} 1.652 - 1.653 -#ifndef PRODUCT 1.654 -void MemSnapshot::print_snapshot_stats(outputStream* st) { 1.655 - st->print_cr("Snapshot:"); 1.656 - st->print_cr("\tMalloced: %d/%d [%5.2f%%] %dKB", _alloc_ptrs->length(), _alloc_ptrs->capacity(), 1.657 - (100.0 * (float)_alloc_ptrs->length()) / (float)_alloc_ptrs->capacity(), _alloc_ptrs->instance_size()/K); 1.658 - 1.659 - st->print_cr("\tVM: %d/%d [%5.2f%%] %dKB", _vm_ptrs->length(), _vm_ptrs->capacity(), 1.660 - (100.0 * (float)_vm_ptrs->length()) / (float)_vm_ptrs->capacity(), _vm_ptrs->instance_size()/K); 1.661 - 1.662 - st->print_cr("\tMalloc staging Area: %d/%d [%5.2f%%] %dKB", _staging_area.malloc_data()->length(), 1.663 - _staging_area.malloc_data()->capacity(), 1.664 - (100.0 * (float)_staging_area.malloc_data()->length()) / (float)_staging_area.malloc_data()->capacity(), 1.665 - _staging_area.malloc_data()->instance_size()/K); 1.666 - 1.667 - st->print_cr("\tVirtual memory staging Area: %d/%d [%5.2f%%] %dKB", _staging_area.vm_data()->length(), 1.668 - _staging_area.vm_data()->capacity(), 1.669 - (100.0 * (float)_staging_area.vm_data()->length()) / (float)_staging_area.vm_data()->capacity(), 1.670 - _staging_area.vm_data()->instance_size()/K); 1.671 - 1.672 - st->print_cr("\tUntracked allocation: %d", _untracked_count); 1.673 -} 1.674 - 1.675 -void MemSnapshot::check_malloc_pointers() { 1.676 - MemPointerArrayIteratorImpl mItr(_alloc_ptrs); 1.677 - MemPointerRecord* p = (MemPointerRecord*)mItr.current(); 1.678 - MemPointerRecord* prev = NULL; 1.679 - while (p != NULL) { 1.680 - if (prev != NULL) { 1.681 - assert(p->addr() >= prev->addr(), "sorting order"); 1.682 - } 1.683 - prev = p; 1.684 - p = (MemPointerRecord*)mItr.next(); 1.685 - } 1.686 -} 1.687 - 1.688 -bool MemSnapshot::has_allocation_record(address addr) { 1.689 - MemPointerArrayIteratorImpl itr(_staging_area.malloc_data()); 1.690 - MemPointerRecord* cur = (MemPointerRecord*)itr.current(); 1.691 - while (cur != NULL) { 1.692 - if (cur->addr() == addr && cur->is_allocation_record()) { 1.693 - return true; 1.694 - } 1.695 - cur = (MemPointerRecord*)itr.next(); 1.696 - } 1.697 - return false; 1.698 -} 1.699 -#endif // PRODUCT 1.700 - 1.701 -#ifdef ASSERT 1.702 -void MemSnapshot::check_staging_data() { 1.703 - MemPointerArrayIteratorImpl itr(_staging_area.malloc_data()); 1.704 - MemPointerRecord* cur = (MemPointerRecord*)itr.current(); 1.705 - MemPointerRecord* next = (MemPointerRecord*)itr.next(); 1.706 - while (next != NULL) { 1.707 - assert((next->addr() > cur->addr()) || 1.708 - ((next->flags() & MemPointerRecord::tag_masks) > 1.709 - (cur->flags() & MemPointerRecord::tag_masks)), 1.710 - "sorting order"); 1.711 - cur = next; 1.712 - next = (MemPointerRecord*)itr.next(); 1.713 - } 1.714 - 1.715 - MemPointerArrayIteratorImpl vm_itr(_staging_area.vm_data()); 1.716 - cur = (MemPointerRecord*)vm_itr.current(); 1.717 - while (cur != NULL) { 1.718 - assert(cur->is_vm_pointer(), "virtual memory pointer only"); 1.719 - cur = (MemPointerRecord*)vm_itr.next(); 1.720 - } 1.721 -} 1.722 - 1.723 -void MemSnapshot::dump_all_vm_pointers() { 1.724 - MemPointerArrayIteratorImpl itr(_vm_ptrs); 1.725 - VMMemRegion* ptr = (VMMemRegion*)itr.current(); 1.726 - tty->print_cr("dump virtual memory pointers:"); 1.727 - while (ptr != NULL) { 1.728 - if (ptr->is_committed_region()) { 1.729 - tty->print("\t"); 1.730 - } 1.731 - tty->print("[" PTR_FORMAT " - " PTR_FORMAT "] [%x]", ptr->addr(), 1.732 - (ptr->addr() + ptr->size()), ptr->flags()); 1.733 - 1.734 - if (MemTracker::track_callsite()) { 1.735 - VMMemRegionEx* ex = (VMMemRegionEx*)ptr; 1.736 - if (ex->pc() != NULL) { 1.737 - char buf[1024]; 1.738 - if (os::dll_address_to_function_name(ex->pc(), buf, sizeof(buf), NULL)) { 1.739 - tty->print_cr("\t%s", buf); 1.740 - } else { 1.741 - tty->cr(); 1.742 - } 1.743 - } 1.744 - } 1.745 - 1.746 - ptr = (VMMemRegion*)itr.next(); 1.747 - } 1.748 - tty->flush(); 1.749 -} 1.750 -#endif // ASSERT 1.751 -