--- 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
//////////////////////////////////////////////////////////////////////