G1BlockOffsetArray::G1BlockOffsetArray(G1BlockOffsetSharedArray* array, MemRegion mr, bool init_to_zero) : G1BlockOffsetTable(mr.start(), mr.end()), _unallocated_block(_bottom), _array(array), _csp(NULL), _init_to_zero(init_to_zero) { assert(_bottom <= _end, "arguments out of order"); if (!_init_to_zero) { // initialize cards to point back to mr.start() set_remainder_to_point_to_start(mr.start() + N_words, mr.end()); _array->set_offset_array(0, 0); // set first card to 0 } }
BlockOffsetArray::BlockOffsetArray(BlockOffsetSharedArray* array, MemRegion mr, bool init_to_zero_) : BlockOffsetTable(mr.start(), mr.end()), _array(array) { assert(_bottom <= _end, "arguments out of order"); set_init_to_zero(init_to_zero_); if (!init_to_zero_) { // initialize cards to point back to mr.start() set_remainder_to_point_to_start(mr.start() + N_words, mr.end()); _array->set_offset_array(0, 0); // set first card to 0 } }
// Action_mark - update the BOT for the block [blk_start, blk_end). // Current typical use is for splitting a block. // Action_single - update the BOT for an allocation. // Action_verify - BOT verification. void G1BlockOffsetArray::do_block_internal(HeapWord* blk_start, HeapWord* blk_end, Action action) { assert(Universe::heap()->is_in_reserved(blk_start), "reference must be into the heap"); assert(Universe::heap()->is_in_reserved(blk_end-1), "limit must be within the heap"); // This is optimized to make the test fast, assuming we only rarely // cross boundaries. uintptr_t end_ui = (uintptr_t)(blk_end - 1); uintptr_t start_ui = (uintptr_t)blk_start; // Calculate the last card boundary preceding end of blk intptr_t boundary_before_end = (intptr_t)end_ui; clear_bits(boundary_before_end, right_n_bits(LogN)); if (start_ui <= (uintptr_t)boundary_before_end) { // blk starts at or crosses a boundary // Calculate index of card on which blk begins size_t start_index = _array->index_for(blk_start); // Index of card on which blk ends size_t end_index = _array->index_for(blk_end - 1); // Start address of card on which blk begins HeapWord* boundary = _array->address_for_index(start_index); assert(boundary <= blk_start, "blk should start at or after boundary"); if (blk_start != boundary) { // blk starts strictly after boundary // adjust card boundary and start_index forward to next card boundary += N_words; start_index++; } assert(start_index <= end_index, "monotonicity of index_for()"); assert(boundary <= (HeapWord*)boundary_before_end, "tautology"); switch (action) { case Action_mark: { if (init_to_zero()) { _array->set_offset_array(start_index, boundary, blk_start); break; } // Else fall through to the next case } case Action_single: { _array->set_offset_array(start_index, boundary, blk_start); // We have finished marking the "offset card". We need to now // mark the subsequent cards that this blk spans. if (start_index < end_index) { HeapWord* rem_st = _array->address_for_index(start_index) + N_words; HeapWord* rem_end = _array->address_for_index(end_index) + N_words; set_remainder_to_point_to_start(rem_st, rem_end); } break; } case Action_check: { _array->check_offset_array(start_index, boundary, blk_start); // We have finished checking the "offset card". We need to now // check the subsequent cards that this blk spans. check_all_cards(start_index + 1, end_index); break; } default: ShouldNotReachHere(); } } }