Wed, 30 Jul 2008 11:54:00 -0700
6730514: assertion failure in mangling code when expanding by 0 bytes
Summary: An expansion by 0 bytes was not anticipated when the assertion was composed.
Reviewed-by: jjh, jcoomes, apetrusenko
1.1 --- a/make/windows/makefiles/defs.make Mon Jul 28 15:30:23 2008 -0700 1.2 +++ b/make/windows/makefiles/defs.make Wed Jul 30 11:54:00 2008 -0700 1.3 @@ -107,7 +107,7 @@ 1.4 ABS_OUTPUTDIR := $(subst /,\\,$(shell /bin/cygpath -m -a "$(OUTPUTDIR)")) 1.5 ABS_BOOTDIR := $(subst /,\\,$(shell /bin/cygpath -m -a "$(BOOTDIR)")) 1.6 ABS_GAMMADIR := $(subst /,\\,$(shell /bin/cygpath -m -a "$(GAMMADIR)")) 1.7 - ABS_OS_MAKEFILE := $(shell /bin/cygpath -m -a "$(HS_BUILD_DIR)/$(OSNAME)")/build.make 1.8 + ABS_OS_MAKEFILE := $(shell /bin/cygpath -m -a "$(HS_MAKE_DIR)/$(OSNAME)")/build.make 1.9 else 1.10 ABS_OUTPUTDIR := $(subst /,\\,$(shell $(CD) $(OUTPUTDIR);$(PWD))) 1.11 ABS_BOOTDIR := $(subst /,\\,$(shell $(CD) $(BOOTDIR);$(PWD)))
2.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Mon Jul 28 15:30:23 2008 -0700 2.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Jul 30 11:54:00 2008 -0700 2.3 @@ -3195,31 +3195,16 @@ 2.4 // YSR: All of this generation expansion/shrinking stuff is an exact copy of 2.5 // OneContigSpaceCardGeneration, which makes me wonder if we should move this 2.6 // to CardGeneration and share it... 2.7 +bool ConcurrentMarkSweepGeneration::expand(size_t bytes, size_t expand_bytes) { 2.8 + return CardGeneration::expand(bytes, expand_bytes); 2.9 +} 2.10 + 2.11 void ConcurrentMarkSweepGeneration::expand(size_t bytes, size_t expand_bytes, 2.12 CMSExpansionCause::Cause cause) 2.13 { 2.14 - assert_locked_or_safepoint(Heap_lock); 2.15 - 2.16 - size_t aligned_bytes = ReservedSpace::page_align_size_up(bytes); 2.17 - size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); 2.18 - bool success = false; 2.19 - if (aligned_expand_bytes > aligned_bytes) { 2.20 - success = grow_by(aligned_expand_bytes); 2.21 - } 2.22 - if (!success) { 2.23 - success = grow_by(aligned_bytes); 2.24 - } 2.25 - if (!success) { 2.26 - size_t remaining_bytes = _virtual_space.uncommitted_size(); 2.27 - if (remaining_bytes > 0) { 2.28 - success = grow_by(remaining_bytes); 2.29 - } 2.30 - } 2.31 - if (GC_locker::is_active()) { 2.32 - if (PrintGC && Verbose) { 2.33 - gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead"); 2.34 - } 2.35 - } 2.36 + 2.37 + bool success = expand(bytes, expand_bytes); 2.38 + 2.39 // remember why we expanded; this information is used 2.40 // by shouldConcurrentCollect() when making decisions on whether to start 2.41 // a new CMS cycle.
3.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Mon Jul 28 15:30:23 2008 -0700 3.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Wed Jul 30 11:54:00 2008 -0700 3.3 @@ -1048,10 +1048,6 @@ 3.4 double _initiating_occupancy; 3.5 3.6 protected: 3.7 - // Grow generation by specified size (returns false if unable to grow) 3.8 - bool grow_by(size_t bytes); 3.9 - // Grow generation to reserved size. 3.10 - bool grow_to_reserved(); 3.11 // Shrink generation by specified size (returns false if unable to shrink) 3.12 virtual void shrink_by(size_t bytes); 3.13 3.14 @@ -1103,6 +1099,11 @@ 3.15 // Override 3.16 virtual void ref_processor_init(); 3.17 3.18 + // Grow generation by specified size (returns false if unable to grow) 3.19 + bool grow_by(size_t bytes); 3.20 + // Grow generation to reserved size. 3.21 + bool grow_to_reserved(); 3.22 + 3.23 void clear_expansion_cause() { _expansion_cause = CMSExpansionCause::_no_expansion; } 3.24 3.25 // Space enquiries 3.26 @@ -1193,6 +1194,7 @@ 3.27 // Allocation failure 3.28 void expand(size_t bytes, size_t expand_bytes, 3.29 CMSExpansionCause::Cause cause); 3.30 + virtual bool expand(size_t bytes, size_t expand_bytes); 3.31 void shrink(size_t bytes); 3.32 HeapWord* expand_and_par_lab_allocate(CMSParGCThreadState* ps, size_t word_sz); 3.33 bool expand_and_ensure_spooling_space(PromotionInfo* promo);
4.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp Mon Jul 28 15:30:23 2008 -0700 4.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp Wed Jul 30 11:54:00 2008 -0700 4.3 @@ -215,10 +215,22 @@ 4.4 } 4.5 4.6 void PSOldGen::expand(size_t bytes) { 4.7 + if (bytes == 0) { 4.8 + return; 4.9 + } 4.10 MutexLocker x(ExpandHeap_lock); 4.11 const size_t alignment = virtual_space()->alignment(); 4.12 size_t aligned_bytes = align_size_up(bytes, alignment); 4.13 size_t aligned_expand_bytes = align_size_up(MinHeapDeltaBytes, alignment); 4.14 + if (aligned_bytes == 0){ 4.15 + // The alignment caused the number of bytes to wrap. An expand_by(0) will 4.16 + // return true with the implication that and expansion was done when it 4.17 + // was not. A call to expand implies a best effort to expand by "bytes" 4.18 + // but not a guarantee. Align down to give a best effort. This is likely 4.19 + // the most that the generation can expand since it has some capacity to 4.20 + // start with. 4.21 + aligned_bytes = align_size_down(bytes, alignment); 4.22 + } 4.23 4.24 bool success = false; 4.25 if (aligned_expand_bytes > aligned_bytes) { 4.26 @@ -231,8 +243,8 @@ 4.27 success = expand_to_reserved(); 4.28 } 4.29 4.30 - if (GC_locker::is_active()) { 4.31 - if (PrintGC && Verbose) { 4.32 + if (PrintGC && Verbose) { 4.33 + if (success && GC_locker::is_active()) { 4.34 gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead"); 4.35 } 4.36 } 4.37 @@ -241,6 +253,9 @@ 4.38 bool PSOldGen::expand_by(size_t bytes) { 4.39 assert_lock_strong(ExpandHeap_lock); 4.40 assert_locked_or_safepoint(Heap_lock); 4.41 + if (bytes == 0) { 4.42 + return true; // That's what virtual_space()->expand_by(0) would return 4.43 + } 4.44 bool result = virtual_space()->expand_by(bytes); 4.45 if (result) { 4.46 if (ZapUnusedHeapArea) {
5.1 --- a/src/share/vm/gc_implementation/shared/spaceDecorator.cpp Mon Jul 28 15:30:23 2008 -0700 5.2 +++ b/src/share/vm/gc_implementation/shared/spaceDecorator.cpp Wed Jul 30 11:54:00 2008 -0700 5.3 @@ -39,7 +39,8 @@ 5.4 5.5 void SpaceMangler::set_top_for_allocations(HeapWord* v) { 5.6 if (v < end()) { 5.7 - assert(is_mangled(v), "The high water mark is not mangled"); 5.8 + assert(!CheckZapUnusedHeapArea || is_mangled(v), 5.9 + "The high water mark is not mangled"); 5.10 } 5.11 _top_for_allocations = v; 5.12 }
6.1 --- a/src/share/vm/memory/compactingPermGenGen.cpp Mon Jul 28 15:30:23 2008 -0700 6.2 +++ b/src/share/vm/memory/compactingPermGenGen.cpp Wed Jul 30 11:54:00 2008 -0700 6.3 @@ -432,14 +432,16 @@ 6.4 } 6.5 6.6 6.7 -void CompactingPermGenGen::grow_to_reserved() { 6.8 +bool CompactingPermGenGen::grow_to_reserved() { 6.9 // Don't allow _virtual_size to expand into shared spaces. 6.10 + bool success = false; 6.11 if (_virtual_space.uncommitted_size() > _shared_space_size) { 6.12 size_t remaining_bytes = 6.13 _virtual_space.uncommitted_size() - _shared_space_size; 6.14 - bool success = OneContigSpaceCardGeneration::grow_by(remaining_bytes); 6.15 + success = OneContigSpaceCardGeneration::grow_by(remaining_bytes); 6.16 DEBUG_ONLY(if (!success) warning("grow to reserved failed");) 6.17 } 6.18 + return success; 6.19 } 6.20 6.21
7.1 --- a/src/share/vm/memory/compactingPermGenGen.hpp Mon Jul 28 15:30:23 2008 -0700 7.2 +++ b/src/share/vm/memory/compactingPermGenGen.hpp Wed Jul 30 11:54:00 2008 -0700 7.3 @@ -184,7 +184,7 @@ 7.4 void post_compact(); 7.5 size_t contiguous_available() const; 7.6 bool grow_by(size_t bytes); 7.7 - void grow_to_reserved(); 7.8 + virtual bool grow_to_reserved(); 7.9 7.10 void clear_remembered_set(); 7.11 void invalidate_remembered_set();
8.1 --- a/src/share/vm/memory/generation.cpp Mon Jul 28 15:30:23 2008 -0700 8.2 +++ b/src/share/vm/memory/generation.cpp Wed Jul 30 11:54:00 2008 -0700 8.3 @@ -379,6 +379,41 @@ 8.4 } 8.5 } 8.6 8.7 +bool CardGeneration::expand(size_t bytes, size_t expand_bytes) { 8.8 + assert_locked_or_safepoint(Heap_lock); 8.9 + if (bytes == 0) { 8.10 + return true; // That's what grow_by(0) would return 8.11 + } 8.12 + size_t aligned_bytes = ReservedSpace::page_align_size_up(bytes); 8.13 + if (aligned_bytes == 0){ 8.14 + // The alignment caused the number of bytes to wrap. An expand_by(0) will 8.15 + // return true with the implication that an expansion was done when it 8.16 + // was not. A call to expand implies a best effort to expand by "bytes" 8.17 + // but not a guarantee. Align down to give a best effort. This is likely 8.18 + // the most that the generation can expand since it has some capacity to 8.19 + // start with. 8.20 + aligned_bytes = ReservedSpace::page_align_size_down(bytes); 8.21 + } 8.22 + size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); 8.23 + bool success = false; 8.24 + if (aligned_expand_bytes > aligned_bytes) { 8.25 + success = grow_by(aligned_expand_bytes); 8.26 + } 8.27 + if (!success) { 8.28 + success = grow_by(aligned_bytes); 8.29 + } 8.30 + if (!success) { 8.31 + success = grow_to_reserved(); 8.32 + } 8.33 + if (PrintGC && Verbose) { 8.34 + if (success && GC_locker::is_active()) { 8.35 + gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead"); 8.36 + } 8.37 + } 8.38 + 8.39 + return success; 8.40 +} 8.41 + 8.42 8.43 // No young generation references, clear this generation's cards. 8.44 void CardGeneration::clear_remembered_set() { 8.45 @@ -441,25 +476,9 @@ 8.46 } 8.47 } 8.48 8.49 -void OneContigSpaceCardGeneration::expand(size_t bytes, size_t expand_bytes) { 8.50 +bool OneContigSpaceCardGeneration::expand(size_t bytes, size_t expand_bytes) { 8.51 GCMutexLocker x(ExpandHeap_lock); 8.52 - size_t aligned_bytes = ReservedSpace::page_align_size_up(bytes); 8.53 - size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); 8.54 - bool success = false; 8.55 - if (aligned_expand_bytes > aligned_bytes) { 8.56 - success = grow_by(aligned_expand_bytes); 8.57 - } 8.58 - if (!success) { 8.59 - success = grow_by(aligned_bytes); 8.60 - } 8.61 - if (!success) { 8.62 - grow_to_reserved(); 8.63 - } 8.64 - if (GC_locker::is_active()) { 8.65 - if (PrintGC && Verbose) { 8.66 - gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead"); 8.67 - } 8.68 - } 8.69 + return CardGeneration::expand(bytes, expand_bytes); 8.70 } 8.71 8.72
9.1 --- a/src/share/vm/memory/generation.hpp Mon Jul 28 15:30:23 2008 -0700 9.2 +++ b/src/share/vm/memory/generation.hpp Wed Jul 30 11:54:00 2008 -0700 9.3 @@ -606,11 +606,21 @@ 9.4 9.5 public: 9.6 9.7 + // Attempt to expand the generation by "bytes". Expand by at a 9.8 + // minimum "expand_bytes". Return true if some amount (not 9.9 + // necessarily the full "bytes") was done. 9.10 + virtual bool expand(size_t bytes, size_t expand_bytes); 9.11 + 9.12 virtual void clear_remembered_set(); 9.13 9.14 virtual void invalidate_remembered_set(); 9.15 9.16 virtual void prepare_for_verify(); 9.17 + 9.18 + // Grow generation with specified size (returns false if unable to grow) 9.19 + virtual bool grow_by(size_t bytes) = 0; 9.20 + // Grow generation to reserved size. 9.21 + virtual bool grow_to_reserved() = 0; 9.22 }; 9.23 9.24 // OneContigSpaceCardGeneration models a heap of old objects contained in a single 9.25 @@ -631,14 +641,14 @@ 9.26 // and after last GC. 9.27 9.28 // Grow generation with specified size (returns false if unable to grow) 9.29 - bool grow_by(size_t bytes); 9.30 + virtual bool grow_by(size_t bytes); 9.31 // Grow generation to reserved size. 9.32 - bool grow_to_reserved(); 9.33 + virtual bool grow_to_reserved(); 9.34 // Shrink generation with specified size (returns false if unable to shrink) 9.35 void shrink_by(size_t bytes); 9.36 9.37 // Allocation failure 9.38 - void expand(size_t bytes, size_t expand_bytes); 9.39 + virtual bool expand(size_t bytes, size_t expand_bytes); 9.40 void shrink(size_t bytes); 9.41 9.42 // Accessing spaces