< 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 >