Sun, 03 Feb 2013 22:28:08 +0400
8002048: Protocol to discovery of manageable Java processes on a network
Summary: Introduce a protocol to discover manageble Java instances across a network subnet, JDP
Reviewed-by: sla, dfuchs
1 /*
2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
25 #include "precompiled.hpp"
26 #include "runtime/mutexLocker.hpp"
27 #include "utilities/decoder.hpp"
28 #include "services/memBaseline.hpp"
29 #include "services/memPtr.hpp"
30 #include "services/memPtrArray.hpp"
31 #include "services/memSnapshot.hpp"
32 #include "services/memTracker.hpp"
34 #ifdef ASSERT
36 void decode_pointer_record(MemPointerRecord* rec) {
37 tty->print("Pointer: [" PTR_FORMAT " - " PTR_FORMAT "] size = %d bytes", rec->addr(),
38 rec->addr() + rec->size(), (int)rec->size());
39 tty->print(" type = %s", MemBaseline::type2name(FLAGS_TO_MEMORY_TYPE(rec->flags())));
40 if (rec->is_vm_pointer()) {
41 if (rec->is_allocation_record()) {
42 tty->print_cr(" (reserve)");
43 } else if (rec->is_commit_record()) {
44 tty->print_cr(" (commit)");
45 } else if (rec->is_uncommit_record()) {
46 tty->print_cr(" (uncommit)");
47 } else if (rec->is_deallocation_record()) {
48 tty->print_cr(" (release)");
49 } else {
50 tty->print_cr(" (tag)");
51 }
52 } else {
53 if (rec->is_arena_memory_record()) {
54 tty->print_cr(" (arena size)");
55 } else if (rec->is_allocation_record()) {
56 tty->print_cr(" (malloc)");
57 } else {
58 tty->print_cr(" (free)");
59 }
60 }
61 if (MemTracker::track_callsite()) {
62 char buf[1024];
63 address pc = ((MemPointerRecordEx*)rec)->pc();
64 if (pc != NULL && os::dll_address_to_function_name(pc, buf, sizeof(buf), NULL)) {
65 tty->print_cr("\tfrom %s", buf);
66 } else {
67 tty->print_cr("\tcould not decode pc = " PTR_FORMAT "", pc);
68 }
69 }
70 }
72 void decode_vm_region_record(VMMemRegion* rec) {
73 tty->print("VM Region [" PTR_FORMAT " - " PTR_FORMAT "]", rec->addr(),
74 rec->addr() + rec->size());
75 tty->print(" type = %s", MemBaseline::type2name(FLAGS_TO_MEMORY_TYPE(rec->flags())));
76 if (rec->is_allocation_record()) {
77 tty->print_cr(" (reserved)");
78 } else if (rec->is_commit_record()) {
79 tty->print_cr(" (committed)");
80 } else {
81 ShouldNotReachHere();
82 }
83 if (MemTracker::track_callsite()) {
84 char buf[1024];
85 address pc = ((VMMemRegionEx*)rec)->pc();
86 if (pc != NULL && os::dll_address_to_function_name(pc, buf, sizeof(buf), NULL)) {
87 tty->print_cr("\tfrom %s", buf);
88 } else {
89 tty->print_cr("\tcould not decode pc = " PTR_FORMAT "", pc);
90 }
92 }
93 }
95 #endif
98 bool VMMemPointerIterator::insert_record(MemPointerRecord* rec) {
99 VMMemRegionEx new_rec;
100 assert(rec->is_allocation_record() || rec->is_commit_record(),
101 "Sanity check");
102 if (MemTracker::track_callsite()) {
103 new_rec.init((MemPointerRecordEx*)rec);
104 } else {
105 new_rec.init(rec);
106 }
107 return insert(&new_rec);
108 }
110 bool VMMemPointerIterator::insert_record_after(MemPointerRecord* rec) {
111 VMMemRegionEx new_rec;
112 assert(rec->is_allocation_record() || rec->is_commit_record(),
113 "Sanity check");
114 if (MemTracker::track_callsite()) {
115 new_rec.init((MemPointerRecordEx*)rec);
116 } else {
117 new_rec.init(rec);
118 }
119 return insert_after(&new_rec);
120 }
122 // we don't consolidate reserved regions, since they may be categorized
123 // in different types.
124 bool VMMemPointerIterator::add_reserved_region(MemPointerRecord* rec) {
125 assert(rec->is_allocation_record(), "Sanity check");
126 VMMemRegion* reserved_region = (VMMemRegion*)current();
128 // we don't have anything yet
129 if (reserved_region == NULL) {
130 return insert_record(rec);
131 }
133 assert(reserved_region->is_reserved_region(), "Sanity check");
134 // duplicated records
135 if (reserved_region->is_same_region(rec)) {
136 return true;
137 }
138 // Overlapping stack regions indicate that a JNI thread failed to
139 // detach from the VM before exiting. This leaks the JavaThread object.
140 if (CheckJNICalls) {
141 guarantee(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) != mtThreadStack ||
142 !reserved_region->overlaps_region(rec),
143 "Attached JNI thread exited without being detached");
144 }
145 // otherwise, we should not have overlapping reserved regions
146 assert(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) == mtThreadStack ||
147 reserved_region->base() > rec->addr(), "Just check: locate()");
148 assert(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) == mtThreadStack ||
149 !reserved_region->overlaps_region(rec), "overlapping reserved regions");
151 return insert_record(rec);
152 }
154 // we do consolidate committed regions
155 bool VMMemPointerIterator::add_committed_region(MemPointerRecord* rec) {
156 assert(rec->is_commit_record(), "Sanity check");
157 VMMemRegion* reserved_rgn = (VMMemRegion*)current();
158 assert(reserved_rgn->is_reserved_region() && reserved_rgn->contains_region(rec),
159 "Sanity check");
161 // thread's native stack is always marked as "committed", ignore
162 // the "commit" operation for creating stack guard pages
163 if (FLAGS_TO_MEMORY_TYPE(reserved_rgn->flags()) == mtThreadStack &&
164 FLAGS_TO_MEMORY_TYPE(rec->flags()) != mtThreadStack) {
165 return true;
166 }
168 // if the reserved region has any committed regions
169 VMMemRegion* committed_rgn = (VMMemRegion*)next();
170 while (committed_rgn != NULL && committed_rgn->is_committed_region()) {
171 // duplicated commit records
172 if(committed_rgn->contains_region(rec)) {
173 return true;
174 } else if (committed_rgn->overlaps_region(rec)) {
175 // overlaps front part
176 if (rec->addr() < committed_rgn->addr()) {
177 committed_rgn->expand_region(rec->addr(),
178 committed_rgn->addr() - rec->addr());
179 } else {
180 // overlaps tail part
181 address committed_rgn_end = committed_rgn->addr() +
182 committed_rgn->size();
183 assert(committed_rgn_end < rec->addr() + rec->size(),
184 "overlap tail part");
185 committed_rgn->expand_region(committed_rgn_end,
186 (rec->addr() + rec->size()) - committed_rgn_end);
187 }
188 } else if (committed_rgn->base() + committed_rgn->size() == rec->addr()) {
189 // adjunct each other
190 committed_rgn->expand_region(rec->addr(), rec->size());
191 VMMemRegion* next_reg = (VMMemRegion*)next();
192 // see if we can consolidate next committed region
193 if (next_reg != NULL && next_reg->is_committed_region() &&
194 next_reg->base() == committed_rgn->base() + committed_rgn->size()) {
195 committed_rgn->expand_region(next_reg->base(), next_reg->size());
196 // delete merged region
197 remove();
198 }
199 return true;
200 } else if (committed_rgn->base() > rec->addr()) {
201 // found the location, insert this committed region
202 return insert_record(rec);
203 }
204 committed_rgn = (VMMemRegion*)next();
205 }
206 return insert_record(rec);
207 }
209 bool VMMemPointerIterator::remove_uncommitted_region(MemPointerRecord* rec) {
210 assert(rec->is_uncommit_record(), "sanity check");
211 VMMemRegion* cur;
212 cur = (VMMemRegion*)current();
213 assert(cur->is_reserved_region() && cur->contains_region(rec),
214 "Sanity check");
215 // thread's native stack is always marked as "committed", ignore
216 // the "commit" operation for creating stack guard pages
217 if (FLAGS_TO_MEMORY_TYPE(cur->flags()) == mtThreadStack &&
218 FLAGS_TO_MEMORY_TYPE(rec->flags()) != mtThreadStack) {
219 return true;
220 }
222 cur = (VMMemRegion*)next();
223 while (cur != NULL && cur->is_committed_region()) {
224 // region already uncommitted, must be due to duplicated record
225 if (cur->addr() >= rec->addr() + rec->size()) {
226 break;
227 } else if (cur->contains_region(rec)) {
228 // uncommit whole region
229 if (cur->is_same_region(rec)) {
230 remove();
231 break;
232 } else if (rec->addr() == cur->addr() ||
233 rec->addr() + rec->size() == cur->addr() + cur->size()) {
234 // uncommitted from either end of current memory region.
235 cur->exclude_region(rec->addr(), rec->size());
236 break;
237 } else { // split the committed region and release the middle
238 address high_addr = cur->addr() + cur->size();
239 size_t sz = high_addr - rec->addr();
240 cur->exclude_region(rec->addr(), sz);
241 sz = high_addr - (rec->addr() + rec->size());
242 if (MemTracker::track_callsite()) {
243 MemPointerRecordEx tmp(rec->addr() + rec->size(), cur->flags(), sz,
244 ((VMMemRegionEx*)cur)->pc());
245 return insert_record_after(&tmp);
246 } else {
247 MemPointerRecord tmp(rec->addr() + rec->size(), cur->flags(), sz);
248 return insert_record_after(&tmp);
249 }
250 }
251 }
252 cur = (VMMemRegion*)next();
253 }
255 // we may not find committed record due to duplicated records
256 return true;
257 }
259 bool VMMemPointerIterator::remove_released_region(MemPointerRecord* rec) {
260 assert(rec->is_deallocation_record(), "Sanity check");
261 VMMemRegion* cur = (VMMemRegion*)current();
262 assert(cur->is_reserved_region() && cur->contains_region(rec),
263 "Sanity check");
264 if (rec->is_same_region(cur)) {
265 // release whole reserved region
266 #ifdef ASSERT
267 VMMemRegion* next_region = (VMMemRegion*)peek_next();
268 // should not have any committed memory in this reserved region
269 assert(next_region == NULL || !next_region->is_committed_region(), "Sanity check");
270 #endif
271 remove();
272 } else if (rec->addr() == cur->addr() ||
273 rec->addr() + rec->size() == cur->addr() + cur->size()) {
274 // released region is at either end of this region
275 cur->exclude_region(rec->addr(), rec->size());
276 assert(check_reserved_region(), "Integrity check");
277 } else { // split the reserved region and release the middle
278 address high_addr = cur->addr() + cur->size();
279 size_t sz = high_addr - rec->addr();
280 cur->exclude_region(rec->addr(), sz);
281 sz = high_addr - rec->addr() - rec->size();
282 if (MemTracker::track_callsite()) {
283 MemPointerRecordEx tmp(rec->addr() + rec->size(), cur->flags(), sz,
284 ((VMMemRegionEx*)cur)->pc());
285 bool ret = insert_reserved_region(&tmp);
286 assert(!ret || check_reserved_region(), "Integrity check");
287 return ret;
288 } else {
289 MemPointerRecord tmp(rec->addr() + rec->size(), cur->flags(), sz);
290 bool ret = insert_reserved_region(&tmp);
291 assert(!ret || check_reserved_region(), "Integrity check");
292 return ret;
293 }
294 }
295 return true;
296 }
298 bool VMMemPointerIterator::insert_reserved_region(MemPointerRecord* rec) {
299 // skip all 'commit' records associated with previous reserved region
300 VMMemRegion* p = (VMMemRegion*)next();
301 while (p != NULL && p->is_committed_region() &&
302 p->base() + p->size() < rec->addr()) {
303 p = (VMMemRegion*)next();
304 }
305 return insert_record(rec);
306 }
308 bool VMMemPointerIterator::split_reserved_region(VMMemRegion* rgn, address new_rgn_addr, size_t new_rgn_size) {
309 assert(rgn->contains_region(new_rgn_addr, new_rgn_size), "Not fully contained");
310 address pc = (MemTracker::track_callsite() ? ((VMMemRegionEx*)rgn)->pc() : NULL);
311 if (rgn->base() == new_rgn_addr) { // new region is at the beginning of the region
312 size_t sz = rgn->size() - new_rgn_size;
313 // the original region becomes 'new' region
314 rgn->exclude_region(new_rgn_addr + new_rgn_size, sz);
315 // remaining becomes next region
316 MemPointerRecordEx next_rgn(new_rgn_addr + new_rgn_size, rgn->flags(), sz, pc);
317 return insert_reserved_region(&next_rgn);
318 } else if (rgn->base() + rgn->size() == new_rgn_addr + new_rgn_size) {
319 rgn->exclude_region(new_rgn_addr, new_rgn_size);
320 MemPointerRecordEx next_rgn(new_rgn_addr, rgn->flags(), new_rgn_size, pc);
321 return insert_reserved_region(&next_rgn);
322 } else {
323 // the orginal region will be split into three
324 address rgn_high_addr = rgn->base() + rgn->size();
325 // first region
326 rgn->exclude_region(new_rgn_addr, (rgn_high_addr - new_rgn_addr));
327 // the second region is the new region
328 MemPointerRecordEx new_rgn(new_rgn_addr, rgn->flags(), new_rgn_size, pc);
329 if (!insert_reserved_region(&new_rgn)) return false;
330 // the remaining region
331 MemPointerRecordEx rem_rgn(new_rgn_addr + new_rgn_size, rgn->flags(),
332 rgn_high_addr - (new_rgn_addr + new_rgn_size), pc);
333 return insert_reserved_region(&rem_rgn);
334 }
335 }
337 static int sort_in_seq_order(const void* p1, const void* p2) {
338 assert(p1 != NULL && p2 != NULL, "Sanity check");
339 const MemPointerRecord* mp1 = (MemPointerRecord*)p1;
340 const MemPointerRecord* mp2 = (MemPointerRecord*)p2;
341 return (mp1->seq() - mp2->seq());
342 }
344 bool StagingArea::init() {
345 if (MemTracker::track_callsite()) {
346 _malloc_data = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecordEx>();
347 _vm_data = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecordEx>();
348 } else {
349 _malloc_data = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecord>();
350 _vm_data = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecord>();
351 }
353 if (_malloc_data != NULL && _vm_data != NULL &&
354 !_malloc_data->out_of_memory() &&
355 !_vm_data->out_of_memory()) {
356 return true;
357 } else {
358 if (_malloc_data != NULL) delete _malloc_data;
359 if (_vm_data != NULL) delete _vm_data;
360 _malloc_data = NULL;
361 _vm_data = NULL;
362 return false;
363 }
364 }
367 VMRecordIterator StagingArea::virtual_memory_record_walker() {
368 MemPointerArray* arr = vm_data();
369 // sort into seq number order
370 arr->sort((FN_SORT)sort_in_seq_order);
371 return VMRecordIterator(arr);
372 }
375 MemSnapshot::MemSnapshot() {
376 if (MemTracker::track_callsite()) {
377 _alloc_ptrs = new (std::nothrow) MemPointerArrayImpl<MemPointerRecordEx>();
378 _vm_ptrs = new (std::nothrow)MemPointerArrayImpl<VMMemRegionEx>(64, true);
379 } else {
380 _alloc_ptrs = new (std::nothrow) MemPointerArrayImpl<MemPointerRecord>();
381 _vm_ptrs = new (std::nothrow)MemPointerArrayImpl<VMMemRegion>(64, true);
382 }
384 _staging_area.init();
385 _lock = new (std::nothrow) Mutex(Monitor::max_nonleaf - 1, "memSnapshotLock");
386 NOT_PRODUCT(_untracked_count = 0;)
387 _number_of_classes = 0;
388 }
390 MemSnapshot::~MemSnapshot() {
391 assert(MemTracker::shutdown_in_progress(), "native memory tracking still on");
392 {
393 MutexLockerEx locker(_lock);
394 if (_alloc_ptrs != NULL) {
395 delete _alloc_ptrs;
396 _alloc_ptrs = NULL;
397 }
399 if (_vm_ptrs != NULL) {
400 delete _vm_ptrs;
401 _vm_ptrs = NULL;
402 }
403 }
405 if (_lock != NULL) {
406 delete _lock;
407 _lock = NULL;
408 }
409 }
412 void MemSnapshot::copy_seq_pointer(MemPointerRecord* dest, const MemPointerRecord* src) {
413 assert(dest != NULL && src != NULL, "Just check");
414 assert(dest->addr() == src->addr(), "Just check");
415 assert(dest->seq() > 0 && src->seq() > 0, "not sequenced");
417 if (MemTracker::track_callsite()) {
418 *(SeqMemPointerRecordEx*)dest = *(SeqMemPointerRecordEx*)src;
419 } else {
420 *(SeqMemPointerRecord*)dest = *(SeqMemPointerRecord*)src;
421 }
422 }
424 void MemSnapshot::assign_pointer(MemPointerRecord*dest, const MemPointerRecord* src) {
425 assert(src != NULL && dest != NULL, "Just check");
426 assert(dest->seq() == 0 && src->seq() >0, "cast away sequence");
428 if (MemTracker::track_callsite()) {
429 *(MemPointerRecordEx*)dest = *(MemPointerRecordEx*)src;
430 } else {
431 *(MemPointerRecord*)dest = *(MemPointerRecord*)src;
432 }
433 }
435 // merge a recorder to the staging area
436 bool MemSnapshot::merge(MemRecorder* rec) {
437 assert(rec != NULL && !rec->out_of_memory(), "Just check");
439 SequencedRecordIterator itr(rec->pointer_itr());
441 MutexLockerEx lock(_lock, true);
442 MemPointerIterator malloc_staging_itr(_staging_area.malloc_data());
443 MemPointerRecord* incoming_rec = (MemPointerRecord*) itr.current();
444 MemPointerRecord* matched_rec;
446 while (incoming_rec != NULL) {
447 if (incoming_rec->is_vm_pointer()) {
448 // we don't do anything with virtual memory records during merge
449 if (!_staging_area.vm_data()->append(incoming_rec)) {
450 return false;
451 }
452 } else {
453 // locate matched record and/or also position the iterator to proper
454 // location for this incoming record.
455 matched_rec = (MemPointerRecord*)malloc_staging_itr.locate(incoming_rec->addr());
456 // we have not seen this memory block in this generation,
457 // so just add to staging area
458 if (matched_rec == NULL) {
459 if (!malloc_staging_itr.insert(incoming_rec)) {
460 return false;
461 }
462 } else if (incoming_rec->addr() == matched_rec->addr()) {
463 // whoever has higher sequence number wins
464 if (incoming_rec->seq() > matched_rec->seq()) {
465 copy_seq_pointer(matched_rec, incoming_rec);
466 }
467 } else if (incoming_rec->addr() < matched_rec->addr()) {
468 if (!malloc_staging_itr.insert(incoming_rec)) {
469 return false;
470 }
471 } else {
472 ShouldNotReachHere();
473 }
474 }
475 incoming_rec = (MemPointerRecord*)itr.next();
476 }
477 NOT_PRODUCT(void check_staging_data();)
478 return true;
479 }
482 // promote data to next generation
483 bool MemSnapshot::promote(int number_of_classes) {
484 assert(_alloc_ptrs != NULL && _vm_ptrs != NULL, "Just check");
485 assert(_staging_area.malloc_data() != NULL && _staging_area.vm_data() != NULL,
486 "Just check");
487 MutexLockerEx lock(_lock, true);
489 MallocRecordIterator malloc_itr = _staging_area.malloc_record_walker();
490 bool promoted = false;
491 if (promote_malloc_records(&malloc_itr)) {
492 VMRecordIterator vm_itr = _staging_area.virtual_memory_record_walker();
493 if (promote_virtual_memory_records(&vm_itr)) {
494 promoted = true;
495 }
496 }
498 NOT_PRODUCT(check_malloc_pointers();)
499 _staging_area.clear();
500 _number_of_classes = number_of_classes;
501 return promoted;
502 }
504 bool MemSnapshot::promote_malloc_records(MemPointerArrayIterator* itr) {
505 MemPointerIterator malloc_snapshot_itr(_alloc_ptrs);
506 MemPointerRecord* new_rec = (MemPointerRecord*)itr->current();
507 MemPointerRecord* matched_rec;
508 while (new_rec != NULL) {
509 matched_rec = (MemPointerRecord*)malloc_snapshot_itr.locate(new_rec->addr());
510 // found matched memory block
511 if (matched_rec != NULL && new_rec->addr() == matched_rec->addr()) {
512 // snapshot already contains 'live' records
513 assert(matched_rec->is_allocation_record() || matched_rec->is_arena_memory_record(),
514 "Sanity check");
515 // update block states
516 if (new_rec->is_allocation_record()) {
517 assign_pointer(matched_rec, new_rec);
518 } else if (new_rec->is_arena_memory_record()) {
519 if (new_rec->size() == 0) {
520 // remove size record once size drops to 0
521 malloc_snapshot_itr.remove();
522 } else {
523 assign_pointer(matched_rec, new_rec);
524 }
525 } else {
526 // a deallocation record
527 assert(new_rec->is_deallocation_record(), "Sanity check");
528 // an arena record can be followed by a size record, we need to remove both
529 if (matched_rec->is_arena_record()) {
530 MemPointerRecord* next = (MemPointerRecord*)malloc_snapshot_itr.peek_next();
531 if (next->is_arena_memory_record() && next->is_memory_record_of_arena(matched_rec)) {
532 malloc_snapshot_itr.remove();
533 }
534 }
535 // the memory is deallocated, remove related record(s)
536 malloc_snapshot_itr.remove();
537 }
538 } else {
539 // don't insert size 0 record
540 if (new_rec->is_arena_memory_record() && new_rec->size() == 0) {
541 new_rec = NULL;
542 }
544 if (new_rec != NULL) {
545 if (new_rec->is_allocation_record() || new_rec->is_arena_memory_record()) {
546 if (matched_rec != NULL && new_rec->addr() > matched_rec->addr()) {
547 if (!malloc_snapshot_itr.insert_after(new_rec)) {
548 return false;
549 }
550 } else {
551 if (!malloc_snapshot_itr.insert(new_rec)) {
552 return false;
553 }
554 }
555 }
556 #ifndef PRODUCT
557 else if (!has_allocation_record(new_rec->addr())) {
558 // NMT can not track some startup memory, which is allocated before NMT is on
559 _untracked_count ++;
560 }
561 #endif
562 }
563 }
564 new_rec = (MemPointerRecord*)itr->next();
565 }
566 return true;
567 }
569 bool MemSnapshot::promote_virtual_memory_records(MemPointerArrayIterator* itr) {
570 VMMemPointerIterator vm_snapshot_itr(_vm_ptrs);
571 MemPointerRecord* new_rec = (MemPointerRecord*)itr->current();
572 VMMemRegion* reserved_rec;
573 while (new_rec != NULL) {
574 assert(new_rec->is_vm_pointer(), "Sanity check");
576 // locate a reserved region that contains the specified address, or
577 // the nearest reserved region has base address just above the specified
578 // address
579 reserved_rec = (VMMemRegion*)vm_snapshot_itr.locate(new_rec->addr());
580 if (reserved_rec != NULL && reserved_rec->contains_region(new_rec)) {
581 // snapshot can only have 'live' records
582 assert(reserved_rec->is_reserved_region(), "Sanity check");
583 if (new_rec->is_allocation_record()) {
584 if (!reserved_rec->is_same_region(new_rec)) {
585 // only deal with split a bigger reserved region into smaller regions.
586 // So far, CDS is the only use case.
587 if (!vm_snapshot_itr.split_reserved_region(reserved_rec, new_rec->addr(), new_rec->size())) {
588 return false;
589 }
590 }
591 } else if (new_rec->is_uncommit_record()) {
592 if (!vm_snapshot_itr.remove_uncommitted_region(new_rec)) {
593 return false;
594 }
595 } else if (new_rec->is_commit_record()) {
596 // insert or expand existing committed region to cover this
597 // newly committed region
598 if (!vm_snapshot_itr.add_committed_region(new_rec)) {
599 return false;
600 }
601 } else if (new_rec->is_deallocation_record()) {
602 // release part or all memory region
603 if (!vm_snapshot_itr.remove_released_region(new_rec)) {
604 return false;
605 }
606 } else if (new_rec->is_type_tagging_record()) {
607 // tag this reserved virtual memory range to a memory type. Can not re-tag a memory range
608 // to different type.
609 assert(FLAGS_TO_MEMORY_TYPE(reserved_rec->flags()) == mtNone ||
610 FLAGS_TO_MEMORY_TYPE(reserved_rec->flags()) == FLAGS_TO_MEMORY_TYPE(new_rec->flags()),
611 "Sanity check");
612 reserved_rec->tag(new_rec->flags());
613 } else {
614 ShouldNotReachHere();
615 }
616 } else {
617 /*
618 * The assertion failure indicates mis-matched virtual memory records. The likely
619 * scenario is, that some virtual memory operations are not going through os::xxxx_memory()
620 * api, which have to be tracked manually. (perfMemory is an example).
621 */
622 assert(new_rec->is_allocation_record(), "Sanity check");
623 if (!vm_snapshot_itr.add_reserved_region(new_rec)) {
624 return false;
625 }
626 }
627 new_rec = (MemPointerRecord*)itr->next();
628 }
629 return true;
630 }
632 #ifndef PRODUCT
633 void MemSnapshot::print_snapshot_stats(outputStream* st) {
634 st->print_cr("Snapshot:");
635 st->print_cr("\tMalloced: %d/%d [%5.2f%%] %dKB", _alloc_ptrs->length(), _alloc_ptrs->capacity(),
636 (100.0 * (float)_alloc_ptrs->length()) / (float)_alloc_ptrs->capacity(), _alloc_ptrs->instance_size()/K);
638 st->print_cr("\tVM: %d/%d [%5.2f%%] %dKB", _vm_ptrs->length(), _vm_ptrs->capacity(),
639 (100.0 * (float)_vm_ptrs->length()) / (float)_vm_ptrs->capacity(), _vm_ptrs->instance_size()/K);
641 st->print_cr("\tMalloc staging Area: %d/%d [%5.2f%%] %dKB", _staging_area.malloc_data()->length(),
642 _staging_area.malloc_data()->capacity(),
643 (100.0 * (float)_staging_area.malloc_data()->length()) / (float)_staging_area.malloc_data()->capacity(),
644 _staging_area.malloc_data()->instance_size()/K);
646 st->print_cr("\tVirtual memory staging Area: %d/%d [%5.2f%%] %dKB", _staging_area.vm_data()->length(),
647 _staging_area.vm_data()->capacity(),
648 (100.0 * (float)_staging_area.vm_data()->length()) / (float)_staging_area.vm_data()->capacity(),
649 _staging_area.vm_data()->instance_size()/K);
651 st->print_cr("\tUntracked allocation: %d", _untracked_count);
652 }
654 void MemSnapshot::check_malloc_pointers() {
655 MemPointerArrayIteratorImpl mItr(_alloc_ptrs);
656 MemPointerRecord* p = (MemPointerRecord*)mItr.current();
657 MemPointerRecord* prev = NULL;
658 while (p != NULL) {
659 if (prev != NULL) {
660 assert(p->addr() >= prev->addr(), "sorting order");
661 }
662 prev = p;
663 p = (MemPointerRecord*)mItr.next();
664 }
665 }
667 bool MemSnapshot::has_allocation_record(address addr) {
668 MemPointerArrayIteratorImpl itr(_staging_area.malloc_data());
669 MemPointerRecord* cur = (MemPointerRecord*)itr.current();
670 while (cur != NULL) {
671 if (cur->addr() == addr && cur->is_allocation_record()) {
672 return true;
673 }
674 cur = (MemPointerRecord*)itr.next();
675 }
676 return false;
677 }
678 #endif // PRODUCT
680 #ifdef ASSERT
681 void MemSnapshot::check_staging_data() {
682 MemPointerArrayIteratorImpl itr(_staging_area.malloc_data());
683 MemPointerRecord* cur = (MemPointerRecord*)itr.current();
684 MemPointerRecord* next = (MemPointerRecord*)itr.next();
685 while (next != NULL) {
686 assert((next->addr() > cur->addr()) ||
687 ((next->flags() & MemPointerRecord::tag_masks) >
688 (cur->flags() & MemPointerRecord::tag_masks)),
689 "sorting order");
690 cur = next;
691 next = (MemPointerRecord*)itr.next();
692 }
694 MemPointerArrayIteratorImpl vm_itr(_staging_area.vm_data());
695 cur = (MemPointerRecord*)vm_itr.current();
696 while (cur != NULL) {
697 assert(cur->is_vm_pointer(), "virtual memory pointer only");
698 cur = (MemPointerRecord*)vm_itr.next();
699 }
700 }
702 void MemSnapshot::dump_all_vm_pointers() {
703 MemPointerArrayIteratorImpl itr(_vm_ptrs);
704 VMMemRegion* ptr = (VMMemRegion*)itr.current();
705 tty->print_cr("dump virtual memory pointers:");
706 while (ptr != NULL) {
707 if (ptr->is_committed_region()) {
708 tty->print("\t");
709 }
710 tty->print("[" PTR_FORMAT " - " PTR_FORMAT "] [%x]", ptr->addr(),
711 (ptr->addr() + ptr->size()), ptr->flags());
713 if (MemTracker::track_callsite()) {
714 VMMemRegionEx* ex = (VMMemRegionEx*)ptr;
715 if (ex->pc() != NULL) {
716 char buf[1024];
717 if (os::dll_address_to_function_name(ex->pc(), buf, sizeof(buf), NULL)) {
718 tty->print_cr("\t%s", buf);
719 } else {
720 tty->print_cr("");
721 }
722 }
723 }
725 ptr = (VMMemRegion*)itr.next();
726 }
727 tty->flush();
728 }
729 #endif // ASSERT