Mercurial > hg > truffle
annotate src/share/vm/utilities/array.hpp @ 1796:18c378513575
Merge
author | kvn |
---|---|
date | Thu, 16 Sep 2010 16:48:40 -0700 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
470
diff
changeset
|
2 * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
470
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
470
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
470
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 // correct linkage required to compile w/o warnings | |
26 // (must be on file level - cannot be local) | |
27 extern "C" { typedef int (*ftype)(const void*, const void*); } | |
28 | |
29 | |
30 class ResourceArray: public ResourceObj { | |
31 protected: | |
32 int _length; // the number of array elements | |
33 void* _data; // the array memory | |
34 #ifdef ASSERT | |
35 int _nesting; // the resource area nesting level | |
36 #endif | |
37 | |
38 // creation | |
39 ResourceArray() { | |
40 _length = 0; | |
41 _data = NULL; | |
42 DEBUG_ONLY(init_nesting();) | |
432 | 43 // client may call initialize, at most once |
0 | 44 } |
45 | |
46 | |
47 ResourceArray(size_t esize, int length) { | |
432 | 48 DEBUG_ONLY(_data = NULL); |
49 initialize(esize, length); | |
50 } | |
51 | |
52 void initialize(size_t esize, int length) { | |
0 | 53 assert(length >= 0, "illegal length"); |
432 | 54 assert(_data == NULL, "must be new object"); |
0 | 55 _length = length; |
56 _data = resource_allocate_bytes(esize * length); | |
57 DEBUG_ONLY(init_nesting();) | |
58 } | |
59 | |
60 #ifdef ASSERT | |
61 void init_nesting(); | |
62 #endif | |
63 | |
64 // helper functions | |
65 void sort (size_t esize, ftype f); // sort the array | |
66 void expand (size_t esize, int i, int& size);// expand the array to include slot i | |
67 void remove_at(size_t esize, int i); // remove the element in slot i | |
68 | |
69 public: | |
70 // standard operations | |
71 int length() const { return _length; } | |
72 bool is_empty() const { return length() == 0; } | |
73 }; | |
74 | |
75 | |
76 class CHeapArray: public CHeapObj { | |
77 protected: | |
78 int _length; // the number of array elements | |
79 void* _data; // the array memory | |
80 | |
81 // creation | |
82 CHeapArray() { | |
83 _length = 0; | |
84 _data = NULL; | |
85 } | |
86 | |
87 | |
88 CHeapArray(size_t esize, int length) { | |
89 assert(length >= 0, "illegal length"); | |
90 _length = length; | |
91 _data = (void*) NEW_C_HEAP_ARRAY(char *, esize * length); | |
92 } | |
93 | |
94 #ifdef ASSERT | |
95 void init_nesting(); | |
96 #endif | |
97 | |
98 // helper functions | |
99 void sort (size_t esize, ftype f); // sort the array | |
100 void expand (size_t esize, int i, int& size);// expand the array to include slot i | |
101 void remove_at(size_t esize, int i); // remove the element in slot i | |
102 | |
103 public: | |
104 // standard operations | |
105 int length() const { return _length; } | |
106 bool is_empty() const { return length() == 0; } | |
107 }; | |
108 | |
109 #define define_generic_array(array_name,element_type, base_class) \ | |
110 class array_name: public base_class { \ | |
111 protected: \ | |
112 typedef element_type etype; \ | |
113 enum { esize = sizeof(etype) }; \ | |
114 \ | |
115 void base_remove_at(size_t size, int i) { base_class::remove_at(size, i); } \ | |
116 \ | |
117 public: \ | |
118 /* creation */ \ | |
119 array_name() : base_class() {} \ | |
120 array_name(const int length) : base_class(esize, length) {} \ | |
432 | 121 array_name(const int length, const etype fx) { initialize(length, fx); } \ |
122 void initialize(const int length) { base_class::initialize(esize, length); } \ | |
123 void initialize(const int length, const etype fx) { \ | |
124 initialize(length); \ | |
0 | 125 for (int i = 0; i < length; i++) ((etype*)_data)[i] = fx; \ |
126 } \ | |
127 \ | |
128 /* standard operations */ \ | |
129 etype& operator [] (const int i) const { \ | |
130 assert(0 <= i && i < length(), "index out of bounds"); \ | |
131 return ((etype*)_data)[i]; \ | |
132 } \ | |
133 \ | |
134 int index_of(const etype x) const { \ | |
135 int i = length(); \ | |
136 while (i-- > 0 && ((etype*)_data)[i] != x) ; \ | |
137 /* i < 0 || ((etype*)_data)_data[i] == x */ \ | |
138 return i; \ | |
139 } \ | |
140 \ | |
141 void sort(int f(etype*, etype*)) { base_class::sort(esize, (ftype)f); } \ | |
142 bool contains(const etype x) const { return index_of(x) >= 0; } \ | |
143 \ | |
144 /* deprecated operations - for compatibility with GrowableArray only */ \ | |
145 etype at(const int i) const { return (*this)[i]; } \ | |
146 void at_put(const int i, const etype x) { (*this)[i] = x; } \ | |
147 etype* adr_at(const int i) { return &(*this)[i]; } \ | |
148 int find(const etype x) { return index_of(x); } \ | |
149 }; \ | |
150 | |
151 | |
152 #define define_array(array_name,element_type) \ | |
153 define_generic_array(array_name, element_type, ResourceArray) | |
154 | |
155 | |
156 #define define_stack(stack_name,array_name) \ | |
157 class stack_name: public array_name { \ | |
158 protected: \ | |
159 int _size; \ | |
160 \ | |
161 void grow(const int i, const etype fx) { \ | |
162 assert(i >= length(), "index too small"); \ | |
163 if (i >= size()) expand(esize, i, _size); \ | |
164 for (int j = length(); j <= i; j++) ((etype*)_data)[j] = fx; \ | |
165 _length = i+1; \ | |
166 } \ | |
167 \ | |
168 public: \ | |
169 /* creation */ \ | |
432 | 170 stack_name() : array_name() { _size = 0; } \ |
171 stack_name(const int size) { initialize(size); } \ | |
172 stack_name(const int size, const etype fx) { initialize(size, fx); } \ | |
173 void initialize(const int size, const etype fx) { \ | |
174 _size = size; \ | |
175 array_name::initialize(size, fx); \ | |
176 /* _length == size, allocation and size are the same */ \ | |
177 } \ | |
178 void initialize(const int size) { \ | |
179 _size = size; \ | |
180 array_name::initialize(size); \ | |
181 _length = 0; /* reset length to zero; _size records the allocation */ \ | |
182 } \ | |
0 | 183 \ |
184 /* standard operations */ \ | |
185 int size() const { return _size; } \ | |
186 \ | |
432 | 187 int push(const etype x) { \ |
188 int len = length(); \ | |
189 if (len >= size()) expand(esize, len, _size); \ | |
190 ((etype*)_data)[len] = x; \ | |
191 _length = len+1; \ | |
192 return len; \ | |
0 | 193 } \ |
194 \ | |
195 etype pop() { \ | |
196 assert(!is_empty(), "stack is empty"); \ | |
197 return ((etype*)_data)[--_length]; \ | |
198 } \ | |
199 \ | |
200 etype top() const { \ | |
201 assert(!is_empty(), "stack is empty"); \ | |
202 return ((etype*)_data)[length() - 1]; \ | |
203 } \ | |
204 \ | |
205 void push_all(const stack_name* stack) { \ | |
206 const int l = stack->length(); \ | |
207 for (int i = 0; i < l; i++) push(((etype*)(stack->_data))[i]); \ | |
208 } \ | |
209 \ | |
210 etype at_grow(const int i, const etype fx) { \ | |
211 if (i >= length()) grow(i, fx); \ | |
212 return ((etype*)_data)[i]; \ | |
213 } \ | |
214 \ | |
215 void at_put_grow(const int i, const etype x, const etype fx) { \ | |
216 if (i >= length()) grow(i, fx); \ | |
217 ((etype*)_data)[i] = x; \ | |
218 } \ | |
219 \ | |
220 void truncate(const int length) { \ | |
221 assert(0 <= length && length <= this->length(), "illegal length"); \ | |
222 _length = length; \ | |
223 } \ | |
224 \ | |
225 void remove_at(int i) { base_remove_at(esize, i); } \ | |
226 void remove(etype x) { remove_at(index_of(x)); } \ | |
227 \ | |
228 /* inserts the given element before the element at index i */ \ | |
229 void insert_before(const int i, const etype el) { \ | |
230 int len = length(); \ | |
231 int new_length = len + 1; \ | |
232 if (new_length >= size()) expand(esize, new_length, _size); \ | |
233 for (int j = len - 1; j >= i; j--) { \ | |
234 ((etype*)_data)[j + 1] = ((etype*)_data)[j]; \ | |
235 } \ | |
236 _length = new_length; \ | |
237 at_put(i, el); \ | |
238 } \ | |
239 \ | |
240 /* inserts contents of the given stack before the element at index i */ \ | |
241 void insert_before(const int i, const stack_name *st) { \ | |
242 if (st->length() == 0) return; \ | |
243 int len = length(); \ | |
244 int st_len = st->length(); \ | |
245 int new_length = len + st_len; \ | |
246 if (new_length >= size()) expand(esize, new_length, _size); \ | |
247 int j; \ | |
248 for (j = len - 1; j >= i; j--) { \ | |
249 ((etype*)_data)[j + st_len] = ((etype*)_data)[j]; \ | |
250 } \ | |
251 for (j = 0; j < st_len; j++) { \ | |
252 ((etype*)_data)[i + j] = ((etype*)st->_data)[j]; \ | |
253 } \ | |
254 _length = new_length; \ | |
255 } \ | |
256 \ | |
257 /* deprecated operations - for compatibility with GrowableArray only */ \ | |
258 int capacity() const { return size(); } \ | |
259 void clear() { truncate(0); } \ | |
260 void trunc_to(const int length) { truncate(length); } \ | |
432 | 261 int append(const etype x) { return push(x); } \ |
0 | 262 void appendAll(const stack_name* stack) { push_all(stack); } \ |
263 etype last() const { return top(); } \ | |
264 }; \ | |
265 | |
266 | |
267 #define define_resource_list(element_type) \ | |
268 define_generic_array(element_type##Array, element_type, ResourceArray) \ | |
269 define_stack(element_type##List, element_type##Array) | |
270 | |
271 #define define_resource_pointer_list(element_type) \ | |
272 define_generic_array(element_type##Array, element_type *, ResourceArray) \ | |
273 define_stack(element_type##List, element_type##Array) | |
274 | |
275 #define define_c_heap_list(element_type) \ | |
276 define_generic_array(element_type##Array, element_type, CHeapArray) \ | |
277 define_stack(element_type##List, element_type##Array) | |
278 | |
279 #define define_c_heap_pointer_list(element_type) \ | |
280 define_generic_array(element_type##Array, element_type *, CHeapArray) \ | |
281 define_stack(element_type##List, element_type##Array) | |
282 | |
283 | |
284 // Arrays for basic types | |
285 | |
286 define_array(boolArray, bool) define_stack(boolStack, boolArray) | |
287 define_array(intArray , int ) define_stack(intStack , intArray ) |