diff -r f0312c7d5b37 -r ba6c248cae19 src/hotspot/share/gc/shared/blockOffsetTable.cpp --- a/src/hotspot/share/gc/shared/blockOffsetTable.cpp Wed Nov 13 11:21:15 2019 +0100 +++ b/src/hotspot/share/gc/shared/blockOffsetTable.cpp Wed Nov 13 11:37:29 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -352,306 +352,6 @@ } ////////////////////////////////////////////////////////////////////// -// BlockOffsetArrayNonContigSpace -////////////////////////////////////////////////////////////////////// - -// The block [blk_start, blk_end) has been allocated; -// adjust the block offset table to represent this information; -// NOTE: Clients of BlockOffsetArrayNonContigSpace: consider using -// the somewhat more lightweight split_block() or -// (when init_to_zero()) mark_block() wherever possible. -// right-open interval: [blk_start, blk_end) -void -BlockOffsetArrayNonContigSpace::alloc_block(HeapWord* blk_start, - HeapWord* blk_end) { - assert(blk_start != NULL && blk_end > blk_start, - "phantom block"); - single_block(blk_start, blk_end); - allocated(blk_start, blk_end); -} - -// 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. - const size_t right_most_fixed_index = suff_index + num_pref_cards - 1; - set_remainder_to_point_to_start_incl(suff_index + 1, - right_most_fixed_index, 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; - // Fix the first power block with back_by > num_pref_cards. - while (more && (i < BOTConstants::N_powers)) { - size_t back_by = BOTConstants::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 (left_index <= right_most_fixed_index) { - left_index = right_most_fixed_index + 1; - } - 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, - BOTConstants::N_words + i - 1, true /* reducing */); - } else { - more = false; // we are done - assert((end_index - 1) == right_index, "Must be at the end."); - } - i++; - break; - } - i++; - } - // Fix the rest of the power blocks. - while (more && (i < BOTConstants::N_powers)) { - size_t back_by = BOTConstants::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, BOTConstants::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); -} - - -// Mark the BOT such that if [blk_start, blk_end) straddles a card -// boundary, the card following the first such boundary is marked -// with the appropriate offset. -// NOTE: this method does _not_ adjust _unallocated_block or -// any cards subsequent to the first one. -void -BlockOffsetArrayNonContigSpace::mark_block(HeapWord* blk_start, - HeapWord* blk_end, bool reducing) { - do_block_internal(blk_start, blk_end, Action_mark, reducing); -} - -HeapWord* BlockOffsetArrayNonContigSpace::block_start_unsafe( - const void* addr) const { - assert(_array->offset_array(0) == 0, "objects can't cross covered areas"); - assert(_bottom <= addr && addr < _end, - "addr must be covered by this Array"); - // Must read this exactly once because it can be modified by parallel - // allocation. - HeapWord* ub = _unallocated_block; - if (BlockOffsetArrayUseUnallocatedBlock && addr >= ub) { - assert(ub < _end, "tautology (see above)"); - return ub; - } - - // Otherwise, find the block start using the table. - size_t index = _array->index_for(addr); - HeapWord* q = _array->address_for_index(index); - - uint offset = _array->offset_array(index); // Extend u_char to uint. - while (offset >= BOTConstants::N_words) { - // The excess of the offset from N_words indicates a power of Base - // to go back by. - size_t n_cards_back = BOTConstants::entry_to_cards_back(offset); - q -= (BOTConstants::N_words * n_cards_back); - assert(q >= _sp->bottom(), - "q = " PTR_FORMAT " crossed below bottom = " PTR_FORMAT, - p2i(q), p2i(_sp->bottom())); - assert(q < _sp->end(), - "q = " PTR_FORMAT " crossed above end = " PTR_FORMAT, - p2i(q), p2i(_sp->end())); - index -= n_cards_back; - offset = _array->offset_array(index); - } - assert(offset < BOTConstants::N_words, "offset too large"); - index--; - q -= offset; - assert(q >= _sp->bottom(), - "q = " PTR_FORMAT " crossed below bottom = " PTR_FORMAT, - p2i(q), p2i(_sp->bottom())); - assert(q < _sp->end(), - "q = " PTR_FORMAT " crossed above end = " PTR_FORMAT, - p2i(q), p2i(_sp->end())); - HeapWord* n = q; - - while (n <= addr) { - debug_only(HeapWord* last = q); // for debugging - q = n; - n += _sp->block_size(n); - assert(n > q, - "Looping at n = " PTR_FORMAT " with last = " PTR_FORMAT "," - " while querying blk_start(" PTR_FORMAT ")" - " on _sp = [" PTR_FORMAT "," PTR_FORMAT ")", - p2i(n), p2i(last), p2i(addr), p2i(_sp->bottom()), p2i(_sp->end())); - } - assert(q <= addr, - "wrong order for current (" INTPTR_FORMAT ")" " <= arg (" INTPTR_FORMAT ")", - p2i(q), p2i(addr)); - assert(addr <= n, - "wrong order for arg (" INTPTR_FORMAT ") <= next (" INTPTR_FORMAT ")", - p2i(addr), p2i(n)); - return q; -} - -HeapWord* BlockOffsetArrayNonContigSpace::block_start_careful( - const void* addr) const { - assert(_array->offset_array(0) == 0, "objects can't cross covered areas"); - - assert(_bottom <= addr && addr < _end, - "addr must be covered by this Array"); - // Must read this exactly once because it can be modified by parallel - // allocation. - HeapWord* ub = _unallocated_block; - if (BlockOffsetArrayUseUnallocatedBlock && addr >= ub) { - assert(ub < _end, "tautology (see above)"); - return ub; - } - - // Otherwise, find the block start using the table, but taking - // care (cf block_start_unsafe() above) not to parse any objects/blocks - // on the cards themselves. - size_t index = _array->index_for(addr); - assert(_array->address_for_index(index) == addr, - "arg should be start of card"); - - HeapWord* q = (HeapWord*)addr; - uint offset; - do { - offset = _array->offset_array(index); - if (offset < BOTConstants::N_words) { - q -= offset; - } else { - size_t n_cards_back = BOTConstants::entry_to_cards_back(offset); - q -= (n_cards_back * BOTConstants::N_words); - index -= n_cards_back; - } - } while (offset >= BOTConstants::N_words); - assert(q <= addr, "block start should be to left of arg"); - return q; -} - -#ifndef PRODUCT -// Verification & debugging - ensure that the offset table reflects the fact -// that the block [blk_start, blk_end) or [blk, blk + size) is a -// single block of storage. NOTE: can't const this because of -// call to non-const do_block_internal() below. -void BlockOffsetArrayNonContigSpace::verify_single_block( - HeapWord* blk_start, HeapWord* blk_end) { - if (VerifyBlockOffsetArray) { - do_block_internal(blk_start, blk_end, Action_check); - } -} - -void BlockOffsetArrayNonContigSpace::verify_single_block( - HeapWord* blk, size_t size) { - verify_single_block(blk, blk + size); -} - -// Verify that the given block is before _unallocated_block -void BlockOffsetArrayNonContigSpace::verify_not_unallocated( - HeapWord* blk_start, HeapWord* blk_end) const { - if (BlockOffsetArrayUseUnallocatedBlock) { - assert(blk_start < blk_end, "Block inconsistency?"); - assert(blk_end <= _unallocated_block, "_unallocated_block problem"); - } -} - -void BlockOffsetArrayNonContigSpace::verify_not_unallocated( - HeapWord* blk, size_t size) const { - verify_not_unallocated(blk, blk + size); -} -#endif // PRODUCT - -size_t BlockOffsetArrayNonContigSpace::last_active_index() const { - if (_unallocated_block == _bottom) { - return 0; - } else { - return _array->index_for(_unallocated_block - 1); - } -} - -////////////////////////////////////////////////////////////////////// // BlockOffsetArrayContigSpace //////////////////////////////////////////////////////////////////////