< prev index next >
src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
Print this page
@@ -265,10 +265,13 @@
// promoting generation, we'll instead just use the minimum
// object size (which today is a header's worth of space);
// note that all arithmetic is in units of HeapWords.
assert(MinChunkSize >= CollectedHeap::min_fill_size(), "just checking");
assert(_dilatation_factor >= 1.0, "from previous assert");
+
+ // Support for CMSFastPromotionFailure
+ reset_promotion_failed();
}
// The field "_initiating_occupancy" represents the occupancy percentage
// at which we trigger a new collection cycle. Unless explicitly specified
@@ -873,10 +876,13 @@
// (cms old generation).
void ConcurrentMarkSweepGeneration::promotion_failure_occurred() {
if (CMSDumpAtPromotionFailure) {
cmsSpace()->dump_at_safepoint_with_locks(collector(), gclog_or_tty);
}
+ if (CMSFastPromotionFailure) {
+ reset_promotion_failed();
+ }
}
CompactibleSpace*
ConcurrentMarkSweepGeneration::first_compaction_space() const {
return _cmsSpace;
@@ -1347,10 +1353,13 @@
#ifndef PRODUCT
if (Universe::heap()->promotion_should_fail()) {
return NULL;
}
#endif // #ifndef PRODUCT
+ if (CMSFastPromotionFailure && has_promotion_failed()) {
+ return NULL;
+ }
CMSParGCThreadState* ps = _par_gc_thread_states[thread_num];
PromotionInfo* promoInfo = &ps->promo;
// if we are tracking promotions, then first ensure space for
// promotion (including spooling space for saving header if necessary).
@@ -1367,10 +1376,13 @@
}
assert(promoInfo->has_spooling_space(), "Control point invariant");
const size_t alloc_sz = CompactibleFreeListSpace::adjustObjectSize(word_sz);
HeapWord* obj_ptr = ps->lab.alloc(alloc_sz);
if (obj_ptr == NULL) {
+ if (CMSFastPromotionFailure && has_promotion_failed()) {
+ return NULL;
+ }
obj_ptr = expand_and_par_lab_allocate(ps, alloc_sz);
if (obj_ptr == NULL) {
return NULL;
}
}
@@ -3347,16 +3359,23 @@
}
HeapWord* ConcurrentMarkSweepGeneration::expand_and_par_lab_allocate(CMSParGCThreadState* ps, size_t word_sz) {
HeapWord* res = NULL;
MutexLocker x(ParGCRareEvent_lock);
+
+ // Check again here while holding the lock.
+ if (CMSFastPromotionFailure && has_promotion_failed()) {
+ return NULL;
+ }
+
while (true) {
// Expansion by some other thread might make alloc OK now:
res = ps->lab.alloc(word_sz);
if (res != NULL) return res;
// If there's not enough expansion space available, give up.
if (_virtual_space.uncommitted_size() < (word_sz * HeapWordSize)) {
+ set_promotion_failed();
return NULL;
}
// Otherwise, we try expansion.
expand(word_sz*HeapWordSize, MinHeapDeltaBytes,
CMSExpansionCause::_allocate_par_lab);
@@ -3371,20 +3390,27 @@
bool ConcurrentMarkSweepGeneration::expand_and_ensure_spooling_space(
PromotionInfo* promo) {
MutexLocker x(ParGCRareEvent_lock);
+
+ // Check again here while holding the lock.
+ if (CMSFastPromotionFailure && has_promotion_failed()) {
+ return false;
+ }
+
size_t refill_size_bytes = promo->refillSize() * HeapWordSize;
while (true) {
// Expansion by some other thread might make alloc OK now:
if (promo->ensure_spooling_space()) {
assert(promo->has_spooling_space(),
"Post-condition of successful ensure_spooling_space()");
return true;
}
// If there's not enough expansion space available, give up.
if (_virtual_space.uncommitted_size() < refill_size_bytes) {
+ set_promotion_failed();
return false;
}
// Otherwise, we try expansion.
expand(refill_size_bytes, MinHeapDeltaBytes,
CMSExpansionCause::_allocate_par_spooling_space);
< prev index next >