Mercurial > hg > truffle
comparison src/share/vm/utilities/taskqueue.hpp @ 1836:894b1d7c7e01
6423256: GC stacks should use a better data structure
6942771: SEGV in ParScanThreadState::take_from_overflow_stack
Reviewed-by: apetrusenko, ysr, pbk
author | jcoomes |
---|---|
date | Tue, 28 Sep 2010 15:56:15 -0700 |
parents | 8b10f48633dc |
children | f95d63e2154a |
comparison
equal
deleted
inserted
replaced
1835:4805b9f4779e | 1836:894b1d7c7e01 |
---|---|
370 } | 370 } |
371 | 371 |
372 // OverflowTaskQueue is a TaskQueue that also includes an overflow stack for | 372 // OverflowTaskQueue is a TaskQueue that also includes an overflow stack for |
373 // elements that do not fit in the TaskQueue. | 373 // elements that do not fit in the TaskQueue. |
374 // | 374 // |
375 // Three methods from super classes are overridden: | 375 // This class hides two methods from super classes: |
376 // | 376 // |
377 // initialize() - initialize the super classes and create the overflow stack | |
378 // push() - push onto the task queue or, if that fails, onto the overflow stack | 377 // push() - push onto the task queue or, if that fails, onto the overflow stack |
379 // is_empty() - return true if both the TaskQueue and overflow stack are empty | 378 // is_empty() - return true if both the TaskQueue and overflow stack are empty |
380 // | 379 // |
381 // Note that size() is not overridden--it returns the number of elements in the | 380 // Note that size() is not hidden--it returns the number of elements in the |
382 // TaskQueue, and does not include the size of the overflow stack. This | 381 // TaskQueue, and does not include the size of the overflow stack. This |
383 // simplifies replacement of GenericTaskQueues with OverflowTaskQueues. | 382 // simplifies replacement of GenericTaskQueues with OverflowTaskQueues. |
384 template<class E, unsigned int N = TASKQUEUE_SIZE> | 383 template<class E, unsigned int N = TASKQUEUE_SIZE> |
385 class OverflowTaskQueue: public GenericTaskQueue<E, N> | 384 class OverflowTaskQueue: public GenericTaskQueue<E, N> |
386 { | 385 { |
387 public: | 386 public: |
388 typedef GrowableArray<E> overflow_t; | 387 typedef Stack<E> overflow_t; |
389 typedef GenericTaskQueue<E, N> taskqueue_t; | 388 typedef GenericTaskQueue<E, N> taskqueue_t; |
390 | 389 |
391 TASKQUEUE_STATS_ONLY(using taskqueue_t::stats;) | 390 TASKQUEUE_STATS_ONLY(using taskqueue_t::stats;) |
392 | |
393 OverflowTaskQueue(); | |
394 ~OverflowTaskQueue(); | |
395 void initialize(); | |
396 | |
397 inline overflow_t* overflow_stack() const { return _overflow_stack; } | |
398 | 391 |
399 // Push task t onto the queue or onto the overflow stack. Return true. | 392 // Push task t onto the queue or onto the overflow stack. Return true. |
400 inline bool push(E t); | 393 inline bool push(E t); |
401 | 394 |
402 // Attempt to pop from the overflow stack; return true if anything was popped. | 395 // Attempt to pop from the overflow stack; return true if anything was popped. |
403 inline bool pop_overflow(E& t); | 396 inline bool pop_overflow(E& t); |
404 | 397 |
398 inline overflow_t* overflow_stack() { return &_overflow_stack; } | |
399 | |
405 inline bool taskqueue_empty() const { return taskqueue_t::is_empty(); } | 400 inline bool taskqueue_empty() const { return taskqueue_t::is_empty(); } |
406 inline bool overflow_empty() const { return overflow_stack()->is_empty(); } | 401 inline bool overflow_empty() const { return _overflow_stack.is_empty(); } |
407 inline bool is_empty() const { | 402 inline bool is_empty() const { |
408 return taskqueue_empty() && overflow_empty(); | 403 return taskqueue_empty() && overflow_empty(); |
409 } | 404 } |
410 | 405 |
411 private: | 406 private: |
412 overflow_t* _overflow_stack; | 407 overflow_t _overflow_stack; |
413 }; | 408 }; |
414 | |
415 template <class E, unsigned int N> | |
416 OverflowTaskQueue<E, N>::OverflowTaskQueue() | |
417 { | |
418 _overflow_stack = NULL; | |
419 } | |
420 | |
421 template <class E, unsigned int N> | |
422 OverflowTaskQueue<E, N>::~OverflowTaskQueue() | |
423 { | |
424 if (_overflow_stack != NULL) { | |
425 delete _overflow_stack; | |
426 _overflow_stack = NULL; | |
427 } | |
428 } | |
429 | |
430 template <class E, unsigned int N> | |
431 void OverflowTaskQueue<E, N>::initialize() | |
432 { | |
433 taskqueue_t::initialize(); | |
434 assert(_overflow_stack == NULL, "memory leak"); | |
435 _overflow_stack = new (ResourceObj::C_HEAP) GrowableArray<E>(10, true); | |
436 } | |
437 | 409 |
438 template <class E, unsigned int N> | 410 template <class E, unsigned int N> |
439 bool OverflowTaskQueue<E, N>::push(E t) | 411 bool OverflowTaskQueue<E, N>::push(E t) |
440 { | 412 { |
441 if (!taskqueue_t::push(t)) { | 413 if (!taskqueue_t::push(t)) { |
442 overflow_stack()->push(t); | 414 overflow_stack()->push(t); |
443 TASKQUEUE_STATS_ONLY(stats.record_overflow(overflow_stack()->length())); | 415 TASKQUEUE_STATS_ONLY(stats.record_overflow(overflow_stack()->size())); |
444 } | 416 } |
445 return true; | 417 return true; |
446 } | 418 } |
447 | 419 |
448 template <class E, unsigned int N> | 420 template <class E, unsigned int N> |