--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Tue Jun 07 13:17:05 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Wed Jun 08 08:39:53 2011 -0700
@@ -1833,8 +1833,6 @@
}
)
_indexedFreeList[size].removeChunk(fc);
- debug_only(fc->clearNext());
- debug_only(fc->clearPrev());
NOT_PRODUCT(
if (FLSVerifyIndexTable) {
verifyIndexedFreeList(size);
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp Tue Jun 07 13:17:05 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp Wed Jun 08 08:39:53 2011 -0700
@@ -114,17 +114,11 @@
linkNext(ptr);
if (ptr != NULL) ptr->linkPrev(this);
}
- void linkAfterNonNull(FreeChunk* ptr) {
- assert(ptr != NULL, "precondition violation");
- linkNext(ptr);
- ptr->linkPrev(this);
- }
void linkNext(FreeChunk* ptr) { _next = ptr; }
void linkPrev(FreeChunk* ptr) {
LP64_ONLY(if (UseCompressedOops) _prev = ptr; else)
_prev = (FreeChunk*)((intptr_t)ptr | 0x1);
}
- void clearPrev() { _prev = NULL; }
void clearNext() { _next = NULL; }
void markNotFree() {
// Set _prev (klass) to null before (if) clearing the mark word below
--- a/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp Tue Jun 07 13:17:05 2011 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp Wed Jun 08 08:39:53 2011 -0700
@@ -348,15 +348,31 @@
// cleared before we had a chance to examine it. In that case, the value
// will have been logged in the LNC for that chunk.
// We need to examine as many chunks to the right as this object
- // covers.
- const uintptr_t last_chunk_index_to_check = addr_to_chunk_index(last_block + last_block_size - 1)
- - lowest_non_clean_base_chunk_index;
- DEBUG_ONLY(const uintptr_t last_chunk_index = addr_to_chunk_index(used.last())
- - lowest_non_clean_base_chunk_index;)
- assert(last_chunk_index_to_check <= last_chunk_index,
- err_msg("Out of bounds: last_chunk_index_to_check " INTPTR_FORMAT
- " exceeds last_chunk_index " INTPTR_FORMAT,
- last_chunk_index_to_check, last_chunk_index));
+ // covers. However, we need to bound this checking to the largest
+ // entry in the LNC array: this is because the heap may expand
+ // after the LNC array has been created but before we reach this point,
+ // and the last block in our chunk may have been expanded to include
+ // the expansion delta (and possibly subsequently allocated from, so
+ // it wouldn't be sufficient to check whether that last block was
+ // or was not an object at this point).
+ uintptr_t last_chunk_index_to_check = addr_to_chunk_index(last_block + last_block_size - 1)
+ - lowest_non_clean_base_chunk_index;
+ const uintptr_t last_chunk_index = addr_to_chunk_index(used.last())
+ - lowest_non_clean_base_chunk_index;
+ if (last_chunk_index_to_check > last_chunk_index) {
+ assert(last_block + last_block_size > used.end(),
+ err_msg("Inconsistency detected: last_block [" PTR_FORMAT "," PTR_FORMAT "]"
+ " does not exceed used.end() = " PTR_FORMAT ","
+ " yet last_chunk_index_to_check " INTPTR_FORMAT
+ " exceeds last_chunk_index " INTPTR_FORMAT,
+ last_chunk_index_to_check, last_chunk_index));
+ assert(sp->used_region().end() > used.end(),
+ err_msg("Expansion did not happen: "
+ "[" PTR_FORMAT "," PTR_FORMAT ") -> [" PTR_FORMAT "," PTR_FORMAT ")",
+ sp->used_region().start(), sp->used_region().end(), used.start(), used.end()));
+ NOISY(tty->print_cr(" process_chunk_boundary: heap expanded; explicitly bounding last_chunk");)
+ last_chunk_index_to_check = last_chunk_index;
+ }
for (uintptr_t lnc_index = cur_chunk_index + 1;
lnc_index <= last_chunk_index_to_check;
lnc_index++) {