< prev index next >

src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp

Print this page
rev 11972 : imported patch overflow_list_3
rev 11973 : [mq]: overflow_list_3_1

*** 7827,7841 **** // 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++;) --- 7827,7841 ---- // 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; ! oopDesc* cur = _overflow_list; const markOop proto = markOopDesc::prototype(); NOT_PRODUCT(ssize_t n = 0;) ! for (oopDesc* next; i > 0 && cur != NULL; cur = next, i--) { ! next = 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++;)
*** 7846,7856 **** _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 --- 7846,7856 ---- _num_par_pushes -=n; #endif return !stack->isEmpty(); } ! #define BUSY ((oopDesc*)(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 ! oopDesc* prefix = (oopDesc*)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 = (oopDesc*)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,7925 **** } 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. // Write back the NULL in lieu of the BUSY we wrote // above, if it is still the same value. --- 7913,7925 ---- } return false; } assert(prefix != NULL && prefix != BUSY, "Error"); size_t i = num; ! oopDesc* cur = prefix; // Walk down the first "num" objects, unless we reach the end. ! for (; i > 1 && cur->mark() != NULL; cur = cast_from_oop<oopDesc*>(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. // Write back the NULL in lieu of the BUSY we wrote // above, if it is still the same value.
*** 7927,7944 **** (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) { --- 7927,7944 ---- (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"); ! oopDesc* 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. ! oopDesc* observed_overflow_list = _overflow_list; ! oopDesc* 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) {
*** 7948,7959 **** } 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 { cur_overflow_list = observed_overflow_list; --- 7948,7959 ---- } 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 = cast_from_oop<oopDesc*>(cur->mark())); ! oopDesc* suffix_tail = cur; assert(suffix_tail != NULL && suffix_tail->mark() == NULL, "Tautology"); observed_overflow_list = _overflow_list; do { cur_overflow_list = observed_overflow_list;
*** 7963,7985 **** } 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?"); NOT_PRODUCT(n++;) --- 7963,7985 ---- } else { // cur_overflow_list == BUSY suffix_tail->set_mark(NULL); } // ... and try to place spliced list back on overflow_list ... observed_overflow_list = ! (oopDesc*) 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(); ! oopDesc* next; NOT_PRODUCT(ssize_t n = 0;) for (cur = prefix; cur != NULL; cur = next) { ! next = cast_from_oop<oopDesc*>(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?"); NOT_PRODUCT(n++;)
*** 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 = (oopDesc*)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); ! oopDesc* observed_overflow_list = _overflow_list; ! oopDesc* 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 = ! (oopDesc*) Atomic::cmpxchg_ptr(p, &_overflow_list, cur_overflow_list); } while (cur_overflow_list != observed_overflow_list); } #undef BUSY // Single threaded
< prev index next >