Mercurial > hg > truffle
annotate src/share/vm/utilities/taskqueue.hpp @ 1638:b2a00dd3117c
6957084: simplify TaskQueue overflow handling
Reviewed-by: ysr, jmasa
author | jcoomes |
---|---|
date | Thu, 01 Jul 2010 21:40:45 -0700 |
parents | c18cbe5936b8 |
children | a93a9eda13f7 |
rev | line source |
---|---|
0 | 1 /* |
1638 | 2 * Copyright (c) 2001, 2010, 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:
1311
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1311
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:
1311
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
25 template <unsigned int N> |
0 | 26 class TaskQueueSuper: public CHeapObj { |
27 protected: | |
907 | 28 // Internal type for indexing the queue; also used for the tag. |
29 typedef NOT_LP64(uint16_t) LP64_ONLY(uint32_t) idx_t; | |
30 | |
31 // The first free element after the last one pushed (mod N). | |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
32 volatile uint _bottom; |
0 | 33 |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
34 enum { MOD_N_MASK = N - 1 }; |
907 | 35 |
36 class Age { | |
37 public: | |
38 Age(size_t data = 0) { _data = data; } | |
39 Age(const Age& age) { _data = age._data; } | |
40 Age(idx_t top, idx_t tag) { _fields._top = top; _fields._tag = tag; } | |
0 | 41 |
907 | 42 Age get() const volatile { return _data; } |
43 void set(Age age) volatile { _data = age._data; } | |
44 | |
45 idx_t top() const volatile { return _fields._top; } | |
46 idx_t tag() const volatile { return _fields._tag; } | |
0 | 47 |
907 | 48 // Increment top; if it wraps, increment tag also. |
49 void increment() { | |
50 _fields._top = increment_index(_fields._top); | |
51 if (_fields._top == 0) ++_fields._tag; | |
52 } | |
0 | 53 |
907 | 54 Age cmpxchg(const Age new_age, const Age old_age) volatile { |
55 return (size_t) Atomic::cmpxchg_ptr((intptr_t)new_age._data, | |
56 (volatile intptr_t *)&_data, | |
57 (intptr_t)old_age._data); | |
58 } | |
59 | |
60 bool operator ==(const Age& other) const { return _data == other._data; } | |
0 | 61 |
907 | 62 private: |
63 struct fields { | |
64 idx_t _top; | |
65 idx_t _tag; | |
66 }; | |
67 union { | |
68 size_t _data; | |
69 fields _fields; | |
70 }; | |
0 | 71 }; |
907 | 72 |
73 volatile Age _age; | |
74 | |
75 // These both operate mod N. | |
76 static uint increment_index(uint ind) { | |
77 return (ind + 1) & MOD_N_MASK; | |
0 | 78 } |
907 | 79 static uint decrement_index(uint ind) { |
80 return (ind - 1) & MOD_N_MASK; | |
0 | 81 } |
82 | |
907 | 83 // Returns a number in the range [0..N). If the result is "N-1", it should be |
84 // interpreted as 0. | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
85 uint dirty_size(uint bot, uint top) const { |
907 | 86 return (bot - top) & MOD_N_MASK; |
0 | 87 } |
88 | |
89 // Returns the size corresponding to the given "bot" and "top". | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
90 uint size(uint bot, uint top) const { |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
91 uint sz = dirty_size(bot, top); |
907 | 92 // Has the queue "wrapped", so that bottom is less than top? There's a |
93 // complicated special case here. A pair of threads could perform pop_local | |
94 // and pop_global operations concurrently, starting from a state in which | |
95 // _bottom == _top+1. The pop_local could succeed in decrementing _bottom, | |
96 // and the pop_global in incrementing _top (in which case the pop_global | |
97 // will be awarded the contested queue element.) The resulting state must | |
98 // be interpreted as an empty queue. (We only need to worry about one such | |
99 // event: only the queue owner performs pop_local's, and several concurrent | |
100 // threads attempting to perform the pop_global will all perform the same | |
101 // CAS, and only one can succeed.) Any stealing thread that reads after | |
102 // either the increment or decrement will see an empty queue, and will not | |
103 // join the competitors. The "sz == -1 || sz == N-1" state will not be | |
104 // modified by concurrent queues, so the owner thread can reset the state to | |
105 // _bottom == top so subsequent pushes will be performed normally. | |
106 return (sz == N - 1) ? 0 : sz; | |
0 | 107 } |
108 | |
109 public: | |
110 TaskQueueSuper() : _bottom(0), _age() {} | |
111 | |
1638 | 112 // Return true if the TaskQueue contains/does not contain any tasks. |
113 bool peek() const { return _bottom != _age.top(); } | |
114 bool is_empty() const { return size() == 0; } | |
0 | 115 |
116 // Return an estimate of the number of elements in the queue. | |
117 // The "careful" version admits the possibility of pop_local/pop_global | |
118 // races. | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
119 uint size() const { |
907 | 120 return size(_bottom, _age.top()); |
0 | 121 } |
122 | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
123 uint dirty_size() const { |
907 | 124 return dirty_size(_bottom, _age.top()); |
0 | 125 } |
126 | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
127 void set_empty() { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
128 _bottom = 0; |
907 | 129 _age.set(0); |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
130 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
131 |
0 | 132 // Maximum number of elements allowed in the queue. This is two less |
133 // than the actual queue size, for somewhat complicated reasons. | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
134 uint max_elems() const { return N - 2; } |
1284 | 135 |
136 // Total size of queue. | |
137 static const uint total_size() { return N; } | |
0 | 138 }; |
139 | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
140 template<class E, unsigned int N = TASKQUEUE_SIZE> |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
141 class GenericTaskQueue: public TaskQueueSuper<N> { |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
142 protected: |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
143 typedef typename TaskQueueSuper<N>::Age Age; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
144 typedef typename TaskQueueSuper<N>::idx_t idx_t; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
145 |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
146 using TaskQueueSuper<N>::_bottom; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
147 using TaskQueueSuper<N>::_age; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
148 using TaskQueueSuper<N>::increment_index; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
149 using TaskQueueSuper<N>::decrement_index; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
150 using TaskQueueSuper<N>::dirty_size; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
151 |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
152 public: |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
153 using TaskQueueSuper<N>::max_elems; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
154 using TaskQueueSuper<N>::size; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
155 |
0 | 156 private: |
157 // Slow paths for push, pop_local. (pop_global has no fast path.) | |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
158 bool push_slow(E t, uint dirty_n_elems); |
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
159 bool pop_local_slow(uint localBot, Age oldAge); |
0 | 160 |
161 public: | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
162 typedef E element_type; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
163 |
0 | 164 // Initializes the queue to empty. |
165 GenericTaskQueue(); | |
166 | |
167 void initialize(); | |
168 | |
1638 | 169 // Push the task "t" on the queue. Returns "false" iff the queue is full. |
0 | 170 inline bool push(E t); |
171 | |
1638 | 172 // Attempts to claim a task from the "local" end of the queue (the most |
173 // recently pushed). If successful, returns true and sets t to the task; | |
174 // otherwise, returns false (the queue is empty). | |
0 | 175 inline bool pop_local(E& t); |
176 | |
1638 | 177 // Like pop_local(), but uses the "global" end of the queue (the least |
178 // recently pushed). | |
0 | 179 bool pop_global(E& t); |
180 | |
181 // Delete any resource associated with the queue. | |
182 ~GenericTaskQueue(); | |
183 | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
184 // apply the closure to all elements in the task queue |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
185 void oops_do(OopClosure* f); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
186 |
0 | 187 private: |
188 // Element array. | |
189 volatile E* _elems; | |
190 }; | |
191 | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
192 template<class E, unsigned int N> |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
193 GenericTaskQueue<E, N>::GenericTaskQueue() { |
907 | 194 assert(sizeof(Age) == sizeof(size_t), "Depends on this."); |
0 | 195 } |
196 | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
197 template<class E, unsigned int N> |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
198 void GenericTaskQueue<E, N>::initialize() { |
907 | 199 _elems = NEW_C_HEAP_ARRAY(E, N); |
0 | 200 } |
201 | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
202 template<class E, unsigned int N> |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
203 void GenericTaskQueue<E, N>::oops_do(OopClosure* f) { |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
204 // tty->print_cr("START OopTaskQueue::oops_do"); |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
205 uint iters = size(); |
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
206 uint index = _bottom; |
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
207 for (uint i = 0; i < iters; ++i) { |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
208 index = decrement_index(index); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
209 // tty->print_cr(" doing entry %d," INTPTR_T " -> " INTPTR_T, |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
210 // index, &_elems[index], _elems[index]); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
211 E* t = (E*)&_elems[index]; // cast away volatility |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
212 oop* p = (oop*)t; |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
213 assert((*t)->is_oop_or_null(), "Not an oop or null"); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
214 f->do_oop(p); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
215 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
216 // tty->print_cr("END OopTaskQueue::oops_do"); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
217 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
218 |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
219 template<class E, unsigned int N> |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
220 bool GenericTaskQueue<E, N>::push_slow(E t, uint dirty_n_elems) { |
907 | 221 if (dirty_n_elems == N - 1) { |
0 | 222 // Actually means 0, so do the push. |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
223 uint localBot = _bottom; |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
224 // g++ complains if the volatile result of the assignment is unused. |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
225 const_cast<E&>(_elems[localBot] = t); |
1024
2c03ce058f55
6888847: TaskQueue needs release_store() for correctness on RMO machines
bobv
parents:
907
diff
changeset
|
226 OrderAccess::release_store(&_bottom, increment_index(localBot)); |
0 | 227 return true; |
907 | 228 } |
229 return false; | |
0 | 230 } |
231 | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
232 template<class E, unsigned int N> |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
233 bool GenericTaskQueue<E, N>:: |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
234 pop_local_slow(uint localBot, Age oldAge) { |
0 | 235 // This queue was observed to contain exactly one element; either this |
236 // thread will claim it, or a competing "pop_global". In either case, | |
237 // the queue will be logically empty afterwards. Create a new Age value | |
238 // that represents the empty queue for the given value of "_bottom". (We | |
239 // must also increment "tag" because of the case where "bottom == 1", | |
240 // "top == 0". A pop_global could read the queue element in that case, | |
241 // then have the owner thread do a pop followed by another push. Without | |
242 // the incrementing of "tag", the pop_global's CAS could succeed, | |
243 // allowing it to believe it has claimed the stale element.) | |
907 | 244 Age newAge((idx_t)localBot, oldAge.tag() + 1); |
0 | 245 // Perhaps a competing pop_global has already incremented "top", in which |
246 // case it wins the element. | |
247 if (localBot == oldAge.top()) { | |
248 // No competing pop_global has yet incremented "top"; we'll try to | |
249 // install new_age, thus claiming the element. | |
907 | 250 Age tempAge = _age.cmpxchg(newAge, oldAge); |
0 | 251 if (tempAge == oldAge) { |
252 // We win. | |
907 | 253 assert(dirty_size(localBot, _age.top()) != N - 1, "sanity"); |
0 | 254 return true; |
255 } | |
256 } | |
907 | 257 // We lose; a completing pop_global gets the element. But the queue is empty |
258 // and top is greater than bottom. Fix this representation of the empty queue | |
259 // to become the canonical one. | |
260 _age.set(newAge); | |
261 assert(dirty_size(localBot, _age.top()) != N - 1, "sanity"); | |
0 | 262 return false; |
263 } | |
264 | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
265 template<class E, unsigned int N> |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
266 bool GenericTaskQueue<E, N>::pop_global(E& t) { |
907 | 267 Age oldAge = _age.get(); |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
268 uint localBot = _bottom; |
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
269 uint n_elems = size(localBot, oldAge.top()); |
0 | 270 if (n_elems == 0) { |
271 return false; | |
272 } | |
907 | 273 |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
274 const_cast<E&>(t = _elems[oldAge.top()]); |
907 | 275 Age newAge(oldAge); |
276 newAge.increment(); | |
277 Age resAge = _age.cmpxchg(newAge, oldAge); | |
278 | |
0 | 279 // Note that using "_bottom" here might fail, since a pop_local might |
280 // have decremented it. | |
907 | 281 assert(dirty_size(localBot, newAge.top()) != N - 1, "sanity"); |
282 return resAge == oldAge; | |
0 | 283 } |
284 | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
285 template<class E, unsigned int N> |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
286 GenericTaskQueue<E, N>::~GenericTaskQueue() { |
0 | 287 FREE_C_HEAP_ARRAY(E, _elems); |
288 } | |
289 | |
1638 | 290 // OverflowTaskQueue is a TaskQueue that also includes an overflow stack for |
291 // elements that do not fit in the TaskQueue. | |
292 // | |
293 // Three methods from super classes are overridden: | |
294 // | |
295 // initialize() - initialize the super classes and create the overflow stack | |
296 // push() - push onto the task queue or, if that fails, onto the overflow stack | |
297 // is_empty() - return true if both the TaskQueue and overflow stack are empty | |
298 // | |
299 // Note that size() is not overridden--it returns the number of elements in the | |
300 // TaskQueue, and does not include the size of the overflow stack. This | |
301 // simplifies replacement of GenericTaskQueues with OverflowTaskQueues. | |
302 template<class E, unsigned int N = TASKQUEUE_SIZE> | |
303 class OverflowTaskQueue: public GenericTaskQueue<E, N> | |
304 { | |
305 public: | |
306 typedef GrowableArray<E> overflow_t; | |
307 typedef GenericTaskQueue<E, N> taskqueue_t; | |
308 | |
309 OverflowTaskQueue(); | |
310 ~OverflowTaskQueue(); | |
311 void initialize(); | |
312 | |
313 inline overflow_t* overflow_stack() const { return _overflow_stack; } | |
314 | |
315 // Push task t onto the queue or onto the overflow stack. Return true. | |
316 inline bool push(E t); | |
317 | |
318 // Attempt to pop from the overflow stack; return true if anything was popped. | |
319 inline bool pop_overflow(E& t); | |
320 | |
321 inline bool taskqueue_empty() const { return taskqueue_t::is_empty(); } | |
322 inline bool overflow_empty() const { return overflow_stack()->is_empty(); } | |
323 inline bool is_empty() const { | |
324 return taskqueue_empty() && overflow_empty(); | |
325 } | |
326 | |
327 private: | |
328 overflow_t* _overflow_stack; | |
329 }; | |
330 | |
331 template <class E, unsigned int N> | |
332 OverflowTaskQueue<E, N>::OverflowTaskQueue() | |
333 { | |
334 _overflow_stack = NULL; | |
335 } | |
336 | |
337 template <class E, unsigned int N> | |
338 OverflowTaskQueue<E, N>::~OverflowTaskQueue() | |
339 { | |
340 if (_overflow_stack != NULL) { | |
341 delete _overflow_stack; | |
342 _overflow_stack = NULL; | |
343 } | |
344 } | |
345 | |
346 template <class E, unsigned int N> | |
347 void OverflowTaskQueue<E, N>::initialize() | |
348 { | |
349 taskqueue_t::initialize(); | |
350 assert(_overflow_stack == NULL, "memory leak"); | |
351 _overflow_stack = new (ResourceObj::C_HEAP) GrowableArray<E>(10, true); | |
352 } | |
353 | |
354 template <class E, unsigned int N> | |
355 bool OverflowTaskQueue<E, N>::push(E t) | |
356 { | |
357 if (!taskqueue_t::push(t)) { | |
358 overflow_stack()->push(t); | |
359 } | |
360 return true; | |
361 } | |
362 | |
363 template <class E, unsigned int N> | |
364 bool OverflowTaskQueue<E, N>::pop_overflow(E& t) | |
365 { | |
366 if (overflow_empty()) return false; | |
367 t = overflow_stack()->pop(); | |
368 return true; | |
369 } | |
370 | |
0 | 371 class TaskQueueSetSuper: public CHeapObj { |
372 protected: | |
373 static int randomParkAndMiller(int* seed0); | |
374 public: | |
375 // Returns "true" if some TaskQueue in the set contains a task. | |
376 virtual bool peek() = 0; | |
377 }; | |
378 | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
379 template<class T> |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
380 class GenericTaskQueueSet: public TaskQueueSetSuper { |
0 | 381 private: |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
382 uint _n; |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
383 T** _queues; |
0 | 384 |
385 public: | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
386 typedef typename T::element_type E; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
387 |
0 | 388 GenericTaskQueueSet(int n) : _n(n) { |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
389 typedef T* GenericTaskQueuePtr; |
0 | 390 _queues = NEW_C_HEAP_ARRAY(GenericTaskQueuePtr, n); |
391 for (int i = 0; i < n; i++) { | |
392 _queues[i] = NULL; | |
393 } | |
394 } | |
395 | |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
396 bool steal_1_random(uint queue_num, int* seed, E& t); |
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
397 bool steal_best_of_2(uint queue_num, int* seed, E& t); |
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
398 bool steal_best_of_all(uint queue_num, int* seed, E& t); |
0 | 399 |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
400 void register_queue(uint i, T* q); |
0 | 401 |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
402 T* queue(uint n); |
0 | 403 |
1638 | 404 // The thread with queue number "queue_num" (and whose random number seed is |
405 // at "seed") is trying to steal a task from some other queue. (It may try | |
406 // several queues, according to some configuration parameter.) If some steal | |
407 // succeeds, returns "true" and sets "t" to the stolen task, otherwise returns | |
408 // false. | |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
409 bool steal(uint queue_num, int* seed, E& t); |
0 | 410 |
411 bool peek(); | |
412 }; | |
413 | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
414 template<class T> void |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
415 GenericTaskQueueSet<T>::register_queue(uint i, T* q) { |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
416 assert(i < _n, "index out of range."); |
0 | 417 _queues[i] = q; |
418 } | |
419 | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
420 template<class T> T* |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
421 GenericTaskQueueSet<T>::queue(uint i) { |
0 | 422 return _queues[i]; |
423 } | |
424 | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
425 template<class T> bool |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
426 GenericTaskQueueSet<T>::steal(uint queue_num, int* seed, E& t) { |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
427 for (uint i = 0; i < 2 * _n; i++) |
0 | 428 if (steal_best_of_2(queue_num, seed, t)) |
429 return true; | |
430 return false; | |
431 } | |
432 | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
433 template<class T> bool |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
434 GenericTaskQueueSet<T>::steal_best_of_all(uint queue_num, int* seed, E& t) { |
0 | 435 if (_n > 2) { |
436 int best_k; | |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
437 uint best_sz = 0; |
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
438 for (uint k = 0; k < _n; k++) { |
0 | 439 if (k == queue_num) continue; |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
440 uint sz = _queues[k]->size(); |
0 | 441 if (sz > best_sz) { |
442 best_sz = sz; | |
443 best_k = k; | |
444 } | |
445 } | |
446 return best_sz > 0 && _queues[best_k]->pop_global(t); | |
447 } else if (_n == 2) { | |
448 // Just try the other one. | |
449 int k = (queue_num + 1) % 2; | |
450 return _queues[k]->pop_global(t); | |
451 } else { | |
452 assert(_n == 1, "can't be zero."); | |
453 return false; | |
454 } | |
455 } | |
456 | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
457 template<class T> bool |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
458 GenericTaskQueueSet<T>::steal_1_random(uint queue_num, int* seed, E& t) { |
0 | 459 if (_n > 2) { |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
460 uint k = queue_num; |
0 | 461 while (k == queue_num) k = randomParkAndMiller(seed) % _n; |
462 return _queues[2]->pop_global(t); | |
463 } else if (_n == 2) { | |
464 // Just try the other one. | |
465 int k = (queue_num + 1) % 2; | |
466 return _queues[k]->pop_global(t); | |
467 } else { | |
468 assert(_n == 1, "can't be zero."); | |
469 return false; | |
470 } | |
471 } | |
472 | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
473 template<class T> bool |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
474 GenericTaskQueueSet<T>::steal_best_of_2(uint queue_num, int* seed, E& t) { |
0 | 475 if (_n > 2) { |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
476 uint k1 = queue_num; |
0 | 477 while (k1 == queue_num) k1 = randomParkAndMiller(seed) % _n; |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
478 uint k2 = queue_num; |
0 | 479 while (k2 == queue_num || k2 == k1) k2 = randomParkAndMiller(seed) % _n; |
480 // Sample both and try the larger. | |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
481 uint sz1 = _queues[k1]->size(); |
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
482 uint sz2 = _queues[k2]->size(); |
0 | 483 if (sz2 > sz1) return _queues[k2]->pop_global(t); |
484 else return _queues[k1]->pop_global(t); | |
485 } else if (_n == 2) { | |
486 // Just try the other one. | |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
487 uint k = (queue_num + 1) % 2; |
0 | 488 return _queues[k]->pop_global(t); |
489 } else { | |
490 assert(_n == 1, "can't be zero."); | |
491 return false; | |
492 } | |
493 } | |
494 | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
495 template<class T> |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
496 bool GenericTaskQueueSet<T>::peek() { |
0 | 497 // Try all the queues. |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
498 for (uint j = 0; j < _n; j++) { |
0 | 499 if (_queues[j]->peek()) |
500 return true; | |
501 } | |
502 return false; | |
503 } | |
504 | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
505 // When to terminate from the termination protocol. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
506 class TerminatorTerminator: public CHeapObj { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
507 public: |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
508 virtual bool should_exit_termination() = 0; |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
509 }; |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
510 |
0 | 511 // A class to aid in the termination of a set of parallel tasks using |
512 // TaskQueueSet's for work stealing. | |
513 | |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
541
diff
changeset
|
514 #undef TRACESPINNING |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
541
diff
changeset
|
515 |
0 | 516 class ParallelTaskTerminator: public StackObj { |
517 private: | |
518 int _n_threads; | |
519 TaskQueueSetSuper* _queue_set; | |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
520 int _offered_termination; |
0 | 521 |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
541
diff
changeset
|
522 #ifdef TRACESPINNING |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
541
diff
changeset
|
523 static uint _total_yields; |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
541
diff
changeset
|
524 static uint _total_spins; |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
541
diff
changeset
|
525 static uint _total_peeks; |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
541
diff
changeset
|
526 #endif |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
541
diff
changeset
|
527 |
0 | 528 bool peek_in_queue_set(); |
529 protected: | |
530 virtual void yield(); | |
531 void sleep(uint millis); | |
532 | |
533 public: | |
534 | |
535 // "n_threads" is the number of threads to be terminated. "queue_set" is a | |
536 // queue sets of work queues of other threads. | |
537 ParallelTaskTerminator(int n_threads, TaskQueueSetSuper* queue_set); | |
538 | |
539 // The current thread has no work, and is ready to terminate if everyone | |
540 // else is. If returns "true", all threads are terminated. If returns | |
541 // "false", available work has been observed in one of the task queues, | |
542 // so the global task is not complete. | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
543 bool offer_termination() { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
544 return offer_termination(NULL); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
545 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
546 |
907 | 547 // As above, but it also terminates if the should_exit_termination() |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
548 // method of the terminator parameter returns true. If terminator is |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
549 // NULL, then it is ignored. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
550 bool offer_termination(TerminatorTerminator* terminator); |
0 | 551 |
552 // Reset the terminator, so that it may be reused again. | |
553 // The caller is responsible for ensuring that this is done | |
554 // in an MT-safe manner, once the previous round of use of | |
555 // the terminator is finished. | |
556 void reset_for_reuse(); | |
557 | |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
541
diff
changeset
|
558 #ifdef TRACESPINNING |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
541
diff
changeset
|
559 static uint total_yields() { return _total_yields; } |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
541
diff
changeset
|
560 static uint total_spins() { return _total_spins; } |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
541
diff
changeset
|
561 static uint total_peeks() { return _total_peeks; } |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
541
diff
changeset
|
562 static void print_termination_counts(); |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
541
diff
changeset
|
563 #endif |
0 | 564 }; |
565 | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
566 template<class E, unsigned int N> inline bool |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
567 GenericTaskQueue<E, N>::push(E t) { |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
568 uint localBot = _bottom; |
907 | 569 assert((localBot >= 0) && (localBot < N), "_bottom out of range."); |
570 idx_t top = _age.top(); | |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
571 uint dirty_n_elems = dirty_size(localBot, top); |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
572 assert(dirty_n_elems < N, "n_elems out of range."); |
0 | 573 if (dirty_n_elems < max_elems()) { |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
574 // g++ complains if the volatile result of the assignment is unused. |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
575 const_cast<E&>(_elems[localBot] = t); |
1024
2c03ce058f55
6888847: TaskQueue needs release_store() for correctness on RMO machines
bobv
parents:
907
diff
changeset
|
576 OrderAccess::release_store(&_bottom, increment_index(localBot)); |
0 | 577 return true; |
578 } else { | |
579 return push_slow(t, dirty_n_elems); | |
580 } | |
581 } | |
582 | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
583 template<class E, unsigned int N> inline bool |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
584 GenericTaskQueue<E, N>::pop_local(E& t) { |
541
23673011938d
6787254: Work queue capacity can be increased substantially on some platforms
ysr
parents:
375
diff
changeset
|
585 uint localBot = _bottom; |
907 | 586 // This value cannot be N-1. That can only occur as a result of |
0 | 587 // the assignment to bottom in this method. If it does, this method |
1638 | 588 // resets the size to 0 before the next call (which is sequential, |
0 | 589 // since this is pop_local.) |
907 | 590 uint dirty_n_elems = dirty_size(localBot, _age.top()); |
591 assert(dirty_n_elems != N - 1, "Shouldn't be possible..."); | |
0 | 592 if (dirty_n_elems == 0) return false; |
593 localBot = decrement_index(localBot); | |
594 _bottom = localBot; | |
595 // This is necessary to prevent any read below from being reordered | |
596 // before the store just above. | |
597 OrderAccess::fence(); | |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
598 const_cast<E&>(t = _elems[localBot]); |
0 | 599 // This is a second read of "age"; the "size()" above is the first. |
600 // If there's still at least one element in the queue, based on the | |
601 // "_bottom" and "age" we've read, then there can be no interference with | |
602 // a "pop_global" operation, and we're done. | |
907 | 603 idx_t tp = _age.top(); // XXX |
0 | 604 if (size(localBot, tp) > 0) { |
907 | 605 assert(dirty_size(localBot, tp) != N - 1, "sanity"); |
0 | 606 return true; |
607 } else { | |
608 // Otherwise, the queue contained exactly one element; we take the slow | |
609 // path. | |
907 | 610 return pop_local_slow(localBot, _age.get()); |
0 | 611 } |
612 } | |
613 | |
1638 | 614 typedef GenericTaskQueue<oop> OopTaskQueue; |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
615 typedef GenericTaskQueueSet<OopTaskQueue> OopTaskQueueSet; |
0 | 616 |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
617 #ifdef _MSC_VER |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
618 #pragma warning(push) |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
619 // warning C4522: multiple assignment operators specified |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
620 #pragma warning(disable:4522) |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
621 #endif |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
622 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
623 // This is a container class for either an oop* or a narrowOop*. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
624 // Both are pushed onto a task queue and the consumer will test is_narrow() |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
625 // to determine which should be processed. |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
626 class StarTask { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
627 void* _holder; // either union oop* or narrowOop* |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
628 |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
629 enum { COMPRESSED_OOP_MASK = 1 }; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
630 |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
631 public: |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
632 StarTask(narrowOop* p) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
633 assert(((uintptr_t)p & COMPRESSED_OOP_MASK) == 0, "Information loss!"); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
634 _holder = (void *)((uintptr_t)p | COMPRESSED_OOP_MASK); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
635 } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
636 StarTask(oop* p) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
637 assert(((uintptr_t)p & COMPRESSED_OOP_MASK) == 0, "Information loss!"); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
638 _holder = (void*)p; |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
579
diff
changeset
|
639 } |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
640 StarTask() { _holder = NULL; } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
641 operator oop*() { return (oop*)_holder; } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
642 operator narrowOop*() { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
643 return (narrowOop*)((uintptr_t)_holder & ~COMPRESSED_OOP_MASK); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
644 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
645 |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
646 StarTask& operator=(const StarTask& t) { |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
647 _holder = t._holder; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
648 return *this; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
649 } |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
650 volatile StarTask& operator=(const volatile StarTask& t) volatile { |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
651 _holder = t._holder; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
652 return *this; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
653 } |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
654 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
655 bool is_narrow() const { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
656 return (((uintptr_t)_holder & COMPRESSED_OOP_MASK) != 0); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
657 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
658 }; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
659 |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
660 class ObjArrayTask |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
661 { |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
662 public: |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
663 ObjArrayTask(oop o = NULL, int idx = 0): _obj(o), _index(idx) { } |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
664 ObjArrayTask(oop o, size_t idx): _obj(o), _index(int(idx)) { |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
665 assert(idx <= size_t(max_jint), "too big"); |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
666 } |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
667 ObjArrayTask(const ObjArrayTask& t): _obj(t._obj), _index(t._index) { } |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
668 |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
669 ObjArrayTask& operator =(const ObjArrayTask& t) { |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
670 _obj = t._obj; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
671 _index = t._index; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
672 return *this; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
673 } |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
674 volatile ObjArrayTask& |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
675 operator =(const volatile ObjArrayTask& t) volatile { |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
676 _obj = t._obj; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
677 _index = t._index; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
678 return *this; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
679 } |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
680 |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
681 inline oop obj() const { return _obj; } |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
682 inline int index() const { return _index; } |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
683 |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
684 DEBUG_ONLY(bool is_valid() const); // Tasks to be pushed/popped must be valid. |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
685 |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
686 private: |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
687 oop _obj; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
688 int _index; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
689 }; |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
690 |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
691 #ifdef _MSC_VER |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
692 #pragma warning(pop) |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
693 #endif |
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
694 |
1638 | 695 typedef OverflowTaskQueue<StarTask> OopStarTaskQueue; |
1311
2a1472c30599
4396719: Mark Sweep stack overflow on deeply nested Object arrays
jcoomes
parents:
1284
diff
changeset
|
696 typedef GenericTaskQueueSet<OopStarTaskQueue> OopStarTaskQueueSet; |
0 | 697 |
1638 | 698 typedef OverflowTaskQueue<size_t> RegionTaskQueue; |
699 typedef GenericTaskQueueSet<RegionTaskQueue> RegionTaskQueueSet; |