1.1 --- a/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp Fri May 27 10:23:03 2011 -0700 1.2 +++ b/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp Thu Jun 02 10:23:36 2011 -0700 1.3 @@ -348,15 +348,31 @@ 1.4 // cleared before we had a chance to examine it. In that case, the value 1.5 // will have been logged in the LNC for that chunk. 1.6 // We need to examine as many chunks to the right as this object 1.7 - // covers. 1.8 - const uintptr_t last_chunk_index_to_check = addr_to_chunk_index(last_block + last_block_size - 1) 1.9 - - lowest_non_clean_base_chunk_index; 1.10 - DEBUG_ONLY(const uintptr_t last_chunk_index = addr_to_chunk_index(used.last()) 1.11 - - lowest_non_clean_base_chunk_index;) 1.12 - assert(last_chunk_index_to_check <= last_chunk_index, 1.13 - err_msg("Out of bounds: last_chunk_index_to_check " INTPTR_FORMAT 1.14 - " exceeds last_chunk_index " INTPTR_FORMAT, 1.15 - last_chunk_index_to_check, last_chunk_index)); 1.16 + // covers. However, we need to bound this checking to the largest 1.17 + // entry in the LNC array: this is because the heap may expand 1.18 + // after the LNC array has been created but before we reach this point, 1.19 + // and the last block in our chunk may have been expanded to include 1.20 + // the expansion delta (and possibly subsequently allocated from, so 1.21 + // it wouldn't be sufficient to check whether that last block was 1.22 + // or was not an object at this point). 1.23 + uintptr_t last_chunk_index_to_check = addr_to_chunk_index(last_block + last_block_size - 1) 1.24 + - lowest_non_clean_base_chunk_index; 1.25 + const uintptr_t last_chunk_index = addr_to_chunk_index(used.last()) 1.26 + - lowest_non_clean_base_chunk_index; 1.27 + if (last_chunk_index_to_check > last_chunk_index) { 1.28 + assert(last_block + last_block_size > used.end(), 1.29 + err_msg("Inconsistency detected: last_block [" PTR_FORMAT "," PTR_FORMAT "]" 1.30 + " does not exceed used.end() = " PTR_FORMAT "," 1.31 + " yet last_chunk_index_to_check " INTPTR_FORMAT 1.32 + " exceeds last_chunk_index " INTPTR_FORMAT, 1.33 + last_chunk_index_to_check, last_chunk_index)); 1.34 + assert(sp->used_region().end() > used.end(), 1.35 + err_msg("Expansion did not happen: " 1.36 + "[" PTR_FORMAT "," PTR_FORMAT ") -> [" PTR_FORMAT "," PTR_FORMAT ")", 1.37 + sp->used_region().start(), sp->used_region().end(), used.start(), used.end())); 1.38 + NOISY(tty->print_cr(" process_chunk_boundary: heap expanded; explicitly bounding last_chunk");) 1.39 + last_chunk_index_to_check = last_chunk_index; 1.40 + } 1.41 for (uintptr_t lnc_index = cur_chunk_index + 1; 1.42 lnc_index <= last_chunk_index_to_check; 1.43 lnc_index++) {