comparison src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp @ 3762:5c0a3c1858b1

7048782: CMS: assert(last_chunk_index_to_check<= last_chunk_index) failed: parCardTableModRefBS.cpp:359 Summary: The LNC array is sized before the start of a scavenge, while the heap may expand during a scavenge. With CMS, the last block of an arbitrary suffice of the LNC array may expand due to coalition with the expansion delta. We now take care not to attempt access past the end of the LNC array. LNC array code will be cleaned up and suitably encapsulated as part of the forthcoming performance RFE 7043675. Reviewed-by: brutisso
author ysr
date Thu, 02 Jun 2011 10:23:36 -0700
parents 7d64aa23eb96
children 3be7439273c5
comparison
equal deleted inserted replaced
3761:1e3493ac2d11 3762:5c0a3c1858b1
346 "Bounds error."); 346 "Bounds error.");
347 // It is possible that a dirty card for the last object may have been 347 // It is possible that a dirty card for the last object may have been
348 // cleared before we had a chance to examine it. In that case, the value 348 // cleared before we had a chance to examine it. In that case, the value
349 // will have been logged in the LNC for that chunk. 349 // will have been logged in the LNC for that chunk.
350 // We need to examine as many chunks to the right as this object 350 // We need to examine as many chunks to the right as this object
351 // covers. 351 // covers. However, we need to bound this checking to the largest
352 const uintptr_t last_chunk_index_to_check = addr_to_chunk_index(last_block + last_block_size - 1) 352 // entry in the LNC array: this is because the heap may expand
353 - lowest_non_clean_base_chunk_index; 353 // after the LNC array has been created but before we reach this point,
354 DEBUG_ONLY(const uintptr_t last_chunk_index = addr_to_chunk_index(used.last()) 354 // and the last block in our chunk may have been expanded to include
355 - lowest_non_clean_base_chunk_index;) 355 // the expansion delta (and possibly subsequently allocated from, so
356 assert(last_chunk_index_to_check <= last_chunk_index, 356 // it wouldn't be sufficient to check whether that last block was
357 err_msg("Out of bounds: last_chunk_index_to_check " INTPTR_FORMAT 357 // or was not an object at this point).
358 " exceeds last_chunk_index " INTPTR_FORMAT, 358 uintptr_t last_chunk_index_to_check = addr_to_chunk_index(last_block + last_block_size - 1)
359 last_chunk_index_to_check, last_chunk_index)); 359 - lowest_non_clean_base_chunk_index;
360 const uintptr_t last_chunk_index = addr_to_chunk_index(used.last())
361 - lowest_non_clean_base_chunk_index;
362 if (last_chunk_index_to_check > last_chunk_index) {
363 assert(last_block + last_block_size > used.end(),
364 err_msg("Inconsistency detected: last_block [" PTR_FORMAT "," PTR_FORMAT "]"
365 " does not exceed used.end() = " PTR_FORMAT ","
366 " yet last_chunk_index_to_check " INTPTR_FORMAT
367 " exceeds last_chunk_index " INTPTR_FORMAT,
368 last_chunk_index_to_check, last_chunk_index));
369 assert(sp->used_region().end() > used.end(),
370 err_msg("Expansion did not happen: "
371 "[" PTR_FORMAT "," PTR_FORMAT ") -> [" PTR_FORMAT "," PTR_FORMAT ")",
372 sp->used_region().start(), sp->used_region().end(), used.start(), used.end()));
373 NOISY(tty->print_cr(" process_chunk_boundary: heap expanded; explicitly bounding last_chunk");)
374 last_chunk_index_to_check = last_chunk_index;
375 }
360 for (uintptr_t lnc_index = cur_chunk_index + 1; 376 for (uintptr_t lnc_index = cur_chunk_index + 1;
361 lnc_index <= last_chunk_index_to_check; 377 lnc_index <= last_chunk_index_to_check;
362 lnc_index++) { 378 lnc_index++) {
363 jbyte* lnc_card = lowest_non_clean[lnc_index]; 379 jbyte* lnc_card = lowest_non_clean[lnc_index];
364 if (lnc_card != NULL) { 380 if (lnc_card != NULL) {