< prev index next >
src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
Print this page
*** 201,211 ****
CardTableRS* ct, bool use_adaptive_freelists,
FreeBlockDictionary<FreeChunk>::DictionaryChoice dictionaryChoice) :
CardGeneration(rs, initial_byte_size, level, ct),
_dilatation_factor(((double)MinChunkSize)/((double)(CollectedHeap::min_fill_size()))),
_debug_collection_type(Concurrent_collection_type),
! _did_compact(false)
{
HeapWord* bottom = (HeapWord*) _virtual_space.low();
HeapWord* end = (HeapWord*) _virtual_space.high();
_direct_allocated_words = 0;
--- 201,212 ----
CardTableRS* ct, bool use_adaptive_freelists,
FreeBlockDictionary<FreeChunk>::DictionaryChoice dictionaryChoice) :
CardGeneration(rs, initial_byte_size, level, ct),
_dilatation_factor(((double)MinChunkSize)/((double)(CollectedHeap::min_fill_size()))),
_debug_collection_type(Concurrent_collection_type),
! _did_compact(false),
! _has_promotion_failed(false)
{
HeapWord* bottom = (HeapWord*) _virtual_space.low();
HeapWord* end = (HeapWord*) _virtual_space.high();
_direct_allocated_words = 0;
*** 873,882 ****
--- 874,886 ----
// (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,1356 ****
--- 1351,1363 ----
#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).
*** 3345,3362 ****
--- 3352,3381 ----
}
}
}
HeapWord* ConcurrentMarkSweepGeneration::expand_and_par_lab_allocate(CMSParGCThreadState* ps, size_t word_sz) {
+ // Fast-path for promotion failure outside the lock.
+ if (CMSFastPromotionFailure && has_promotion_failed()) {
+ return NULL;
+ }
+
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,3390 ****
--- 3390,3416 ----
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 >