Mercurial > hg > truffle
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) { |