src/share/vm/services/memPtrArray.hpp

changeset 7074
833b0f92429a
parent 4053
33143ee07800
child 6876
710a3c8b516e
equal deleted inserted replaced
7073:4d3a43351904 7074:833b0f92429a
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 NOT_PRODUCT(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 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
204 NOT_PRODUCT(int capacity() const { return _max_size; })
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

mercurial