Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
8275055: Improve HeapRegionRemSet::split_card()
Reviewed-by: sjohanss, ayang
  • Loading branch information
Thomas Schatzl committed Oct 20, 2021
1 parent 35e5bb5 commit 7e28bdd
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 3 deletions.
31 changes: 31 additions & 0 deletions src/hotspot/share/gc/g1/g1CardSetContainers.cpp
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2021, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/

#include "precompiled.hpp"

#include "gc/g1/g1CardSetContainers.hpp"
#include "utilities/globalDefinitions.hpp"

// The only limitation is from the G1CardSetArray.
uint G1CardSetContainer::LogCardsPerRegionLimit = sizeof(G1CardSetArray::EntryDataType) * BitsPerByte;
3 changes: 3 additions & 0 deletions src/hotspot/share/gc/g1/g1CardSetContainers.hpp
Expand Up @@ -177,6 +177,9 @@ class G1CardSetContainer {
void set_next(G1CardSetContainer* next) {
_next = next;
}

// Log of largest card index that can be stored in any G1CardSetContainer
static uint LogCardsPerRegionLimit;
};

class G1CardSetArray : public G1CardSetContainer {
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/gc/g1/g1CardSetContainers.inline.hpp
Expand Up @@ -27,6 +27,7 @@

#include "gc/g1/g1CardSetContainers.hpp"
#include "gc/g1/g1GCPhaseTimes.hpp"
#include "utilities/globalDefinitions.hpp"

inline G1CardSetInlinePtr::CardSetPtr G1CardSetInlinePtr::merge(CardSetPtr orig_value, uint card_in_region, uint idx, uint bits_per_card) {
assert((idx & (SizeFieldMask >> SizeFieldPos)) == idx, "Index %u too large to fit into size field", idx);
Expand Down
2 changes: 2 additions & 0 deletions src/hotspot/share/gc/g1/g1CollectedHeap.cpp
Expand Up @@ -1671,6 +1671,8 @@ jint G1CollectedHeap::initialize() {
guarantee(HeapRegion::CardsPerRegion < max_cards_per_region,
"too many cards per region");

HeapRegionRemSet::initialize(_reserved);

FreeRegionList::set_unrealistically_long_length(max_regions() + 1);

_bot = new G1BlockOffsetTable(reserved(), bot_storage);
Expand Down
31 changes: 31 additions & 0 deletions src/hotspot/share/gc/g1/heapRegionRemSet.cpp
Expand Up @@ -35,16 +35,47 @@
#include "oops/oop.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/globals_extension.hpp"
#include "runtime/java.hpp"
#include "utilities/bitMap.inline.hpp"
#include "utilities/debug.hpp"
#include "utilities/formatBuffer.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/powerOfTwo.hpp"

uint HeapRegionRemSet::_split_card_shift = 0;
size_t HeapRegionRemSet::_split_card_mask = 0;
HeapWord* HeapRegionRemSet::_heap_base_address = nullptr;

const char* HeapRegionRemSet::_state_strings[] = {"Untracked", "Updating", "Complete"};
const char* HeapRegionRemSet::_short_state_strings[] = {"UNTRA", "UPDAT", "CMPLT"};

void HeapRegionRemSet::initialize(MemRegion reserved) {
const uint BitsInUint = sizeof(uint) * BitsPerByte;
const uint CardBitsWithinCardRegion = MIN2((uint)HeapRegion::LogCardsPerRegion, G1CardSetContainer::LogCardsPerRegionLimit);

// Check if the number of cards within a region fits an uint.
if (CardBitsWithinCardRegion > BitsInUint) {
vm_exit_during_initialization("Can not represent all cards in a card region within uint.");
}

_split_card_shift = CardBitsWithinCardRegion + CardTable::card_shift;
_split_card_mask = ((size_t)1 << _split_card_shift) - 1;

// Check if the card region/region within cards combination can cover the heap.
const uint HeapSizeBits = log2i_exact(round_up_power_of_2(reserved.byte_size()));
if (HeapSizeBits > (BitsInUint + _split_card_shift)) {
FormatBuffer<> fmt("Can not represent all cards in the heap with card region/card within region. "
"Heap %zuB (%u bits) Remembered set covers %u bits.",
reserved.byte_size(),
HeapSizeBits,
BitsInUint + _split_card_shift);
vm_exit_during_initialization(fmt, "Decrease heap size.");
}

_heap_base_address = reserved.start();
}

HeapRegionRemSet::HeapRegionRemSet(HeapRegion* hr,
G1CardSetConfiguration* config) :
_m(Mutex::service - 1, FormatBuffer<128>("HeapRegionRemSet#%u_lock", hr->hrm_index())),
Expand Down
13 changes: 13 additions & 0 deletions src/hotspot/share/gc/g1/heapRegionRemSet.hpp
Expand Up @@ -50,6 +50,17 @@ class HeapRegionRemSet : public CHeapObj<mtGC> {

HeapRegion* _hr;

// When splitting addresses into region and card within that region, the logical
// shift value to get the region.
static uint _split_card_shift;
// When splitting addresses into region and card within that region, the mask
// to get the offset within the region.
static size_t _split_card_mask;
// Cached value of heap base address.
static HeapWord* _heap_base_address;

// Split the given address into region of that card and the card within that
// region.
inline void split_card(OopOrNarrowOopStar from, uint& card_region, uint& card_within_region) const;
void clear_fcc();

Expand Down Expand Up @@ -78,6 +89,8 @@ class HeapRegionRemSet : public CHeapObj<mtGC> {
return _card_set.occupied();
}

static void initialize(MemRegion reserved);

// Coarsening statistics since VM start.
static G1CardSetCoarsenStats coarsen_stats() { return G1CardSet::coarsen_stats(); }

Expand Down
7 changes: 4 additions & 3 deletions src/hotspot/share/gc/g1/heapRegionRemSet.inline.hpp
Expand Up @@ -62,9 +62,10 @@ inline void HeapRegionRemSet::iterate_for_merge(CardOrRangeVisitor& cl) {
}

void HeapRegionRemSet::split_card(OopOrNarrowOopStar from, uint& card_region, uint& card_within_region) const {
HeapRegion* hr = G1CollectedHeap::heap()->heap_region_containing(from);
card_region = hr->hrm_index();
card_within_region = (uint)(pointer_delta((HeapWord*)from, hr->bottom()) >> (CardTable::card_shift - LogHeapWordSize));
size_t offset = pointer_delta(from, _heap_base_address, 1);
card_region = (uint)(offset >> _split_card_shift);
card_within_region = (uint)((offset & _split_card_mask) >> CardTable::card_shift);
assert(card_within_region < ((uint)1 << G1CardSetContainer::LogCardsPerRegionLimit), "must be");
}

void HeapRegionRemSet::add_reference(OopOrNarrowOopStar from, uint tid) {
Expand Down

1 comment on commit 7e28bdd

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.