src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp
changeset 47634 6a0c42c40cd1
parent 47622 817f2a7019e4
child 47648 226b1fc611b9
equal deleted inserted replaced
47633:1c21c60f51bf 47634:6a0c42c40cd1
  1075   collector()->promoted(true,          // parallel
  1075   collector()->promoted(true,          // parallel
  1076                         obj_ptr, old->is_objArray(), word_sz);
  1076                         obj_ptr, old->is_objArray(), word_sz);
  1077 
  1077 
  1078   NOT_PRODUCT(
  1078   NOT_PRODUCT(
  1079     Atomic::inc(&_numObjectsPromoted);
  1079     Atomic::inc(&_numObjectsPromoted);
  1080     Atomic::add_ptr(alloc_sz, &_numWordsPromoted);
  1080     Atomic::add(alloc_sz, &_numWordsPromoted);
  1081   )
  1081   )
  1082 
  1082 
  1083   return obj;
  1083   return obj;
  1084 }
  1084 }
  1085 
  1085 
  3178 void CMSConcMarkingTask::bump_global_finger(HeapWord* f) {
  3178 void CMSConcMarkingTask::bump_global_finger(HeapWord* f) {
  3179   HeapWord* read = _global_finger;
  3179   HeapWord* read = _global_finger;
  3180   HeapWord* cur  = read;
  3180   HeapWord* cur  = read;
  3181   while (f > read) {
  3181   while (f > read) {
  3182     cur = read;
  3182     cur = read;
  3183     read = (HeapWord*) Atomic::cmpxchg_ptr(f, &_global_finger, cur);
  3183     read = Atomic::cmpxchg(f, &_global_finger, cur);
  3184     if (cur == read) {
  3184     if (cur == read) {
  3185       // our cas succeeded
  3185       // our cas succeeded
  3186       assert(_global_finger >= f, "protocol consistency");
  3186       assert(_global_finger >= f, "protocol consistency");
  3187       break;
  3187       break;
  3188     }
  3188     }
  7851   assert(num < work_q->max_elems(), "Can't bite more than we can chew");
  7851   assert(num < work_q->max_elems(), "Can't bite more than we can chew");
  7852   if (_overflow_list == NULL) {
  7852   if (_overflow_list == NULL) {
  7853     return false;
  7853     return false;
  7854   }
  7854   }
  7855   // Grab the entire list; we'll put back a suffix
  7855   // Grab the entire list; we'll put back a suffix
  7856   oop prefix = cast_to_oop(Atomic::xchg_ptr(BUSY, &_overflow_list));
  7856   oop prefix = cast_to_oop(Atomic::xchg((oopDesc*)BUSY, &_overflow_list));
  7857   Thread* tid = Thread::current();
  7857   Thread* tid = Thread::current();
  7858   // Before "no_of_gc_threads" was introduced CMSOverflowSpinCount was
  7858   // Before "no_of_gc_threads" was introduced CMSOverflowSpinCount was
  7859   // set to ParallelGCThreads.
  7859   // set to ParallelGCThreads.
  7860   size_t CMSOverflowSpinCount = (size_t) no_of_gc_threads; // was ParallelGCThreads;
  7860   size_t CMSOverflowSpinCount = (size_t) no_of_gc_threads; // was ParallelGCThreads;
  7861   size_t sleep_time_millis = MAX2((size_t)1, num/100);
  7861   size_t sleep_time_millis = MAX2((size_t)1, num/100);
  7866     if (_overflow_list == NULL) {
  7866     if (_overflow_list == NULL) {
  7867       // Nothing left to take
  7867       // Nothing left to take
  7868       return false;
  7868       return false;
  7869     } else if (_overflow_list != BUSY) {
  7869     } else if (_overflow_list != BUSY) {
  7870       // Try and grab the prefix
  7870       // Try and grab the prefix
  7871       prefix = cast_to_oop(Atomic::xchg_ptr(BUSY, &_overflow_list));
  7871       prefix = cast_to_oop(Atomic::xchg((oopDesc*)BUSY, &_overflow_list));
  7872     }
  7872     }
  7873   }
  7873   }
  7874   // If the list was found to be empty, or we spun long
  7874   // If the list was found to be empty, or we spun long
  7875   // enough, we give up and return empty-handed. If we leave
  7875   // enough, we give up and return empty-handed. If we leave
  7876   // the list in the BUSY state below, it must be the case that
  7876   // the list in the BUSY state below, it must be the case that
  7879   if (prefix == NULL || prefix == BUSY) {
  7879   if (prefix == NULL || prefix == BUSY) {
  7880      // Nothing to take or waited long enough
  7880      // Nothing to take or waited long enough
  7881      if (prefix == NULL) {
  7881      if (prefix == NULL) {
  7882        // Write back the NULL in case we overwrote it with BUSY above
  7882        // Write back the NULL in case we overwrote it with BUSY above
  7883        // and it is still the same value.
  7883        // and it is still the same value.
  7884        (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
  7884        Atomic::cmpxchg((oopDesc*)NULL, &_overflow_list, (oopDesc*)BUSY);
  7885      }
  7885      }
  7886      return false;
  7886      return false;
  7887   }
  7887   }
  7888   assert(prefix != NULL && prefix != BUSY, "Error");
  7888   assert(prefix != NULL && prefix != BUSY, "Error");
  7889   size_t i = num;
  7889   size_t i = num;
  7894     // We have "num" or fewer elements in the list, so there
  7894     // We have "num" or fewer elements in the list, so there
  7895     // is nothing to return to the global list.
  7895     // is nothing to return to the global list.
  7896     // Write back the NULL in lieu of the BUSY we wrote
  7896     // Write back the NULL in lieu of the BUSY we wrote
  7897     // above, if it is still the same value.
  7897     // above, if it is still the same value.
  7898     if (_overflow_list == BUSY) {
  7898     if (_overflow_list == BUSY) {
  7899       (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY);
  7899       Atomic::cmpxchg((oopDesc*)NULL, &_overflow_list, (oopDesc*)BUSY);
  7900     }
  7900     }
  7901   } else {
  7901   } else {
  7902     // Chop off the suffix and return it to the global list.
  7902     // Chop off the suffix and return it to the global list.
  7903     assert(cur->mark() != BUSY, "Error");
  7903     assert(cur->mark() != BUSY, "Error");
  7904     oop suffix_head = cur->mark(); // suffix will be put back on global list
  7904     oop suffix_head = cur->mark(); // suffix will be put back on global list
  7910     oop observed_overflow_list = _overflow_list;
  7910     oop observed_overflow_list = _overflow_list;
  7911     oop cur_overflow_list = observed_overflow_list;
  7911     oop cur_overflow_list = observed_overflow_list;
  7912     bool attached = false;
  7912     bool attached = false;
  7913     while (observed_overflow_list == BUSY || observed_overflow_list == NULL) {
  7913     while (observed_overflow_list == BUSY || observed_overflow_list == NULL) {
  7914       observed_overflow_list =
  7914       observed_overflow_list =
  7915         (oop) Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur_overflow_list);
  7915         Atomic::cmpxchg((oopDesc*)suffix_head, &_overflow_list, (oopDesc*)cur_overflow_list);
  7916       if (cur_overflow_list == observed_overflow_list) {
  7916       if (cur_overflow_list == observed_overflow_list) {
  7917         attached = true;
  7917         attached = true;
  7918         break;
  7918         break;
  7919       } else cur_overflow_list = observed_overflow_list;
  7919       } else cur_overflow_list = observed_overflow_list;
  7920     }
  7920     }
  7935         } else { // cur_overflow_list == BUSY
  7935         } else { // cur_overflow_list == BUSY
  7936           suffix_tail->set_mark(NULL);
  7936           suffix_tail->set_mark(NULL);
  7937         }
  7937         }
  7938         // ... and try to place spliced list back on overflow_list ...
  7938         // ... and try to place spliced list back on overflow_list ...
  7939         observed_overflow_list =
  7939         observed_overflow_list =
  7940           (oop) Atomic::cmpxchg_ptr(suffix_head, &_overflow_list, cur_overflow_list);
  7940           Atomic::cmpxchg((oopDesc*)suffix_head, &_overflow_list, (oopDesc*)cur_overflow_list);
  7941       } while (cur_overflow_list != observed_overflow_list);
  7941       } while (cur_overflow_list != observed_overflow_list);
  7942       // ... until we have succeeded in doing so.
  7942       // ... until we have succeeded in doing so.
  7943     }
  7943     }
  7944   }
  7944   }
  7945 
  7945 
  7956     assert(res, "Bit off more than we can chew?");
  7956     assert(res, "Bit off more than we can chew?");
  7957     NOT_PRODUCT(n++;)
  7957     NOT_PRODUCT(n++;)
  7958   }
  7958   }
  7959 #ifndef PRODUCT
  7959 #ifndef PRODUCT
  7960   assert(_num_par_pushes >= n, "Too many pops?");
  7960   assert(_num_par_pushes >= n, "Too many pops?");
  7961   Atomic::add_ptr(-(intptr_t)n, &_num_par_pushes);
  7961   Atomic::sub(n, &_num_par_pushes);
  7962 #endif
  7962 #endif
  7963   return true;
  7963   return true;
  7964 }
  7964 }
  7965 
  7965 
  7966 // Single-threaded
  7966 // Single-threaded
  7985       p->set_mark(markOop(cur_overflow_list));
  7985       p->set_mark(markOop(cur_overflow_list));
  7986     } else {
  7986     } else {
  7987       p->set_mark(NULL);
  7987       p->set_mark(NULL);
  7988     }
  7988     }
  7989     observed_overflow_list =
  7989     observed_overflow_list =
  7990       (oop) Atomic::cmpxchg_ptr(p, &_overflow_list, cur_overflow_list);
  7990       Atomic::cmpxchg((oopDesc*)p, &_overflow_list, (oopDesc*)cur_overflow_list);
  7991   } while (cur_overflow_list != observed_overflow_list);
  7991   } while (cur_overflow_list != observed_overflow_list);
  7992 }
  7992 }
  7993 #undef BUSY
  7993 #undef BUSY
  7994 
  7994 
  7995 // Single threaded
  7995 // Single threaded