Mercurial > hg > graal-jvmci-8
comparison src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp @ 1886:72a161e62cc4
6991377: G1: race between concurrent refinement and humongous object allocation
Summary: There is a race between the concurrent refinement threads and the humongous object allocation that can cause the concurrent refinement threads to corrupt the part of the BOT that it is being initialized by the humongous object allocation operation. The solution is to do the humongous object allocation in careful steps to ensure that the concurrent refinement threads always have a consistent view over the BOT, region contents, and top. The fix includes some very minor tidying up in sparsePRT.
Reviewed-by: jcoomes, johnc, ysr
author | tonyp |
---|---|
date | Sat, 16 Oct 2010 17:12:19 -0400 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
comparison
equal
deleted
inserted
replaced
1885:a5c514e74487 | 1886:72a161e62cc4 |
---|---|
173 if (start_card > end_card) { | 173 if (start_card > end_card) { |
174 return; | 174 return; |
175 } | 175 } |
176 assert(start_card > _array->index_for(_bottom), "Cannot be first card"); | 176 assert(start_card > _array->index_for(_bottom), "Cannot be first card"); |
177 assert(_array->offset_array(start_card-1) <= N_words, | 177 assert(_array->offset_array(start_card-1) <= N_words, |
178 "Offset card has an unexpected value"); | 178 "Offset card has an unexpected value"); |
179 size_t start_card_for_region = start_card; | 179 size_t start_card_for_region = start_card; |
180 u_char offset = max_jubyte; | 180 u_char offset = max_jubyte; |
181 for (int i = 0; i < BlockOffsetArray::N_powers; i++) { | 181 for (int i = 0; i < BlockOffsetArray::N_powers; i++) { |
182 // -1 so that the the card with the actual offset is counted. Another -1 | 182 // -1 so that the the card with the actual offset is counted. Another -1 |
183 // so that the reach ends in this region and not at the start | 183 // so that the reach ends in this region and not at the start |
575 "offset array should have been set"); | 575 "offset array should have been set"); |
576 } | 576 } |
577 #endif | 577 #endif |
578 } | 578 } |
579 | 579 |
580 void | |
581 G1BlockOffsetArray::set_for_starts_humongous(HeapWord* new_end) { | |
582 assert(_end == new_end, "_end should have already been updated"); | |
583 | |
584 // The first BOT entry should have offset 0. | |
585 _array->set_offset_array(_array->index_for(_bottom), 0); | |
586 // The rest should point to the first one. | |
587 set_remainder_to_point_to_start(_bottom + N_words, new_end); | |
588 } | |
589 | |
580 ////////////////////////////////////////////////////////////////////// | 590 ////////////////////////////////////////////////////////////////////// |
581 // G1BlockOffsetArrayContigSpace | 591 // G1BlockOffsetArrayContigSpace |
582 ////////////////////////////////////////////////////////////////////// | 592 ////////////////////////////////////////////////////////////////////// |
583 | 593 |
584 HeapWord* | 594 HeapWord* |
624 size_t bottom_index = _array->index_for(_bottom); | 634 size_t bottom_index = _array->index_for(_bottom); |
625 assert(_array->address_for_index(bottom_index) == _bottom, | 635 assert(_array->address_for_index(bottom_index) == _bottom, |
626 "Precondition of call"); | 636 "Precondition of call"); |
627 _array->set_offset_array(bottom_index, 0); | 637 _array->set_offset_array(bottom_index, 0); |
628 } | 638 } |
639 | |
640 void | |
641 G1BlockOffsetArrayContigSpace::set_for_starts_humongous(HeapWord* new_end) { | |
642 G1BlockOffsetArray::set_for_starts_humongous(new_end); | |
643 | |
644 // Make sure _next_offset_threshold and _next_offset_index point to new_end. | |
645 _next_offset_threshold = new_end; | |
646 _next_offset_index = _array->index_for(new_end); | |
647 } |