Mercurial > hg > truffle
annotate src/share/vm/services/memSnapshot.hpp @ 6882:716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
Summary: Enhanced virtual memory tracking to track committed regions as well as reserved regions, so NMT now can generate virtual memory map.
Reviewed-by: acorn, coleenp
author | zgu |
---|---|
date | Fri, 19 Oct 2012 21:40:07 -0400 |
parents | 33143ee07800 |
children | fb3190e77d3c |
rev | line source |
---|---|
6197 | 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 */ | |
24 | |
25 #ifndef SHARE_VM_SERVICES_MEM_SNAPSHOT_HPP | |
26 #define SHARE_VM_SERVICES_MEM_SNAPSHOT_HPP | |
27 | |
28 #include "memory/allocation.hpp" | |
29 #include "runtime/mutex.hpp" | |
30 #include "runtime/mutexLocker.hpp" | |
31 #include "services/memBaseline.hpp" | |
32 #include "services/memPtrArray.hpp" | |
33 | |
34 | |
35 // Snapshot pointer array iterator | |
36 | |
37 // The pointer array contains malloc-ed pointers | |
38 class MemPointerIterator : public MemPointerArrayIteratorImpl { | |
39 public: | |
40 MemPointerIterator(MemPointerArray* arr): | |
41 MemPointerArrayIteratorImpl(arr) { | |
42 assert(arr != NULL, "null array"); | |
43 } | |
44 | |
45 #ifdef ASSERT | |
46 virtual bool is_dup_pointer(const MemPointer* ptr1, | |
47 const MemPointer* ptr2) const { | |
48 MemPointerRecord* p1 = (MemPointerRecord*)ptr1; | |
49 MemPointerRecord* p2 = (MemPointerRecord*)ptr2; | |
50 | |
51 if (p1->addr() != p2->addr()) return false; | |
52 if ((p1->flags() & MemPointerRecord::tag_masks) != | |
53 (p2->flags() & MemPointerRecord::tag_masks)) { | |
54 return false; | |
55 } | |
56 // we do see multiple commit/uncommit on the same memory, it is ok | |
57 return (p1->flags() & MemPointerRecord::tag_masks) == MemPointerRecord::tag_alloc || | |
58 (p1->flags() & MemPointerRecord::tag_masks) == MemPointerRecord::tag_release; | |
59 } | |
60 | |
61 virtual bool insert(MemPointer* ptr) { | |
62 if (_pos > 0) { | |
63 MemPointer* p1 = (MemPointer*)ptr; | |
64 MemPointer* p2 = (MemPointer*)_array->at(_pos - 1); | |
65 assert(!is_dup_pointer(p1, p2), | |
6599
4acebbe310e1
7185614: NMT ON: "check by caller" assertion failed on nsk ThreadMXBean test
zgu
parents:
6197
diff
changeset
|
66 err_msg("duplicated pointer, flag = [%x]", (unsigned int)((MemPointerRecord*)p1)->flags())); |
6197 | 67 } |
68 if (_pos < _array->length() -1) { | |
69 MemPointer* p1 = (MemPointer*)ptr; | |
70 MemPointer* p2 = (MemPointer*)_array->at(_pos + 1); | |
71 assert(!is_dup_pointer(p1, p2), | |
6599
4acebbe310e1
7185614: NMT ON: "check by caller" assertion failed on nsk ThreadMXBean test
zgu
parents:
6197
diff
changeset
|
72 err_msg("duplicated pointer, flag = [%x]", (unsigned int)((MemPointerRecord*)p1)->flags())); |
6197 | 73 } |
74 return _array->insert_at(ptr, _pos); | |
75 } | |
76 | |
77 virtual bool insert_after(MemPointer* ptr) { | |
78 if (_pos > 0) { | |
79 MemPointer* p1 = (MemPointer*)ptr; | |
80 MemPointer* p2 = (MemPointer*)_array->at(_pos - 1); | |
81 assert(!is_dup_pointer(p1, p2), | |
6599
4acebbe310e1
7185614: NMT ON: "check by caller" assertion failed on nsk ThreadMXBean test
zgu
parents:
6197
diff
changeset
|
82 err_msg("duplicated pointer, flag = [%x]", (unsigned int)((MemPointerRecord*)p1)->flags())); |
6197 | 83 } |
84 if (_pos < _array->length() - 1) { | |
85 MemPointer* p1 = (MemPointer*)ptr; | |
86 MemPointer* p2 = (MemPointer*)_array->at(_pos + 1); | |
87 | |
88 assert(!is_dup_pointer(p1, p2), | |
6599
4acebbe310e1
7185614: NMT ON: "check by caller" assertion failed on nsk ThreadMXBean test
zgu
parents:
6197
diff
changeset
|
89 err_msg("duplicated pointer, flag = [%x]", (unsigned int)((MemPointerRecord*)p1)->flags())); |
6197 | 90 } |
91 if (_array->insert_at(ptr, _pos + 1)) { | |
92 _pos ++; | |
93 return true; | |
94 } | |
95 return false; | |
96 } | |
97 #endif | |
98 | |
99 virtual MemPointer* locate(address addr) { | |
100 MemPointer* cur = current(); | |
101 while (cur != NULL && cur->addr() < addr) { | |
102 cur = next(); | |
103 } | |
104 return cur; | |
105 } | |
106 }; | |
107 | |
108 class VMMemPointerIterator : public MemPointerIterator { | |
109 public: | |
110 VMMemPointerIterator(MemPointerArray* arr): | |
111 MemPointerIterator(arr) { | |
112 } | |
113 | |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
114 // locate an existing reserved memory region that contains specified address, |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
115 // or the reserved region just above this address, where the incoming |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
116 // reserved region should be inserted. |
6197 | 117 virtual MemPointer* locate(address addr) { |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
118 reset(); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
119 VMMemRegion* reg = (VMMemRegion*)current(); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
120 while (reg != NULL) { |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
121 if (reg->is_reserved_region()) { |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
122 if (reg->contains_address(addr) || addr < reg->base()) { |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
123 return reg; |
6197 | 124 } |
125 } | |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
126 reg = (VMMemRegion*)next(); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
127 } |
6741
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
128 return NULL; |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
129 } |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
130 |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
131 // following methods update virtual memory in the context |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
132 // of 'current' position, which is properly positioned by |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
133 // callers via locate method. |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
134 bool add_reserved_region(MemPointerRecord* rec); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
135 bool add_committed_region(MemPointerRecord* rec); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
136 bool remove_uncommitted_region(MemPointerRecord* rec); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
137 bool remove_released_region(MemPointerRecord* rec); |
6197 | 138 |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
139 // split a reserved region to create a new memory region with specified base and size |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
140 bool split_reserved_region(VMMemRegion* rgn, address new_rgn_addr, size_t new_rgn_size); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
141 private: |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
142 bool insert_record(MemPointerRecord* rec); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
143 bool insert_record_after(MemPointerRecord* rec); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
144 |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
145 bool insert_reserved_region(MemPointerRecord* rec); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
146 |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
147 // reset current position |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
148 inline void reset() { _pos = 0; } |
6197 | 149 #ifdef ASSERT |
150 virtual bool is_dup_pointer(const MemPointer* ptr1, | |
151 const MemPointer* ptr2) const { | |
152 VMMemRegion* p1 = (VMMemRegion*)ptr1; | |
153 VMMemRegion* p2 = (VMMemRegion*)ptr2; | |
154 | |
155 if (p1->addr() != p2->addr()) return false; | |
156 if ((p1->flags() & MemPointerRecord::tag_masks) != | |
157 (p2->flags() & MemPointerRecord::tag_masks)) { | |
158 return false; | |
159 } | |
160 // we do see multiple commit/uncommit on the same memory, it is ok | |
161 return (p1->flags() & MemPointerRecord::tag_masks) == MemPointerRecord::tag_alloc || | |
162 (p1->flags() & MemPointerRecord::tag_masks) == MemPointerRecord::tag_release; | |
163 } | |
164 #endif | |
165 }; | |
166 | |
6741
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
167 class MallocRecordIterator : public MemPointerArrayIterator { |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
168 protected: |
6197 | 169 MemPointerArrayIteratorImpl _itr; |
170 | |
171 public: | |
6741
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
172 MallocRecordIterator(MemPointerArray* arr) : _itr(arr) { |
6197 | 173 } |
174 | |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
175 virtual MemPointer* current() const { |
6741
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
176 MemPointerRecord* cur = (MemPointerRecord*)_itr.current(); |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
177 assert(cur == NULL || !cur->is_vm_pointer(), "seek error"); |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
178 MemPointerRecord* next = (MemPointerRecord*)_itr.peek_next(); |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
179 if (next == NULL || next->addr() != cur->addr()) { |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
180 return cur; |
6197 | 181 } else { |
6741
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
182 assert(!cur->is_vm_pointer(), "Sanity check"); |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
183 assert(cur->is_allocation_record() && next->is_deallocation_record(), |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
184 "sorting order"); |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
185 assert(cur->seq() != next->seq(), "Sanity check"); |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
186 return cur->seq() > next->seq() ? cur : next; |
6197 | 187 } |
188 } | |
189 | |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
190 virtual MemPointer* next() { |
6741
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
191 MemPointerRecord* cur = (MemPointerRecord*)_itr.current(); |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
192 assert(cur == NULL || !cur->is_vm_pointer(), "Sanity check"); |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
193 MemPointerRecord* next = (MemPointerRecord*)_itr.next(); |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
194 if (next == NULL) { |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
195 return NULL; |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
196 } |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
197 if (cur->addr() == next->addr()) { |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
198 next = (MemPointerRecord*)_itr.next(); |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
199 } |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
200 return current(); |
6197 | 201 } |
202 | |
6741
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
203 MemPointer* peek_next() const { ShouldNotReachHere(); return NULL; } |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
204 MemPointer* peek_prev() const { ShouldNotReachHere(); return NULL; } |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
205 void remove() { ShouldNotReachHere(); } |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
206 bool insert(MemPointer* ptr) { ShouldNotReachHere(); return false; } |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
207 bool insert_after(MemPointer* ptr) { ShouldNotReachHere(); return false; } |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
208 }; |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
209 |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
210 // collapse duplicated records. Eliminating duplicated records here, is much |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
211 // cheaper than during promotion phase. However, it does have limitation - it |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
212 // can only eliminate duplicated records within the generation, there are |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
213 // still chances seeing duplicated records during promotion. |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
214 // We want to use the record with higher sequence number, because it has |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
215 // more accurate callsite pc. |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
216 class VMRecordIterator : public MallocRecordIterator { |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
217 public: |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
218 VMRecordIterator(MemPointerArray* arr) : MallocRecordIterator(arr) { |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
219 MemPointerRecord* cur = (MemPointerRecord*)_itr.current(); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
220 MemPointerRecord* next = (MemPointerRecord*)_itr.peek_next(); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
221 while (next != NULL) { |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
222 assert(cur != NULL, "Sanity check"); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
223 assert(((SeqMemPointerRecord*)next)->seq() > ((SeqMemPointerRecord*)cur)->seq(), |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
224 "pre-sort order"); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
225 |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
226 if (is_duplicated_record(cur, next)) { |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
227 _itr.next(); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
228 next = (MemPointerRecord*)_itr.peek_next(); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
229 } else { |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
230 break; |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
231 } |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
232 } |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
233 } |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
234 |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
235 virtual MemPointer* current() const { |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
236 return _itr.current(); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
237 } |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
238 |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
239 // get next record, but skip the duplicated records |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
240 virtual MemPointer* next() { |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
241 MemPointerRecord* cur = (MemPointerRecord*)_itr.next(); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
242 MemPointerRecord* next = (MemPointerRecord*)_itr.peek_next(); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
243 while (next != NULL) { |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
244 assert(cur != NULL, "Sanity check"); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
245 assert(((SeqMemPointerRecord*)next)->seq() > ((SeqMemPointerRecord*)cur)->seq(), |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
246 "pre-sort order"); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
247 |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
248 if (is_duplicated_record(cur, next)) { |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
249 _itr.next(); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
250 cur = next; |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
251 next = (MemPointerRecord*)_itr.peek_next(); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
252 } else { |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
253 break; |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
254 } |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
255 } |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
256 return cur; |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
257 } |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
258 |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
259 private: |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
260 bool is_duplicated_record(MemPointerRecord* p1, MemPointerRecord* p2) const { |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
261 bool ret = (p1->addr() == p2->addr() && p1->size() == p2->size() && p1->flags() == p2->flags()); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
262 assert(!(ret && FLAGS_TO_MEMORY_TYPE(p1->flags()) == mtThreadStack), "dup on stack record"); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
263 return ret; |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
264 } |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
265 }; |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
266 |
6741
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
267 class StagingArea : public _ValueObj { |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
268 private: |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
269 MemPointerArray* _malloc_data; |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
270 MemPointerArray* _vm_data; |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
271 |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
272 public: |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
273 StagingArea() : _malloc_data(NULL), _vm_data(NULL) { |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
274 init(); |
6197 | 275 } |
276 | |
6741
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
277 ~StagingArea() { |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
278 if (_malloc_data != NULL) delete _malloc_data; |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
279 if (_vm_data != NULL) delete _vm_data; |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
280 } |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
281 |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
282 MallocRecordIterator malloc_record_walker() { |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
283 return MallocRecordIterator(malloc_data()); |
6197 | 284 } |
285 | |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
286 VMRecordIterator virtual_memory_record_walker(); |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
287 |
6741
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
288 bool init(); |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
289 void clear() { |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
290 assert(_malloc_data != NULL && _vm_data != NULL, "Just check"); |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
291 _malloc_data->shrink(); |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
292 _malloc_data->clear(); |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
293 _vm_data->clear(); |
6197 | 294 } |
295 | |
6741
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
296 inline MemPointerArray* malloc_data() { return _malloc_data; } |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
297 inline MemPointerArray* vm_data() { return _vm_data; } |
6197 | 298 }; |
299 | |
300 class MemBaseline; | |
301 class MemSnapshot : public CHeapObj<mtNMT> { | |
302 private: | |
303 // the following two arrays contain records of all known lived memory blocks | |
304 // live malloc-ed memory pointers | |
305 MemPointerArray* _alloc_ptrs; | |
306 // live virtual memory pointers | |
307 MemPointerArray* _vm_ptrs; | |
308 | |
6741
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
309 StagingArea _staging_area; |
6197 | 310 |
311 // the lock to protect this snapshot | |
312 Monitor* _lock; | |
313 | |
314 NOT_PRODUCT(size_t _untracked_count;) | |
315 friend class MemBaseline; | |
316 | |
317 public: | |
318 MemSnapshot(); | |
319 virtual ~MemSnapshot(); | |
320 | |
321 // if we are running out of native memory | |
6741
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
322 bool out_of_memory() { |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
323 return (_alloc_ptrs == NULL || |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
324 _staging_area.malloc_data() == NULL || |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
325 _staging_area.vm_data() == NULL || |
6197 | 326 _vm_ptrs == NULL || _lock == NULL || |
327 _alloc_ptrs->out_of_memory() || | |
328 _vm_ptrs->out_of_memory()); | |
329 } | |
330 | |
331 // merge a per-thread memory recorder into staging area | |
332 bool merge(MemRecorder* rec); | |
333 // promote staged data to snapshot | |
6741
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
334 bool promote(); |
6197 | 335 |
336 | |
337 void wait(long timeout) { | |
338 assert(_lock != NULL, "Just check"); | |
339 MonitorLockerEx locker(_lock); | |
340 locker.wait(true, timeout); | |
341 } | |
342 | |
343 NOT_PRODUCT(void print_snapshot_stats(outputStream* st);) | |
344 NOT_PRODUCT(void check_staging_data();) | |
345 NOT_PRODUCT(void check_malloc_pointers();) | |
346 NOT_PRODUCT(bool has_allocation_record(address addr);) | |
6882
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
347 // dump all virtual memory pointers in snapshot |
716c64bda5ba
7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents:
6741
diff
changeset
|
348 DEBUG_ONLY( void dump_all_vm_pointers();) |
6197 | 349 |
350 private: | |
351 // copy pointer data from src to dest | |
352 void copy_pointer(MemPointerRecord* dest, const MemPointerRecord* src); | |
6741
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
353 |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
354 bool promote_malloc_records(MemPointerArrayIterator* itr); |
33143ee07800
7181995: NMT ON: NMT assertion failure assert(cur_vm->is_uncommit_record() || cur_vm->is_deallocation_record
zgu
parents:
6599
diff
changeset
|
355 bool promote_virtual_memory_records(MemPointerArrayIterator* itr); |
6197 | 356 }; |
357 | |
358 #endif // SHARE_VM_SERVICES_MEM_SNAPSHOT_HPP |