Mercurial > hg > truffle
annotate src/share/vm/services/memPtrArray.hpp @ 14702:d4dd5204c0aa
Merge
author | ehelin |
---|---|
date | Fri, 14 Mar 2014 13:27:18 +0100 |
parents | 33143ee07800 |
children |
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 #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 | |
6607
e5bf1c79ed5b
7191124: Optimized build is broken due to inconsistent use of DEBUG_ONLY and NOT_PRODUCT macros in NMT
zgu
parents:
6197
diff
changeset
|
62 NOT_PRODUCT(virtual int capacity() const = 0;) |
6197 | 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 protected: | |
88 MemPointerArray* _array; | |
89 int _pos; | |
90 | |
91 public: | |
92 MemPointerArrayIteratorImpl(MemPointerArray* arr) { | |
93 assert(arr != NULL, "Parameter check"); | |
94 _array = arr; | |
95 _pos = 0; | |
96 } | |
97 | |
98 virtual MemPointer* current() const { | |
99 if (_pos < _array->length()) { | |
100 return _array->at(_pos); | |
101 } | |
102 return NULL; | |
103 } | |
104 | |
105 virtual MemPointer* next() { | |
106 if (_pos + 1 < _array->length()) { | |
107 return _array->at(++_pos); | |
108 } | |
109 _pos = _array->length(); | |
110 return NULL; | |
111 } | |
112 | |
113 virtual MemPointer* peek_next() const { | |
114 if (_pos + 1 < _array->length()) { | |
115 return _array->at(_pos + 1); | |
116 } | |
117 return NULL; | |
118 } | |
119 | |
120 virtual MemPointer* peek_prev() const { | |
121 if (_pos > 0) { | |
122 return _array->at(_pos - 1); | |
123 } | |
124 return NULL; | |
125 } | |
126 | |
127 virtual void remove() { | |
128 if (_pos < _array->length()) { | |
129 _array->remove_at(_pos); | |
130 } | |
131 } | |
132 | |
133 virtual bool insert(MemPointer* ptr) { | |
134 return _array->insert_at(ptr, _pos); | |
135 } | |
136 | |
137 virtual bool insert_after(MemPointer* ptr) { | |
138 if (_array->insert_at(ptr, _pos + 1)) { | |
139 _pos ++; | |
140 return true; | |
141 } | |
142 return false; | |
143 } | |
144 }; | |
145 | |
146 | |
147 | |
148 // Memory pointer array implementation. | |
149 // This implementation implements expandable array | |
150 #define DEFAULT_PTR_ARRAY_SIZE 1024 | |
151 | |
152 template <class E> class MemPointerArrayImpl : public MemPointerArray { | |
153 private: | |
154 int _max_size; | |
155 int _size; | |
156 bool _init_elements; | |
157 E* _data; | |
158 | |
159 public: | |
160 MemPointerArrayImpl(int initial_size = DEFAULT_PTR_ARRAY_SIZE, bool init_elements = true): | |
161 _max_size(initial_size), _size(0), _init_elements(init_elements) { | |
162 _data = (E*)raw_allocate(sizeof(E), initial_size); | |
163 if (_init_elements) { | |
164 for (int index = 0; index < _max_size; index ++) { | |
165 ::new ((void*)&_data[index]) E(); | |
166 } | |
167 } | |
168 } | |
169 | |
170 virtual ~MemPointerArrayImpl() { | |
171 if (_data != NULL) { | |
172 raw_free(_data); | |
173 } | |
174 } | |
175 | |
176 public: | |
177 bool out_of_memory() const { | |
178 return (_data == NULL); | |
179 } | |
180 | |
181 size_t instance_size() const { | |
182 return sizeof(MemPointerArrayImpl<E>) + _max_size * sizeof(E); | |
183 } | |
184 | |
185 bool is_empty() const { | |
186 assert(_data != NULL, "Just check"); | |
187 return _size == 0; | |
188 } | |
189 | |
190 bool is_full() { | |
191 assert(_data != NULL, "Just check"); | |
192 if (_size < _max_size) { | |
193 return false; | |
194 } else { | |
195 return !expand_array(); | |
196 } | |
197 } | |
198 | |
199 int length() const { | |
200 assert(_data != NULL, "Just check"); | |
201 return _size; | |
202 } | |
203 | |
6607
e5bf1c79ed5b
7191124: Optimized build is broken due to inconsistent use of DEBUG_ONLY and NOT_PRODUCT macros in NMT
zgu
parents:
6197
diff
changeset
|
204 NOT_PRODUCT(int capacity() const { return _max_size; }) |
6197 | 205 |
206 void clear() { | |
207 assert(_data != NULL, "Just check"); | |
208 _size = 0; | |
209 } | |
210 | |
211 bool append(MemPointer* ptr) { | |
212 assert(_data != NULL, "Just check"); | |
213 if (is_full()) { | |
214 return false; | |
215 } | |
216 _data[_size ++] = *(E*)ptr; | |
217 return true; | |
218 } | |
219 | |
220 bool insert_at(MemPointer* ptr, int pos) { | |
221 assert(_data != NULL, "Just check"); | |
222 if (is_full()) { | |
223 return false; | |
224 } | |
225 for (int index = _size; index > pos; index --) { | |
226 _data[index] = _data[index - 1]; | |
227 } | |
228 _data[pos] = *(E*)ptr; | |
229 _size ++; | |
230 return true; | |
231 } | |
232 | |
233 bool remove_at(int pos) { | |
234 assert(_data != NULL, "Just check"); | |
235 if (_size <= pos && pos >= 0) { | |
236 return false; | |
237 } | |
238 -- _size; | |
239 | |
240 for (int index = pos; index < _size; index ++) { | |
241 _data[index] = _data[index + 1]; | |
242 } | |
243 return true; | |
244 } | |
245 | |
246 MemPointer* at(int index) const { | |
247 assert(_data != NULL, "Just check"); | |
248 assert(index >= 0 && index < _size, "illegal index"); | |
249 return &_data[index]; | |
250 } | |
251 | |
252 bool shrink() { | |
253 float used = ((float)_size) / ((float)_max_size); | |
254 if (used < 0.40) { | |
255 E* old_ptr = _data; | |
256 int new_size = ((_max_size) / (2 * DEFAULT_PTR_ARRAY_SIZE) + 1) * DEFAULT_PTR_ARRAY_SIZE; | |
257 _data = (E*)raw_reallocate(_data, sizeof(E), new_size); | |
258 if (_data == NULL) { | |
259 _data = old_ptr; | |
260 return false; | |
261 } else { | |
262 _max_size = new_size; | |
263 return true; | |
264 } | |
265 } | |
266 return false; | |
267 } | |
268 | |
269 void sort(FN_SORT fn) { | |
270 assert(_data != NULL, "Just check"); | |
271 qsort((void*)_data, _size, sizeof(E), fn); | |
272 } | |
273 | |
274 private: | |
275 bool expand_array() { | |
276 assert(_data != NULL, "Not yet allocated"); | |
277 E* old_ptr = _data; | |
278 if ((_data = (E*)raw_reallocate((void*)_data, sizeof(E), | |
279 _max_size + DEFAULT_PTR_ARRAY_SIZE)) == NULL) { | |
280 _data = old_ptr; | |
281 return false; | |
282 } else { | |
283 _max_size += DEFAULT_PTR_ARRAY_SIZE; | |
284 if (_init_elements) { | |
285 for (int index = _size; index < _max_size; index ++) { | |
286 ::new ((void*)&_data[index]) E(); | |
287 } | |
288 } | |
289 return true; | |
290 } | |
291 } | |
292 | |
293 void* raw_allocate(size_t elementSize, int items) { | |
294 return os::malloc(elementSize * items, mtNMT); | |
295 } | |
296 | |
297 void* raw_reallocate(void* ptr, size_t elementSize, int items) { | |
298 return os::realloc(ptr, elementSize * items, mtNMT); | |
299 } | |
300 | |
301 void raw_free(void* ptr) { | |
302 os::free(ptr, mtNMT); | |
303 } | |
304 }; | |
305 | |
306 #endif // SHARE_VM_UTILITIES_MEM_PTR_ARRAY_HPP |