comparison src/share/vm/services/memPtrArray.hpp @ 6197:d2a62e0f25eb

6995781: Native Memory Tracking (Phase 1) 7151532: DCmd for hotspot native memory tracking Summary: Implementation of native memory tracking phase 1, which tracks VM native memory usage, and related DCmd Reviewed-by: acorn, coleenp, fparain
author zgu
date Thu, 28 Jun 2012 17:03:16 -0400
parents
children e5bf1c79ed5b
comparison
equal deleted inserted replaced
6174:74533f63b116 6197:d2a62e0f25eb
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 #ifndef SHARE_VM_UTILITIES_MEM_PTR_ARRAY_HPP
25 #define SHARE_VM_UTILITIES_MEM_PTR_ARRAY_HPP
26
27 #include "memory/allocation.hpp"
28 #include "services/memPtr.hpp"
29
30 class MemPtr;
31 class MemRecorder;
32 class ArenaInfo;
33 class MemSnapshot;
34
35 extern "C" {
36 typedef int (*FN_SORT)(const void *, const void *);
37 }
38
39
40 // Memory pointer array interface. This array is used by NMT to hold
41 // various memory block information.
42 // The memory pointer arrays are usually walked with their iterators.
43
44 class MemPointerArray : public CHeapObj<mtNMT> {
45 public:
46 virtual ~MemPointerArray() { }
47
48 // return true if it can not allocate storage for the data
49 virtual bool out_of_memory() const = 0;
50 virtual bool is_empty() const = 0;
51 virtual bool is_full() = 0;
52 virtual int length() const = 0;
53 virtual void clear() = 0;
54 virtual bool append(MemPointer* ptr) = 0;
55 virtual bool insert_at(MemPointer* ptr, int pos) = 0;
56 virtual bool remove_at(int pos) = 0;
57 virtual MemPointer* at(int index) const = 0;
58 virtual void sort(FN_SORT fn) = 0;
59 virtual size_t instance_size() const = 0;
60 virtual bool shrink() = 0;
61
62 debug_only(virtual int capacity() const = 0;)
63 };
64
65 // Iterator interface
66 class MemPointerArrayIterator VALUE_OBJ_CLASS_SPEC {
67 public:
68 // return the pointer at current position
69 virtual MemPointer* current() const = 0;
70 // return the next pointer and advance current position
71 virtual MemPointer* next() = 0;
72 // return next pointer without advancing current position
73 virtual MemPointer* peek_next() const = 0;
74 // return previous pointer without changing current position
75 virtual MemPointer* peek_prev() const = 0;
76 // remove the pointer at current position
77 virtual void remove() = 0;
78 // insert the pointer at current position
79 virtual bool insert(MemPointer* ptr) = 0;
80 // insert specified element after current position and
81 // move current position to newly inserted position
82 virtual bool insert_after(MemPointer* ptr) = 0;
83 };
84
85 // implementation class
86 class MemPointerArrayIteratorImpl : public MemPointerArrayIterator {
87 #ifdef ASSERT
88 protected:
89 #else
90 private:
91 #endif
92 MemPointerArray* _array;
93 int _pos;
94
95 public:
96 MemPointerArrayIteratorImpl(MemPointerArray* arr) {
97 assert(arr != NULL, "Parameter check");
98 _array = arr;
99 _pos = 0;
100 }
101
102 virtual MemPointer* current() const {
103 if (_pos < _array->length()) {
104 return _array->at(_pos);
105 }
106 return NULL;
107 }
108
109 virtual MemPointer* next() {
110 if (_pos + 1 < _array->length()) {
111 return _array->at(++_pos);
112 }
113 _pos = _array->length();
114 return NULL;
115 }
116
117 virtual MemPointer* peek_next() const {
118 if (_pos + 1 < _array->length()) {
119 return _array->at(_pos + 1);
120 }
121 return NULL;
122 }
123
124 virtual MemPointer* peek_prev() const {
125 if (_pos > 0) {
126 return _array->at(_pos - 1);
127 }
128 return NULL;
129 }
130
131 virtual void remove() {
132 if (_pos < _array->length()) {
133 _array->remove_at(_pos);
134 }
135 }
136
137 virtual bool insert(MemPointer* ptr) {
138 return _array->insert_at(ptr, _pos);
139 }
140
141 virtual bool insert_after(MemPointer* ptr) {
142 if (_array->insert_at(ptr, _pos + 1)) {
143 _pos ++;
144 return true;
145 }
146 return false;
147 }
148 };
149
150
151
152 // Memory pointer array implementation.
153 // This implementation implements expandable array
154 #define DEFAULT_PTR_ARRAY_SIZE 1024
155
156 template <class E> class MemPointerArrayImpl : public MemPointerArray {
157 private:
158 int _max_size;
159 int _size;
160 bool _init_elements;
161 E* _data;
162
163 public:
164 MemPointerArrayImpl(int initial_size = DEFAULT_PTR_ARRAY_SIZE, bool init_elements = true):
165 _max_size(initial_size), _size(0), _init_elements(init_elements) {
166 _data = (E*)raw_allocate(sizeof(E), initial_size);
167 if (_init_elements) {
168 for (int index = 0; index < _max_size; index ++) {
169 ::new ((void*)&_data[index]) E();
170 }
171 }
172 }
173
174 virtual ~MemPointerArrayImpl() {
175 if (_data != NULL) {
176 raw_free(_data);
177 }
178 }
179
180 public:
181 bool out_of_memory() const {
182 return (_data == NULL);
183 }
184
185 size_t instance_size() const {
186 return sizeof(MemPointerArrayImpl<E>) + _max_size * sizeof(E);
187 }
188
189 bool is_empty() const {
190 assert(_data != NULL, "Just check");
191 return _size == 0;
192 }
193
194 bool is_full() {
195 assert(_data != NULL, "Just check");
196 if (_size < _max_size) {
197 return false;
198 } else {
199 return !expand_array();
200 }
201 }
202
203 int length() const {
204 assert(_data != NULL, "Just check");
205 return _size;
206 }
207
208 debug_only(int capacity() const { return _max_size; })
209
210 void clear() {
211 assert(_data != NULL, "Just check");
212 _size = 0;
213 }
214
215 bool append(MemPointer* ptr) {
216 assert(_data != NULL, "Just check");
217 if (is_full()) {
218 return false;
219 }
220 _data[_size ++] = *(E*)ptr;
221 return true;
222 }
223
224 bool insert_at(MemPointer* ptr, int pos) {
225 assert(_data != NULL, "Just check");
226 if (is_full()) {
227 return false;
228 }
229 for (int index = _size; index > pos; index --) {
230 _data[index] = _data[index - 1];
231 }
232 _data[pos] = *(E*)ptr;
233 _size ++;
234 return true;
235 }
236
237 bool remove_at(int pos) {
238 assert(_data != NULL, "Just check");
239 if (_size <= pos && pos >= 0) {
240 return false;
241 }
242 -- _size;
243
244 for (int index = pos; index < _size; index ++) {
245 _data[index] = _data[index + 1];
246 }
247 return true;
248 }
249
250 MemPointer* at(int index) const {
251 assert(_data != NULL, "Just check");
252 assert(index >= 0 && index < _size, "illegal index");
253 return &_data[index];
254 }
255
256 bool shrink() {
257 float used = ((float)_size) / ((float)_max_size);
258 if (used < 0.40) {
259 E* old_ptr = _data;
260 int new_size = ((_max_size) / (2 * DEFAULT_PTR_ARRAY_SIZE) + 1) * DEFAULT_PTR_ARRAY_SIZE;
261 _data = (E*)raw_reallocate(_data, sizeof(E), new_size);
262 if (_data == NULL) {
263 _data = old_ptr;
264 return false;
265 } else {
266 _max_size = new_size;
267 return true;
268 }
269 }
270 return false;
271 }
272
273 void sort(FN_SORT fn) {
274 assert(_data != NULL, "Just check");
275 qsort((void*)_data, _size, sizeof(E), fn);
276 }
277
278 private:
279 bool expand_array() {
280 assert(_data != NULL, "Not yet allocated");
281 E* old_ptr = _data;
282 if ((_data = (E*)raw_reallocate((void*)_data, sizeof(E),
283 _max_size + DEFAULT_PTR_ARRAY_SIZE)) == NULL) {
284 _data = old_ptr;
285 return false;
286 } else {
287 _max_size += DEFAULT_PTR_ARRAY_SIZE;
288 if (_init_elements) {
289 for (int index = _size; index < _max_size; index ++) {
290 ::new ((void*)&_data[index]) E();
291 }
292 }
293 return true;
294 }
295 }
296
297 void* raw_allocate(size_t elementSize, int items) {
298 return os::malloc(elementSize * items, mtNMT);
299 }
300
301 void* raw_reallocate(void* ptr, size_t elementSize, int items) {
302 return os::realloc(ptr, elementSize * items, mtNMT);
303 }
304
305 void raw_free(void* ptr) {
306 os::free(ptr, mtNMT);
307 }
308 };
309
310 #endif // SHARE_VM_UTILITIES_MEM_PTR_ARRAY_HPP