// Adjust BOT to show that a previously whole block has been split // into two. void G1BlockOffsetArray::split_block(HeapWord* blk, size_t blk_size, size_t left_blk_size) { // Verify that the BOT shows [blk, blk + blk_size) to be one block. verify_single_block(blk, blk_size); // Update the BOT to indicate that [blk + left_blk_size, blk + blk_size) // is one single block. mark_block(blk + left_blk_size, blk + blk_size); }
////////////////////////////////////////////////////////////////////////// // BlockOffsetArrayNonContigSpace inlines ////////////////////////////////////////////////////////////////////////// inline void G1BlockOffsetArray::freed(HeapWord* blk_start, HeapWord* blk_end) { // Verify that the BOT shows [blk_start, blk_end) to be one block. verify_single_block(blk_start, blk_end); // adjust _unallocated_block upward or downward // as appropriate if (BlockOffsetArrayUseUnallocatedBlock) { assert(_unallocated_block <= _end, "Inconsistent value for _unallocated_block"); if (blk_end >= _unallocated_block && blk_start <= _unallocated_block) { // CMS-specific note: a block abutting _unallocated_block to // its left is being freed, a new block is being added or // we are resetting following a compaction _unallocated_block = blk_start; } } }
void BlockOffsetArrayNonContigSpace::verify_single_block( HeapWord* blk, size_t size) { verify_single_block(blk, blk + size); }
// Adjust BOT to show that a previously whole block has been split // into two. We verify the BOT for the first part (prefix) and // update the BOT for the second part (suffix). // blk is the start of the block // blk_size is the size of the original block // left_blk_size is the size of the first part of the split void BlockOffsetArrayNonContigSpace::split_block(HeapWord* blk, size_t blk_size, size_t left_blk_size) { // Verify that the BOT shows [blk, blk + blk_size) to be one block. verify_single_block(blk, blk_size); // Update the BOT to indicate that [blk + left_blk_size, blk + blk_size) // is one single block. assert(blk_size > 0, "Should be positive"); assert(left_blk_size > 0, "Should be positive"); assert(left_blk_size < blk_size, "Not a split"); // Start addresses of prefix block and suffix block. HeapWord* pref_addr = blk; HeapWord* suff_addr = blk + left_blk_size; HeapWord* end_addr = blk + blk_size; // Indices for starts of prefix block and suffix block. size_t pref_index = _array->index_for(pref_addr); if (_array->address_for_index(pref_index) != pref_addr) { // pref_addr does not begin pref_index pref_index++; } size_t suff_index = _array->index_for(suff_addr); if (_array->address_for_index(suff_index) != suff_addr) { // suff_addr does not begin suff_index suff_index++; } // Definition: A block B, denoted [B_start, B_end) __starts__ // a card C, denoted [C_start, C_end), where C_start and C_end // are the heap addresses that card C covers, iff // B_start <= C_start < B_end. // // We say that a card C "is started by" a block B, iff // B "starts" C. // // Note that the cardinality of the set of cards {C} // started by a block B can be 0, 1, or more. // // Below, pref_index and suff_index are, respectively, the // first (least) card indices that the prefix and suffix of // the split start; end_index is one more than the index of // the last (greatest) card that blk starts. size_t end_index = _array->index_for(end_addr - 1) + 1; // Calculate the # cards that the prefix and suffix affect. size_t num_pref_cards = suff_index - pref_index; size_t num_suff_cards = end_index - suff_index; // Change the cards that need changing if (num_suff_cards > 0) { HeapWord* boundary = _array->address_for_index(suff_index); // Set the offset card for suffix block _array->set_offset_array(suff_index, boundary, suff_addr, true /* reducing */); // Change any further cards that need changing in the suffix if (num_pref_cards > 0) { if (num_pref_cards >= num_suff_cards) { // Unilaterally fix all of the suffix cards: closed card // index interval in args below. set_remainder_to_point_to_start_incl(suff_index + 1, end_index - 1, true /* reducing */); } else { // Unilaterally fix the first (num_pref_cards - 1) following // the "offset card" in the suffix block. set_remainder_to_point_to_start_incl(suff_index + 1, suff_index + num_pref_cards - 1, true /* reducing */); // Fix the appropriate cards in the remainder of the // suffix block -- these are the last num_pref_cards // cards in each power block of the "new" range plumbed // from suff_addr. bool more = true; uint i = 1; while (more && (i < N_powers)) { size_t back_by = power_to_cards_back(i); size_t right_index = suff_index + back_by - 1; size_t left_index = right_index - num_pref_cards + 1; if (right_index >= end_index - 1) { // last iteration right_index = end_index - 1; more = false; } if (back_by > num_pref_cards) { // Fill in the remainder of this "power block", if it // is non-null. if (left_index <= right_index) { _array->set_offset_array(left_index, right_index, N_words + i - 1, true /* reducing */); } else { more = false; // we are done } i++; break; } i++; } while (more && (i < N_powers)) { size_t back_by = power_to_cards_back(i); size_t right_index = suff_index + back_by - 1; size_t left_index = right_index - num_pref_cards + 1; if (right_index >= end_index - 1) { // last iteration right_index = end_index - 1; if (left_index > right_index) { break; } more = false; } assert(left_index <= right_index, "Error"); _array->set_offset_array(left_index, right_index, N_words + i - 1, true /* reducing */); i++; } } } // else no more cards to fix in suffix } // else nothing needs to be done // Verify that we did the right thing verify_single_block(pref_addr, left_blk_size); verify_single_block(suff_addr, blk_size - left_blk_size); }