annotate src/share/vm/utilities/growableArray.hpp @ 1994:6cd6d394f280

7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed()) 7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages. Reviewed-by: johnc, tonyp
author ysr
date Tue, 07 Dec 2010 21:55:53 -0800
parents f95d63e2154a
children f6f3bb0ee072
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1685
diff changeset
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1080
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1080
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: 1080
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1685
diff changeset
25 #ifndef SHARE_VM_UTILITIES_GROWABLEARRAY_HPP
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1685
diff changeset
26 #define SHARE_VM_UTILITIES_GROWABLEARRAY_HPP
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1685
diff changeset
27
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1685
diff changeset
28 #include "memory/allocation.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1685
diff changeset
29 #include "memory/allocation.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1685
diff changeset
30 #include "utilities/debug.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1685
diff changeset
31 #include "utilities/globalDefinitions.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1685
diff changeset
32 #include "utilities/top.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1685
diff changeset
33
0
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // A growable array.
a61af66fc99e Initial load
duke
parents:
diff changeset
35
a61af66fc99e Initial load
duke
parents:
diff changeset
36 /*************************************************************************/
a61af66fc99e Initial load
duke
parents:
diff changeset
37 /* */
a61af66fc99e Initial load
duke
parents:
diff changeset
38 /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING */
a61af66fc99e Initial load
duke
parents:
diff changeset
39 /* */
a61af66fc99e Initial load
duke
parents:
diff changeset
40 /* Should you use GrowableArrays to contain handles you must be certain */
a61af66fc99e Initial load
duke
parents:
diff changeset
41 /* the the GrowableArray does not outlive the HandleMark that contains */
a61af66fc99e Initial load
duke
parents:
diff changeset
42 /* the handles. Since GrowableArrays are typically resource allocated */
a61af66fc99e Initial load
duke
parents:
diff changeset
43 /* the following is an example of INCORRECT CODE, */
a61af66fc99e Initial load
duke
parents:
diff changeset
44 /* */
a61af66fc99e Initial load
duke
parents:
diff changeset
45 /* ResourceMark rm; */
a61af66fc99e Initial load
duke
parents:
diff changeset
46 /* GrowableArray<Handle>* arr = new GrowableArray<Handle>(size); */
a61af66fc99e Initial load
duke
parents:
diff changeset
47 /* if (blah) { */
a61af66fc99e Initial load
duke
parents:
diff changeset
48 /* while (...) { */
a61af66fc99e Initial load
duke
parents:
diff changeset
49 /* HandleMark hm; */
a61af66fc99e Initial load
duke
parents:
diff changeset
50 /* ... */
a61af66fc99e Initial load
duke
parents:
diff changeset
51 /* Handle h(THREAD, some_oop); */
a61af66fc99e Initial load
duke
parents:
diff changeset
52 /* arr->append(h); */
a61af66fc99e Initial load
duke
parents:
diff changeset
53 /* } */
a61af66fc99e Initial load
duke
parents:
diff changeset
54 /* } */
a61af66fc99e Initial load
duke
parents:
diff changeset
55 /* if (arr->length() != 0 ) { */
a61af66fc99e Initial load
duke
parents:
diff changeset
56 /* oop bad_oop = arr->at(0)(); // Handle is BAD HERE. */
a61af66fc99e Initial load
duke
parents:
diff changeset
57 /* ... */
a61af66fc99e Initial load
duke
parents:
diff changeset
58 /* } */
a61af66fc99e Initial load
duke
parents:
diff changeset
59 /* */
a61af66fc99e Initial load
duke
parents:
diff changeset
60 /* If the GrowableArrays you are creating is C_Heap allocated then it */
a61af66fc99e Initial load
duke
parents:
diff changeset
61 /* hould not old handles since the handles could trivially try and */
a61af66fc99e Initial load
duke
parents:
diff changeset
62 /* outlive their HandleMark. In some situations you might need to do */
a61af66fc99e Initial load
duke
parents:
diff changeset
63 /* this and it would be legal but be very careful and see if you can do */
a61af66fc99e Initial load
duke
parents:
diff changeset
64 /* the code in some other manner. */
a61af66fc99e Initial load
duke
parents:
diff changeset
65 /* */
a61af66fc99e Initial load
duke
parents:
diff changeset
66 /*************************************************************************/
a61af66fc99e Initial load
duke
parents:
diff changeset
67
a61af66fc99e Initial load
duke
parents:
diff changeset
68 // To call default constructor the placement operator new() is used.
a61af66fc99e Initial load
duke
parents:
diff changeset
69 // It should be empty (it only returns the passed void* pointer).
a61af66fc99e Initial load
duke
parents:
diff changeset
70 // The definition of placement operator new(size_t, void*) in the <new>.
a61af66fc99e Initial load
duke
parents:
diff changeset
71
a61af66fc99e Initial load
duke
parents:
diff changeset
72 #include <new>
a61af66fc99e Initial load
duke
parents:
diff changeset
73
a61af66fc99e Initial load
duke
parents:
diff changeset
74 // Need the correct linkage to call qsort without warnings
a61af66fc99e Initial load
duke
parents:
diff changeset
75 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
76 typedef int (*_sort_Fn)(const void *, const void *);
a61af66fc99e Initial load
duke
parents:
diff changeset
77 }
a61af66fc99e Initial load
duke
parents:
diff changeset
78
a61af66fc99e Initial load
duke
parents:
diff changeset
79 class GenericGrowableArray : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
80 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
81 int _len; // current length
a61af66fc99e Initial load
duke
parents:
diff changeset
82 int _max; // maximum length
a61af66fc99e Initial load
duke
parents:
diff changeset
83 Arena* _arena; // Indicates where allocation occurs:
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // 0 means default ResourceArea
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // 1 means on C heap
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // otherwise, allocate in _arena
a61af66fc99e Initial load
duke
parents:
diff changeset
87 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
88 int _nesting; // resource area nesting at creation
a61af66fc99e Initial load
duke
parents:
diff changeset
89 void set_nesting();
a61af66fc99e Initial load
duke
parents:
diff changeset
90 void check_nesting();
a61af66fc99e Initial load
duke
parents:
diff changeset
91 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
92 #define set_nesting();
a61af66fc99e Initial load
duke
parents:
diff changeset
93 #define check_nesting();
a61af66fc99e Initial load
duke
parents:
diff changeset
94 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
95
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // Where are we going to allocate memory?
a61af66fc99e Initial load
duke
parents:
diff changeset
97 bool on_C_heap() { return _arena == (Arena*)1; }
a61af66fc99e Initial load
duke
parents:
diff changeset
98 bool on_stack () { return _arena == NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
99 bool on_arena () { return _arena > (Arena*)1; }
a61af66fc99e Initial load
duke
parents:
diff changeset
100
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // This GA will use the resource stack for storage if c_heap==false,
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // Else it will use the C heap. Use clear_and_deallocate to avoid leaks.
a61af66fc99e Initial load
duke
parents:
diff changeset
103 GenericGrowableArray(int initial_size, int initial_len, bool c_heap) {
a61af66fc99e Initial load
duke
parents:
diff changeset
104 _len = initial_len;
a61af66fc99e Initial load
duke
parents:
diff changeset
105 _max = initial_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
106 assert(_len >= 0 && _len <= _max, "initial_len too big");
a61af66fc99e Initial load
duke
parents:
diff changeset
107 _arena = (c_heap ? (Arena*)1 : NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
108 set_nesting();
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
109 assert(!on_C_heap() || allocated_on_C_heap(), "growable array must be on C heap if elements are");
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
110 assert(!on_stack() ||
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
111 (allocated_on_res_area() || allocated_on_stack()),
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
112 "growable array must be on stack if elements are not on arena and not on C heap");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
114
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // This GA will use the given arena for storage.
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // Consider using new(arena) GrowableArray<T> to allocate the header.
a61af66fc99e Initial load
duke
parents:
diff changeset
117 GenericGrowableArray(Arena* arena, int initial_size, int initial_len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 _len = initial_len;
a61af66fc99e Initial load
duke
parents:
diff changeset
119 _max = initial_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
120 assert(_len >= 0 && _len <= _max, "initial_len too big");
a61af66fc99e Initial load
duke
parents:
diff changeset
121 _arena = arena;
a61af66fc99e Initial load
duke
parents:
diff changeset
122 assert(on_arena(), "arena has taken on reserved value 0 or 1");
1685
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
123 // Relax next assert to allow object allocation on resource area,
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
124 // on stack or embedded into an other object.
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
125 assert(allocated_on_arena() || allocated_on_stack(),
0e35fa8ebccd 6973963: SEGV in ciBlock::start_bci() with EA
kvn
parents: 1552
diff changeset
126 "growable array must be on arena or on stack if elements are on arena");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129 void* raw_allocate(int elementSize);
432
275a3b7ff0d6 6770949: minor tweaks before 6655638
jrose
parents: 0
diff changeset
130
275a3b7ff0d6 6770949: minor tweaks before 6655638
jrose
parents: 0
diff changeset
131 // some uses pass the Thread explicitly for speed (4990299 tuning)
275a3b7ff0d6 6770949: minor tweaks before 6655638
jrose
parents: 0
diff changeset
132 void* raw_allocate(Thread* thread, int elementSize) {
275a3b7ff0d6 6770949: minor tweaks before 6655638
jrose
parents: 0
diff changeset
133 assert(on_stack(), "fast ResourceObj path only");
275a3b7ff0d6 6770949: minor tweaks before 6655638
jrose
parents: 0
diff changeset
134 return (void*)resource_allocate_bytes(thread, elementSize * _max);
275a3b7ff0d6 6770949: minor tweaks before 6655638
jrose
parents: 0
diff changeset
135 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
136 };
a61af66fc99e Initial load
duke
parents:
diff changeset
137
a61af66fc99e Initial load
duke
parents:
diff changeset
138 template<class E> class GrowableArray : public GenericGrowableArray {
a61af66fc99e Initial load
duke
parents:
diff changeset
139 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
140 E* _data; // data array
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142 void grow(int j);
a61af66fc99e Initial load
duke
parents:
diff changeset
143 void raw_at_put_grow(int i, const E& p, const E& fill);
a61af66fc99e Initial load
duke
parents:
diff changeset
144 void clear_and_deallocate();
a61af66fc99e Initial load
duke
parents:
diff changeset
145 public:
432
275a3b7ff0d6 6770949: minor tweaks before 6655638
jrose
parents: 0
diff changeset
146 GrowableArray(Thread* thread, int initial_size) : GenericGrowableArray(initial_size, 0, false) {
275a3b7ff0d6 6770949: minor tweaks before 6655638
jrose
parents: 0
diff changeset
147 _data = (E*)raw_allocate(thread, sizeof(E));
275a3b7ff0d6 6770949: minor tweaks before 6655638
jrose
parents: 0
diff changeset
148 for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E();
275a3b7ff0d6 6770949: minor tweaks before 6655638
jrose
parents: 0
diff changeset
149 }
275a3b7ff0d6 6770949: minor tweaks before 6655638
jrose
parents: 0
diff changeset
150
0
a61af66fc99e Initial load
duke
parents:
diff changeset
151 GrowableArray(int initial_size, bool C_heap = false) : GenericGrowableArray(initial_size, 0, C_heap) {
a61af66fc99e Initial load
duke
parents:
diff changeset
152 _data = (E*)raw_allocate(sizeof(E));
a61af66fc99e Initial load
duke
parents:
diff changeset
153 for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E();
a61af66fc99e Initial load
duke
parents:
diff changeset
154 }
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156 GrowableArray(int initial_size, int initial_len, const E& filler, bool C_heap = false) : GenericGrowableArray(initial_size, initial_len, C_heap) {
a61af66fc99e Initial load
duke
parents:
diff changeset
157 _data = (E*)raw_allocate(sizeof(E));
a61af66fc99e Initial load
duke
parents:
diff changeset
158 int i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
159 for (; i < _len; i++) ::new ((void*)&_data[i]) E(filler);
a61af66fc99e Initial load
duke
parents:
diff changeset
160 for (; i < _max; i++) ::new ((void*)&_data[i]) E();
a61af66fc99e Initial load
duke
parents:
diff changeset
161 }
a61af66fc99e Initial load
duke
parents:
diff changeset
162
a61af66fc99e Initial load
duke
parents:
diff changeset
163 GrowableArray(Arena* arena, int initial_size, int initial_len, const E& filler) : GenericGrowableArray(arena, initial_size, initial_len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
164 _data = (E*)raw_allocate(sizeof(E));
a61af66fc99e Initial load
duke
parents:
diff changeset
165 int i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
166 for (; i < _len; i++) ::new ((void*)&_data[i]) E(filler);
a61af66fc99e Initial load
duke
parents:
diff changeset
167 for (; i < _max; i++) ::new ((void*)&_data[i]) E();
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 GrowableArray() : GenericGrowableArray(2, 0, false) {
a61af66fc99e Initial load
duke
parents:
diff changeset
171 _data = (E*)raw_allocate(sizeof(E));
a61af66fc99e Initial load
duke
parents:
diff changeset
172 ::new ((void*)&_data[0]) E();
a61af66fc99e Initial load
duke
parents:
diff changeset
173 ::new ((void*)&_data[1]) E();
a61af66fc99e Initial load
duke
parents:
diff changeset
174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
175
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // Does nothing for resource and arena objects
a61af66fc99e Initial load
duke
parents:
diff changeset
177 ~GrowableArray() { if (on_C_heap()) clear_and_deallocate(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
178
a61af66fc99e Initial load
duke
parents:
diff changeset
179 void clear() { _len = 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
180 int length() const { return _len; }
a61af66fc99e Initial load
duke
parents:
diff changeset
181 void trunc_to(int l) { assert(l <= _len,"cannot increase length"); _len = l; }
a61af66fc99e Initial load
duke
parents:
diff changeset
182 bool is_empty() const { return _len == 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
183 bool is_nonempty() const { return _len != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
184 bool is_full() const { return _len == _max; }
a61af66fc99e Initial load
duke
parents:
diff changeset
185 DEBUG_ONLY(E* data_addr() const { return _data; })
a61af66fc99e Initial load
duke
parents:
diff changeset
186
a61af66fc99e Initial load
duke
parents:
diff changeset
187 void print();
a61af66fc99e Initial load
duke
parents:
diff changeset
188
432
275a3b7ff0d6 6770949: minor tweaks before 6655638
jrose
parents: 0
diff changeset
189 int append(const E& elem) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
190 check_nesting();
a61af66fc99e Initial load
duke
parents:
diff changeset
191 if (_len == _max) grow(_len);
432
275a3b7ff0d6 6770949: minor tweaks before 6655638
jrose
parents: 0
diff changeset
192 int idx = _len++;
275a3b7ff0d6 6770949: minor tweaks before 6655638
jrose
parents: 0
diff changeset
193 _data[idx] = elem;
275a3b7ff0d6 6770949: minor tweaks before 6655638
jrose
parents: 0
diff changeset
194 return idx;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
195 }
a61af66fc99e Initial load
duke
parents:
diff changeset
196
a61af66fc99e Initial load
duke
parents:
diff changeset
197 void append_if_missing(const E& elem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
198 if (!contains(elem)) append(elem);
a61af66fc99e Initial load
duke
parents:
diff changeset
199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
200
a61af66fc99e Initial load
duke
parents:
diff changeset
201 E at(int i) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
202 assert(0 <= i && i < _len, "illegal index");
a61af66fc99e Initial load
duke
parents:
diff changeset
203 return _data[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
205
a61af66fc99e Initial load
duke
parents:
diff changeset
206 E* adr_at(int i) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
207 assert(0 <= i && i < _len, "illegal index");
a61af66fc99e Initial load
duke
parents:
diff changeset
208 return &_data[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
210
a61af66fc99e Initial load
duke
parents:
diff changeset
211 E first() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 assert(_len > 0, "empty list");
a61af66fc99e Initial load
duke
parents:
diff changeset
213 return _data[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
215
a61af66fc99e Initial load
duke
parents:
diff changeset
216 E top() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
217 assert(_len > 0, "empty list");
a61af66fc99e Initial load
duke
parents:
diff changeset
218 return _data[_len-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
220
a61af66fc99e Initial load
duke
parents:
diff changeset
221 void push(const E& elem) { append(elem); }
a61af66fc99e Initial load
duke
parents:
diff changeset
222
a61af66fc99e Initial load
duke
parents:
diff changeset
223 E pop() {
a61af66fc99e Initial load
duke
parents:
diff changeset
224 assert(_len > 0, "empty list");
a61af66fc99e Initial load
duke
parents:
diff changeset
225 return _data[--_len];
a61af66fc99e Initial load
duke
parents:
diff changeset
226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
227
a61af66fc99e Initial load
duke
parents:
diff changeset
228 void at_put(int i, const E& elem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
229 assert(0 <= i && i < _len, "illegal index");
a61af66fc99e Initial load
duke
parents:
diff changeset
230 _data[i] = elem;
a61af66fc99e Initial load
duke
parents:
diff changeset
231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233 E at_grow(int i, const E& fill = E()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
234 assert(0 <= i, "negative index");
a61af66fc99e Initial load
duke
parents:
diff changeset
235 check_nesting();
a61af66fc99e Initial load
duke
parents:
diff changeset
236 if (i >= _len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
237 if (i >= _max) grow(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
238 for (int j = _len; j <= i; j++)
a61af66fc99e Initial load
duke
parents:
diff changeset
239 _data[j] = fill;
a61af66fc99e Initial load
duke
parents:
diff changeset
240 _len = i+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
242 return _data[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
243 }
a61af66fc99e Initial load
duke
parents:
diff changeset
244
a61af66fc99e Initial load
duke
parents:
diff changeset
245 void at_put_grow(int i, const E& elem, const E& fill = E()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
246 assert(0 <= i, "negative index");
a61af66fc99e Initial load
duke
parents:
diff changeset
247 check_nesting();
a61af66fc99e Initial load
duke
parents:
diff changeset
248 raw_at_put_grow(i, elem, fill);
a61af66fc99e Initial load
duke
parents:
diff changeset
249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
250
a61af66fc99e Initial load
duke
parents:
diff changeset
251 bool contains(const E& elem) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
252 for (int i = 0; i < _len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
253 if (_data[i] == elem) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
254 }
a61af66fc99e Initial load
duke
parents:
diff changeset
255 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
257
a61af66fc99e Initial load
duke
parents:
diff changeset
258 int find(const E& elem) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
259 for (int i = 0; i < _len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
260 if (_data[i] == elem) return i;
a61af66fc99e Initial load
duke
parents:
diff changeset
261 }
a61af66fc99e Initial load
duke
parents:
diff changeset
262 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
264
a61af66fc99e Initial load
duke
parents:
diff changeset
265 int find(void* token, bool f(void*, E)) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
266 for (int i = 0; i < _len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
267 if (f(token, _data[i])) return i;
a61af66fc99e Initial load
duke
parents:
diff changeset
268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
269 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
270 }
a61af66fc99e Initial load
duke
parents:
diff changeset
271
a61af66fc99e Initial load
duke
parents:
diff changeset
272 int find_at_end(void* token, bool f(void*, E)) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
273 // start at the end of the array
a61af66fc99e Initial load
duke
parents:
diff changeset
274 for (int i = _len-1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
275 if (f(token, _data[i])) return i;
a61af66fc99e Initial load
duke
parents:
diff changeset
276 }
a61af66fc99e Initial load
duke
parents:
diff changeset
277 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
279
a61af66fc99e Initial load
duke
parents:
diff changeset
280 void remove(const E& elem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
281 for (int i = 0; i < _len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
282 if (_data[i] == elem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
283 for (int j = i + 1; j < _len; j++) _data[j-1] = _data[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
284 _len--;
a61af66fc99e Initial load
duke
parents:
diff changeset
285 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
286 }
a61af66fc99e Initial load
duke
parents:
diff changeset
287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
288 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
289 }
a61af66fc99e Initial load
duke
parents:
diff changeset
290
a61af66fc99e Initial load
duke
parents:
diff changeset
291 void remove_at(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
292 assert(0 <= index && index < _len, "illegal index");
a61af66fc99e Initial load
duke
parents:
diff changeset
293 for (int j = index + 1; j < _len; j++) _data[j-1] = _data[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
294 _len--;
a61af66fc99e Initial load
duke
parents:
diff changeset
295 }
a61af66fc99e Initial load
duke
parents:
diff changeset
296
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 470
diff changeset
297 // inserts the given element before the element at index i
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 470
diff changeset
298 void insert_before(const int idx, const E& elem) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 470
diff changeset
299 check_nesting();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 470
diff changeset
300 if (_len == _max) grow(_len);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 470
diff changeset
301 for (int j = _len - 1; j >= idx; j--) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 470
diff changeset
302 _data[j + 1] = _data[j];
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 470
diff changeset
303 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 470
diff changeset
304 _len++;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 470
diff changeset
305 _data[idx] = elem;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 470
diff changeset
306 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 470
diff changeset
307
0
a61af66fc99e Initial load
duke
parents:
diff changeset
308 void appendAll(const GrowableArray<E>* l) {
a61af66fc99e Initial load
duke
parents:
diff changeset
309 for (int i = 0; i < l->_len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
310 raw_at_put_grow(_len, l->_data[i], 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
313
a61af66fc99e Initial load
duke
parents:
diff changeset
314 void sort(int f(E*,E*)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
315 qsort(_data, length(), sizeof(E), (_sort_Fn)f);
a61af66fc99e Initial load
duke
parents:
diff changeset
316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
317 // sort by fixed-stride sub arrays:
a61af66fc99e Initial load
duke
parents:
diff changeset
318 void sort(int f(E*,E*), int stride) {
a61af66fc99e Initial load
duke
parents:
diff changeset
319 qsort(_data, length() / stride, sizeof(E) * stride, (_sort_Fn)f);
a61af66fc99e Initial load
duke
parents:
diff changeset
320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
321 };
a61af66fc99e Initial load
duke
parents:
diff changeset
322
a61af66fc99e Initial load
duke
parents:
diff changeset
323 // Global GrowableArray methods (one instance in the library per each 'E' type).
a61af66fc99e Initial load
duke
parents:
diff changeset
324
a61af66fc99e Initial load
duke
parents:
diff changeset
325 template<class E> void GrowableArray<E>::grow(int j) {
a61af66fc99e Initial load
duke
parents:
diff changeset
326 // grow the array by doubling its size (amortized growth)
a61af66fc99e Initial load
duke
parents:
diff changeset
327 int old_max = _max;
a61af66fc99e Initial load
duke
parents:
diff changeset
328 if (_max == 0) _max = 1; // prevent endless loop
a61af66fc99e Initial load
duke
parents:
diff changeset
329 while (j >= _max) _max = _max*2;
a61af66fc99e Initial load
duke
parents:
diff changeset
330 // j < _max
a61af66fc99e Initial load
duke
parents:
diff changeset
331 E* newData = (E*)raw_allocate(sizeof(E));
a61af66fc99e Initial load
duke
parents:
diff changeset
332 int i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
333 for ( ; i < _len; i++) ::new ((void*)&newData[i]) E(_data[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
334 for ( ; i < _max; i++) ::new ((void*)&newData[i]) E();
a61af66fc99e Initial load
duke
parents:
diff changeset
335 for (i = 0; i < old_max; i++) _data[i].~E();
a61af66fc99e Initial load
duke
parents:
diff changeset
336 if (on_C_heap() && _data != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
337 FreeHeap(_data);
a61af66fc99e Initial load
duke
parents:
diff changeset
338 }
a61af66fc99e Initial load
duke
parents:
diff changeset
339 _data = newData;
a61af66fc99e Initial load
duke
parents:
diff changeset
340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
341
a61af66fc99e Initial load
duke
parents:
diff changeset
342 template<class E> void GrowableArray<E>::raw_at_put_grow(int i, const E& p, const E& fill) {
a61af66fc99e Initial load
duke
parents:
diff changeset
343 if (i >= _len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
344 if (i >= _max) grow(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
345 for (int j = _len; j < i; j++)
a61af66fc99e Initial load
duke
parents:
diff changeset
346 _data[j] = fill;
a61af66fc99e Initial load
duke
parents:
diff changeset
347 _len = i+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
348 }
a61af66fc99e Initial load
duke
parents:
diff changeset
349 _data[i] = p;
a61af66fc99e Initial load
duke
parents:
diff changeset
350 }
a61af66fc99e Initial load
duke
parents:
diff changeset
351
a61af66fc99e Initial load
duke
parents:
diff changeset
352 // This function clears and deallocate the data in the growable array that
a61af66fc99e Initial load
duke
parents:
diff changeset
353 // has been allocated on the C heap. It's not public - called by the
a61af66fc99e Initial load
duke
parents:
diff changeset
354 // destructor.
a61af66fc99e Initial load
duke
parents:
diff changeset
355 template<class E> void GrowableArray<E>::clear_and_deallocate() {
a61af66fc99e Initial load
duke
parents:
diff changeset
356 assert(on_C_heap(),
a61af66fc99e Initial load
duke
parents:
diff changeset
357 "clear_and_deallocate should only be called when on C heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
358 clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
359 if (_data != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
360 for (int i = 0; i < _max; i++) _data[i].~E();
a61af66fc99e Initial load
duke
parents:
diff changeset
361 FreeHeap(_data);
a61af66fc99e Initial load
duke
parents:
diff changeset
362 _data = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
363 }
a61af66fc99e Initial load
duke
parents:
diff changeset
364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
365
a61af66fc99e Initial load
duke
parents:
diff changeset
366 template<class E> void GrowableArray<E>::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
367 tty->print("Growable Array " INTPTR_FORMAT, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
368 tty->print(": length %ld (_max %ld) { ", _len, _max);
a61af66fc99e Initial load
duke
parents:
diff changeset
369 for (int i = 0; i < _len; i++) tty->print(INTPTR_FORMAT " ", *(intptr_t*)&(_data[i]));
a61af66fc99e Initial load
duke
parents:
diff changeset
370 tty->print("}\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
371 }
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1685
diff changeset
372
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1685
diff changeset
373 #endif // SHARE_VM_UTILITIES_GROWABLEARRAY_HPP