< prev index next >
src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp
Print this page
rev 11970 : imported patch overflow_list
*** 7827,7856 ****
// Single-threaded
bool CMSCollector::take_from_overflow_list(size_t num, CMSMarkStack* stack) {
assert(stack->isEmpty(), "Expected precondition");
assert(stack->capacity() > num, "Shouldn't bite more than can chew");
size_t i = num;
! oop cur = _overflow_list;
const markOop proto = markOopDesc::prototype();
NOT_PRODUCT(ssize_t n = 0;)
for (oop next; i > 0 && cur != NULL; cur = next, i--) {
next = oop(cur->mark());
cur->set_mark(proto); // until proven otherwise
assert(cur->is_oop(), "Should be an oop");
bool res = stack->push(cur);
assert(res, "Bit off more than can chew?");
NOT_PRODUCT(n++;)
}
! _overflow_list = cur;
#ifndef PRODUCT
assert(_num_par_pushes >= n, "Too many pops?");
_num_par_pushes -=n;
#endif
return !stack->isEmpty();
}
! #define BUSY (cast_to_oop<intptr_t>(0x1aff1aff))
// (MT-safe) Get a prefix of at most "num" from the list.
// The overflow list is chained through the mark word of
// each object in the list. We fetch the entire list,
// break off a prefix of the right size and return the
// remainder. If other threads try to take objects from
--- 7827,7856 ----
// Single-threaded
bool CMSCollector::take_from_overflow_list(size_t num, CMSMarkStack* stack) {
assert(stack->isEmpty(), "Expected precondition");
assert(stack->capacity() > num, "Shouldn't bite more than can chew");
size_t i = num;
! oop cur = cast_to_oop<HeapWord*>(_overflow_list);
const markOop proto = markOopDesc::prototype();
NOT_PRODUCT(ssize_t n = 0;)
for (oop next; i > 0 && cur != NULL; cur = next, i--) {
next = oop(cur->mark());
cur->set_mark(proto); // until proven otherwise
assert(cur->is_oop(), "Should be an oop");
bool res = stack->push(cur);
assert(res, "Bit off more than can chew?");
NOT_PRODUCT(n++;)
}
! _overflow_list = cast_from_oop<HeapWord*>(cur);
#ifndef PRODUCT
assert(_num_par_pushes >= n, "Too many pops?");
_num_par_pushes -=n;
#endif
return !stack->isEmpty();
}
! #define BUSY ((HeapWord*)(0x1aff1aff))
// (MT-safe) Get a prefix of at most "num" from the list.
// The overflow list is chained through the mark word of
// each object in the list. We fetch the entire list,
// break off a prefix of the right size and return the
// remainder. If other threads try to take objects from
*** 7879,7889 ****
assert(num < work_q->max_elems(), "Can't bite more than we can chew");
if (_overflow_list == NULL) {
return false;
}
// Grab the entire list; we'll put back a suffix
! oop prefix = cast_to_oop(Atomic::xchg_ptr(BUSY, &_overflow_list));
Thread* tid = Thread::current();
// Before "no_of_gc_threads" was introduced CMSOverflowSpinCount was
// set to ParallelGCThreads.
size_t CMSOverflowSpinCount = (size_t) no_of_gc_threads; // was ParallelGCThreads;
size_t sleep_time_millis = MAX2((size_t)1, num/100);
--- 7879,7889 ----
assert(num < work_q->max_elems(), "Can't bite more than we can chew");
if (_overflow_list == NULL) {
return false;
}
// Grab the entire list; we'll put back a suffix
! HeapWord* prefix = (HeapWord*)Atomic::xchg_ptr(BUSY, &_overflow_list);
Thread* tid = Thread::current();
// Before "no_of_gc_threads" was introduced CMSOverflowSpinCount was
// set to ParallelGCThreads.
size_t CMSOverflowSpinCount = (size_t) no_of_gc_threads; // was ParallelGCThreads;
size_t sleep_time_millis = MAX2((size_t)1, num/100);
*** 7894,7904 ****
if (_overflow_list == NULL) {
// Nothing left to take
return false;
} else if (_overflow_list != BUSY) {
// Try and grab the prefix
! prefix = cast_to_oop(Atomic::xchg_ptr(BUSY, &_overflow_list));
}
}
// If the list was found to be empty, or we spun long
// enough, we give up and return empty-handed. If we leave
// the list in the BUSY state below, it must be the case that
--- 7894,7904 ----
if (_overflow_list == NULL) {
// Nothing left to take
return false;
} else if (_overflow_list != BUSY) {
// Try and grab the prefix
! prefix = (HeapWord*)Atomic::xchg_ptr(BUSY, &_overflow_list);
}
}
// If the list was found to be empty, or we spun long
// enough, we give up and return empty-handed. If we leave
// the list in the BUSY state below, it must be the case that
*** 7913,7923 ****
}
return false;
}
assert(prefix != NULL && prefix != BUSY, "Error");
size_t i = num;
! oop cur = prefix;
// Walk down the first "num" objects, unless we reach the end.
for (; i > 1 && cur->mark() != NULL; cur = oop(cur->mark()), i--);
if (cur->mark() == NULL) {
// We have "num" or fewer elements in the list, so there
// is nothing to return to the global list.
--- 7913,7923 ----
}
return false;
}
assert(prefix != NULL && prefix != BUSY, "Error");
size_t i = num;
! oop cur = cast_to_oop<HeapWord*>(prefix);
// Walk down the first "num" objects, unless we reach the end.
for (; i > 1 && cur->mark() != NULL; cur = oop(cur->mark()), i--);
if (cur->mark() == NULL) {
// We have "num" or fewer elements in the list, so there
// is nothing to return to the global list.
*** 7926,7958 ****
if (_overflow_list == BUSY) {
(void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
}
} else {
// Chop off the suffix and return it to the global list.
! assert(cur->mark() != BUSY, "Error");
! oop suffix_head = cur->mark(); // suffix will be put back on global list
cur->set_mark(NULL); // break off suffix
// It's possible that the list is still in the empty(busy) state
// we left it in a short while ago; in that case we may be
// able to place back the suffix without incurring the cost
// of a walk down the list.
! oop observed_overflow_list = _overflow_list;
! oop cur_overflow_list = observed_overflow_list;
bool attached = false;
while (observed_overflow_list == BUSY || observed_overflow_list == NULL) {
observed_overflow_list =
! (oop) Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur_overflow_list);
if (cur_overflow_list == observed_overflow_list) {
attached = true;
break;
} else cur_overflow_list = observed_overflow_list;
}
if (!attached) {
// Too bad, someone else sneaked in (at least) an element; we'll need
// to do a splice. Find tail of suffix so we can prepend suffix to global
// list.
! for (cur = suffix_head; cur->mark() != NULL; cur = (oop)(cur->mark()));
oop suffix_tail = cur;
assert(suffix_tail != NULL && suffix_tail->mark() == NULL,
"Tautology");
observed_overflow_list = _overflow_list;
do {
--- 7926,7958 ----
if (_overflow_list == BUSY) {
(void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
}
} else {
// Chop off the suffix and return it to the global list.
! assert(cast_from_oop<HeapWord*>(cur->mark()) != BUSY, "Error");
! HeapWord *suffix_head = cast_from_oop<HeapWord*>(cur->mark()); // suffix will be put back on global list
cur->set_mark(NULL); // break off suffix
// It's possible that the list is still in the empty(busy) state
// we left it in a short while ago; in that case we may be
// able to place back the suffix without incurring the cost
// of a walk down the list.
! HeapWord* observed_overflow_list = _overflow_list;
! HeapWord* cur_overflow_list = observed_overflow_list;
bool attached = false;
while (observed_overflow_list == BUSY || observed_overflow_list == NULL) {
observed_overflow_list =
! (HeapWord*)Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur_overflow_list);
if (cur_overflow_list == observed_overflow_list) {
attached = true;
break;
} else cur_overflow_list = observed_overflow_list;
}
if (!attached) {
// Too bad, someone else sneaked in (at least) an element; we'll need
// to do a splice. Find tail of suffix so we can prepend suffix to global
// list.
! for (cur = cast_to_oop<HeapWord*>(suffix_head); cur->mark() != NULL; cur = (oop)(cur->mark()));
oop suffix_tail = cur;
assert(suffix_tail != NULL && suffix_tail->mark() == NULL,
"Tautology");
observed_overflow_list = _overflow_list;
do {
*** 7963,7984 ****
} else { // cur_overflow_list == BUSY
suffix_tail->set_mark(NULL);
}
// ... and try to place spliced list back on overflow_list ...
observed_overflow_list =
! (oop) Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur_overflow_list);
} while (cur_overflow_list != observed_overflow_list);
// ... until we have succeeded in doing so.
}
}
// Push the prefix elements on work_q
assert(prefix != NULL, "control point invariant");
const markOop proto = markOopDesc::prototype();
oop next;
NOT_PRODUCT(ssize_t n = 0;)
! for (cur = prefix; cur != NULL; cur = next) {
next = oop(cur->mark());
cur->set_mark(proto); // until proven otherwise
assert(cur->is_oop(), "Should be an oop");
bool res = work_q->push(cur);
assert(res, "Bit off more than we can chew?");
--- 7963,7984 ----
} else { // cur_overflow_list == BUSY
suffix_tail->set_mark(NULL);
}
// ... and try to place spliced list back on overflow_list ...
observed_overflow_list =
! (HeapWord*)Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur_overflow_list);
} while (cur_overflow_list != observed_overflow_list);
// ... until we have succeeded in doing so.
}
}
// Push the prefix elements on work_q
assert(prefix != NULL, "control point invariant");
const markOop proto = markOopDesc::prototype();
oop next;
NOT_PRODUCT(ssize_t n = 0;)
! for (cur = cast_to_oop<HeapWord*>(prefix); cur != NULL; cur = next) {
next = oop(cur->mark());
cur->set_mark(proto); // until proven otherwise
assert(cur->is_oop(), "Should be an oop");
bool res = work_q->push(cur);
assert(res, "Bit off more than we can chew?");
*** 7995,8023 ****
void CMSCollector::push_on_overflow_list(oop p) {
NOT_PRODUCT(_num_par_pushes++;)
assert(p->is_oop(), "Not an oop");
preserve_mark_if_necessary(p);
p->set_mark((markOop)_overflow_list);
! _overflow_list = p;
}
// Multi-threaded; use CAS to prepend to overflow list
void CMSCollector::par_push_on_overflow_list(oop p) {
NOT_PRODUCT(Atomic::inc_ptr(&_num_par_pushes);)
assert(p->is_oop(), "Not an oop");
par_preserve_mark_if_necessary(p);
! oop observed_overflow_list = _overflow_list;
! oop cur_overflow_list;
do {
cur_overflow_list = observed_overflow_list;
if (cur_overflow_list != BUSY) {
p->set_mark(markOop(cur_overflow_list));
} else {
p->set_mark(NULL);
}
observed_overflow_list =
! (oop) Atomic::cmpxchg_ptr(p, &_overflow_list, cur_overflow_list);
} while (cur_overflow_list != observed_overflow_list);
}
#undef BUSY
// Single threaded
--- 7995,8023 ----
void CMSCollector::push_on_overflow_list(oop p) {
NOT_PRODUCT(_num_par_pushes++;)
assert(p->is_oop(), "Not an oop");
preserve_mark_if_necessary(p);
p->set_mark((markOop)_overflow_list);
! _overflow_list = cast_from_oop<HeapWord*>(p);
}
// Multi-threaded; use CAS to prepend to overflow list
void CMSCollector::par_push_on_overflow_list(oop p) {
NOT_PRODUCT(Atomic::inc_ptr(&_num_par_pushes);)
assert(p->is_oop(), "Not an oop");
par_preserve_mark_if_necessary(p);
! HeapWord* observed_overflow_list = _overflow_list;
! HeapWord* cur_overflow_list;
do {
cur_overflow_list = observed_overflow_list;
if (cur_overflow_list != BUSY) {
p->set_mark(markOop(cur_overflow_list));
} else {
p->set_mark(NULL);
}
observed_overflow_list =
! (HeapWord*)Atomic::cmpxchg_ptr(cast_from_oop<HeapWord*>(p), &_overflow_list, cur_overflow_list);
} while (cur_overflow_list != observed_overflow_list);
}
#undef BUSY
// Single threaded
< prev index next >