--- old/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 2014-10-30 10:05:33.214289531 -0700 +++ new/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 2014-10-30 10:05:33.158288657 -0700 @@ -267,6 +267,9 @@ // 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(); } @@ -875,6 +878,9 @@ if (CMSDumpAtPromotionFailure) { cmsSpace()->dump_at_safepoint_with_locks(collector(), gclog_or_tty); } + if (CMSFastPromotionFailure) { + reset_promotion_failed(); + } } CompactibleSpace* @@ -1349,6 +1355,9 @@ return NULL; } #endif // #ifndef PRODUCT + if (CMSFastPromotionFailure && has_promotion_failed()) { + return NULL; + } CMSParGCThreadState* ps = _par_gc_thread_states[thread_num]; PromotionInfo* promoInfo = &ps->promo; @@ -1369,6 +1378,9 @@ 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; @@ -3349,12 +3361,19 @@ 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. @@ -3373,6 +3392,12 @@ 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: @@ -3383,6 +3408,7 @@ } // 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.