314 GenericTaskQueue<E, F, N>::GenericTaskQueue() {
315 assert(sizeof(Age) == sizeof(size_t), "Depends on this.");
316 }
317
318 template<class E, MEMFLAGS F, unsigned int N>
319 void GenericTaskQueue<E, F, N>::initialize() {
320 _elems = _array_allocator.allocate(N);
321 }
322
323 template<class E, MEMFLAGS F, unsigned int N>
324 void GenericTaskQueue<E, F, N>::oops_do(OopClosure* f) {
325 // tty->print_cr("START OopTaskQueue::oops_do");
326 uint iters = size();
327 uint index = _bottom;
328 for (uint i = 0; i < iters; ++i) {
329 index = decrement_index(index);
330 // tty->print_cr(" doing entry %d," INTPTR_T " -> " INTPTR_T,
331 // index, &_elems[index], _elems[index]);
332 E* t = (E*)&_elems[index]; // cast away volatility
333 oop* p = (oop*)t;
334 assert((*t)->is_oop_or_null(), "Not an oop or null");
335 f->do_oop(p);
336 }
337 // tty->print_cr("END OopTaskQueue::oops_do");
338 }
339
340 template<class E, MEMFLAGS F, unsigned int N>
341 bool GenericTaskQueue<E, F, N>::push_slow(E t, uint dirty_n_elems) {
342 if (dirty_n_elems == N - 1) {
343 // Actually means 0, so do the push.
344 uint localBot = _bottom;
345 // g++ complains if the volatile result of the assignment is
346 // unused, so we cast the volatile away. We cannot cast directly
347 // to void, because gcc treats that as not using the result of the
348 // assignment. However, casting to E& means that we trigger an
349 // unused-value warning. So, we cast the E& to void.
350 (void)const_cast<E&>(_elems[localBot] = t);
351 OrderAccess::release_store(&_bottom, increment_index(localBot));
352 TASKQUEUE_STATS_ONLY(stats.record_push());
353 return true;
354 }
|
314 GenericTaskQueue<E, F, N>::GenericTaskQueue() {
315 assert(sizeof(Age) == sizeof(size_t), "Depends on this.");
316 }
317
318 template<class E, MEMFLAGS F, unsigned int N>
319 void GenericTaskQueue<E, F, N>::initialize() {
320 _elems = _array_allocator.allocate(N);
321 }
322
323 template<class E, MEMFLAGS F, unsigned int N>
324 void GenericTaskQueue<E, F, N>::oops_do(OopClosure* f) {
325 // tty->print_cr("START OopTaskQueue::oops_do");
326 uint iters = size();
327 uint index = _bottom;
328 for (uint i = 0; i < iters; ++i) {
329 index = decrement_index(index);
330 // tty->print_cr(" doing entry %d," INTPTR_T " -> " INTPTR_T,
331 // index, &_elems[index], _elems[index]);
332 E* t = (E*)&_elems[index]; // cast away volatility
333 oop* p = (oop*)t;
334 assert((*t)->is_oop_or_null(), err_msg("Not an oop or null: " PTR_FORMAT, p2i(*t)));
335 f->do_oop(p);
336 }
337 // tty->print_cr("END OopTaskQueue::oops_do");
338 }
339
340 template<class E, MEMFLAGS F, unsigned int N>
341 bool GenericTaskQueue<E, F, N>::push_slow(E t, uint dirty_n_elems) {
342 if (dirty_n_elems == N - 1) {
343 // Actually means 0, so do the push.
344 uint localBot = _bottom;
345 // g++ complains if the volatile result of the assignment is
346 // unused, so we cast the volatile away. We cannot cast directly
347 // to void, because gcc treats that as not using the result of the
348 // assignment. However, casting to E& means that we trigger an
349 // unused-value warning. So, we cast the E& to void.
350 (void)const_cast<E&>(_elems[localBot] = t);
351 OrderAccess::release_store(&_bottom, increment_index(localBot));
352 TASKQUEUE_STATS_ONLY(stats.record_push());
353 return true;
354 }
|