mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-16 09:04:41 +02:00
6423256: GC stacks should use a better data structure
6942771: SEGV in ParScanThreadState::take_from_overflow_stack Reviewed-by: apetrusenko, ysr, pbk
This commit is contained in:
parent
aff36499e7
commit
1cdd538ea5
30 changed files with 718 additions and 402 deletions
|
@ -372,75 +372,47 @@ GenericTaskQueue<E, N>::~GenericTaskQueue() {
|
|||
// OverflowTaskQueue is a TaskQueue that also includes an overflow stack for
|
||||
// elements that do not fit in the TaskQueue.
|
||||
//
|
||||
// Three methods from super classes are overridden:
|
||||
// This class hides two methods from super classes:
|
||||
//
|
||||
// initialize() - initialize the super classes and create the overflow stack
|
||||
// push() - push onto the task queue or, if that fails, onto the overflow stack
|
||||
// is_empty() - return true if both the TaskQueue and overflow stack are empty
|
||||
//
|
||||
// Note that size() is not overridden--it returns the number of elements in the
|
||||
// Note that size() is not hidden--it returns the number of elements in the
|
||||
// TaskQueue, and does not include the size of the overflow stack. This
|
||||
// simplifies replacement of GenericTaskQueues with OverflowTaskQueues.
|
||||
template<class E, unsigned int N = TASKQUEUE_SIZE>
|
||||
class OverflowTaskQueue: public GenericTaskQueue<E, N>
|
||||
{
|
||||
public:
|
||||
typedef GrowableArray<E> overflow_t;
|
||||
typedef Stack<E> overflow_t;
|
||||
typedef GenericTaskQueue<E, N> taskqueue_t;
|
||||
|
||||
TASKQUEUE_STATS_ONLY(using taskqueue_t::stats;)
|
||||
|
||||
OverflowTaskQueue();
|
||||
~OverflowTaskQueue();
|
||||
void initialize();
|
||||
|
||||
inline overflow_t* overflow_stack() const { return _overflow_stack; }
|
||||
|
||||
// Push task t onto the queue or onto the overflow stack. Return true.
|
||||
inline bool push(E t);
|
||||
|
||||
// Attempt to pop from the overflow stack; return true if anything was popped.
|
||||
inline bool pop_overflow(E& t);
|
||||
|
||||
inline overflow_t* overflow_stack() { return &_overflow_stack; }
|
||||
|
||||
inline bool taskqueue_empty() const { return taskqueue_t::is_empty(); }
|
||||
inline bool overflow_empty() const { return overflow_stack()->is_empty(); }
|
||||
inline bool overflow_empty() const { return _overflow_stack.is_empty(); }
|
||||
inline bool is_empty() const {
|
||||
return taskqueue_empty() && overflow_empty();
|
||||
}
|
||||
|
||||
private:
|
||||
overflow_t* _overflow_stack;
|
||||
overflow_t _overflow_stack;
|
||||
};
|
||||
|
||||
template <class E, unsigned int N>
|
||||
OverflowTaskQueue<E, N>::OverflowTaskQueue()
|
||||
{
|
||||
_overflow_stack = NULL;
|
||||
}
|
||||
|
||||
template <class E, unsigned int N>
|
||||
OverflowTaskQueue<E, N>::~OverflowTaskQueue()
|
||||
{
|
||||
if (_overflow_stack != NULL) {
|
||||
delete _overflow_stack;
|
||||
_overflow_stack = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
template <class E, unsigned int N>
|
||||
void OverflowTaskQueue<E, N>::initialize()
|
||||
{
|
||||
taskqueue_t::initialize();
|
||||
assert(_overflow_stack == NULL, "memory leak");
|
||||
_overflow_stack = new (ResourceObj::C_HEAP) GrowableArray<E>(10, true);
|
||||
}
|
||||
|
||||
template <class E, unsigned int N>
|
||||
bool OverflowTaskQueue<E, N>::push(E t)
|
||||
{
|
||||
if (!taskqueue_t::push(t)) {
|
||||
overflow_stack()->push(t);
|
||||
TASKQUEUE_STATS_ONLY(stats.record_overflow(overflow_stack()->length()));
|
||||
TASKQUEUE_STATS_ONLY(stats.record_overflow(overflow_stack()->size()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue