8328352: Serial: Inline SerialBlockOffsetSharedArray

Reviewed-by: ayang, aboldtch
This commit is contained in:
Guoxiong Li 2024-04-03 15:22:01 +00:00
parent bea493bcb8
commit ee09801afd
9 changed files with 66 additions and 82 deletions

View File

@ -33,8 +33,8 @@
#include "oops/oop.inline.hpp"
#include "runtime/java.hpp"
SerialBlockOffsetSharedArray::SerialBlockOffsetSharedArray(MemRegion reserved,
size_t init_word_size):
SerialBlockOffsetTable::SerialBlockOffsetTable(MemRegion reserved,
size_t init_word_size):
_reserved(reserved) {
size_t size = compute_size(reserved.word_size());
ReservedSpace rs(size);
@ -49,14 +49,14 @@ SerialBlockOffsetSharedArray::SerialBlockOffsetSharedArray(MemRegion reserved,
}
_offset_base = (uint8_t*)(_vs.low_boundary() - (uintptr_t(reserved.start()) >> CardTable::card_shift()));
resize(init_word_size);
log_trace(gc, bot)("SerialBlockOffsetSharedArray::SerialBlockOffsetSharedArray: ");
log_trace(gc, bot)("SerialBlockOffsetTable::SerialBlockOffsetTable: ");
log_trace(gc, bot)(" rs.base(): " PTR_FORMAT " rs.size(): " SIZE_FORMAT_X_0 " rs end(): " PTR_FORMAT,
p2i(rs.base()), rs.size(), p2i(rs.base() + rs.size()));
log_trace(gc, bot)(" _vs.low_boundary(): " PTR_FORMAT " _vs.high_boundary(): " PTR_FORMAT,
p2i(_vs.low_boundary()), p2i(_vs.high_boundary()));
}
void SerialBlockOffsetSharedArray::resize(size_t new_word_size) {
void SerialBlockOffsetTable::resize(size_t new_word_size) {
assert(new_word_size <= _reserved.word_size(), "Resize larger than reserved");
size_t new_size = compute_size(new_word_size);
size_t old_size = _vs.committed_size();
@ -112,13 +112,13 @@ void SerialBlockOffsetSharedArray::resize(size_t new_word_size) {
void SerialBlockOffsetTable::update_for_block_work(HeapWord* blk_start,
HeapWord* blk_end) {
HeapWord* const cur_card_boundary = align_up_by_card_size(blk_start);
uint8_t* const offset_card = _array->entry_for_addr(cur_card_boundary);
uint8_t* const offset_card = entry_for_addr(cur_card_boundary);
// The first card holds the actual offset.
_array->set_offset_array(offset_card, cur_card_boundary, blk_start);
set_offset_array(offset_card, cur_card_boundary, blk_start);
// Check if this block spans over other cards.
uint8_t* end_card = _array->entry_for_addr(blk_end - 1);
uint8_t* end_card = entry_for_addr(blk_end - 1);
assert(offset_card <= end_card, "inv");
if (offset_card != end_card) {
@ -130,7 +130,7 @@ void SerialBlockOffsetTable::update_for_block_work(HeapWord* blk_start,
uint8_t* reach = offset_card + BOTConstants::power_to_cards_back(i + 1) - 1;
uint8_t value = checked_cast<uint8_t>(CardTable::card_size_in_words() + i);
_array->set_offset_array(start_card_for_region, MIN2(reach, end_card), value);
set_offset_array(start_card_for_region, MIN2(reach, end_card), value);
start_card_for_region = reach + 1;
if (reach >= end_card) {
@ -144,7 +144,7 @@ void SerialBlockOffsetTable::update_for_block_work(HeapWord* blk_start,
}
HeapWord* SerialBlockOffsetTable::block_start_reaching_into_card(const void* addr) const {
uint8_t* entry = _array->entry_for_addr(addr);
uint8_t* entry = entry_for_addr(addr);
uint8_t offset = *entry;
while (offset >= CardTable::card_size_in_words()) {
// The excess of the offset from N_words indicates a power of Base
@ -153,15 +153,15 @@ HeapWord* SerialBlockOffsetTable::block_start_reaching_into_card(const void* add
entry -= n_cards_back;
offset = *entry;
}
HeapWord* q = _array->addr_for_entry(entry);
HeapWord* q = addr_for_entry(entry);
return q - offset;
}
void SerialBlockOffsetTable::verify_for_block(HeapWord* blk_start, HeapWord* blk_end) const {
assert(is_crossing_card_boundary(blk_start, blk_end), "precondition");
uint8_t* start_card = _array->entry_for_addr(align_up_by_card_size(blk_start));
uint8_t* end_card = _array->entry_for_addr(blk_end - 1);
uint8_t* start_card = entry_for_addr(align_up_by_card_size(blk_start));
uint8_t* end_card = entry_for_addr(blk_end - 1);
// Check cards in [start_card, end_card]
assert(*start_card < CardTable::card_size_in_words(), "offset card");

View File

@ -36,9 +36,12 @@
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
class SerialBlockOffsetSharedArray: public CHeapObj<mtGC> {
// SerialBlockOffsetTable divides the covered region into "N"-word subregions (where
// "N" = 2^"LogN". An array with an entry for each such subregion indicates
// how far back one must go to find the start of the chunk that includes the
// first word of the subregion.
class SerialBlockOffsetTable: public CHeapObj<mtGC> {
friend class VMStructs;
friend class SerialBlockOffsetTable;
// The reserved heap (i.e. old-gen) covered by the shared array.
MemRegion _reserved;
@ -63,6 +66,14 @@ class SerialBlockOffsetSharedArray: public CHeapObj<mtGC> {
return ReservedSpace::allocation_align_size_up(number_of_slots);
}
void update_for_block_work(HeapWord* blk_start, HeapWord* blk_end);
static HeapWord* align_up_by_card_size(HeapWord* const addr) {
return align_up(addr, CardTable::card_size());
}
void verify_for_block(HeapWord* blk_start, HeapWord* blk_end) const;
public:
// Initialize the table to cover from "base" to (at least)
// "base + init_word_size". In the future, the table may be expanded
@ -70,7 +81,25 @@ public:
// least "init_word_size".) The contents of the initial table are
// undefined; it is the responsibility of the constituent
// SerialBlockOffsetTable(s) to initialize cards.
SerialBlockOffsetSharedArray(MemRegion reserved, size_t init_word_size);
SerialBlockOffsetTable(MemRegion reserved, size_t init_word_size);
static bool is_crossing_card_boundary(HeapWord* const obj_start,
HeapWord* const obj_end) {
HeapWord* cur_card_boundary = align_up_by_card_size(obj_start);
// Strictly greater-than, since we check if this block *crosses* card boundary.
return obj_end > cur_card_boundary;
}
// Returns the address of the start of the block reaching into the card containing
// "addr".
HeapWord* block_start_reaching_into_card(const void* addr) const;
// [blk_start, blk_end) representing a block of memory in the heap.
void update_for_block(HeapWord* blk_start, HeapWord* blk_end) {
if (is_crossing_card_boundary(blk_start, blk_end)) {
update_for_block_work(blk_start, blk_end);
}
}
// Notes a change in the committed size of the region covered by the
// table. The "new_word_size" may not be larger than the size of the
@ -99,46 +128,4 @@ public:
}
};
// SerialBlockOffsetTable divides the covered region into "N"-word subregions (where
// "N" = 2^"LogN". An array with an entry for each such subregion indicates
// how far back one must go to find the start of the chunk that includes the
// first word of the subregion.
class SerialBlockOffsetTable {
friend class VMStructs;
// The array that contains offset values. Its reacts to heap resizing.
SerialBlockOffsetSharedArray* _array;
void update_for_block_work(HeapWord* blk_start, HeapWord* blk_end);
static HeapWord* align_up_by_card_size(HeapWord* const addr) {
return align_up(addr, CardTable::card_size());
}
void verify_for_block(HeapWord* blk_start, HeapWord* blk_end) const;
public:
// Initialize the table to cover the given space.
// The contents of the initial table are undefined.
SerialBlockOffsetTable(SerialBlockOffsetSharedArray* array) : _array(array) {}
static bool is_crossing_card_boundary(HeapWord* const obj_start,
HeapWord* const obj_end) {
HeapWord* cur_card_boundary = align_up_by_card_size(obj_start);
// Strictly greater-than, since we check if this block *crosses* card boundary.
return obj_end > cur_card_boundary;
}
// Returns the address of the start of the block reaching into the card containing
// "addr".
HeapWord* block_start_reaching_into_card(const void* addr) const;
// [blk_start, blk_end) representing a block of memory in the heap.
void update_for_block(HeapWord* blk_start, HeapWord* blk_end) {
if (is_crossing_card_boundary(blk_start, blk_end)) {
update_for_block_work(blk_start, blk_end);
}
}
};
#endif // SHARE_GC_SERIAL_SERIALBLOCKOFFSETTABLE_HPP

View File

@ -27,14 +27,14 @@
#include "gc/serial/serialBlockOffsetTable.hpp"
inline uint8_t* SerialBlockOffsetSharedArray::entry_for_addr(const void* const p) const {
inline uint8_t* SerialBlockOffsetTable::entry_for_addr(const void* const p) const {
assert(_reserved.contains(p),
"out of bounds access to block offset array");
uint8_t* result = &_offset_base[uintptr_t(p) >> CardTable::card_shift()];
return result;
}
inline HeapWord* SerialBlockOffsetSharedArray::addr_for_entry(const uint8_t* const p) const {
inline HeapWord* SerialBlockOffsetTable::addr_for_entry(const uint8_t* const p) const {
size_t delta = pointer_delta(p, _offset_base, sizeof(uint8_t));
HeapWord* result = (HeapWord*) (delta << CardTable::card_shift());
assert(_reserved.contains(result),

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2024, 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
@ -287,8 +287,8 @@ TenuredGeneration::TenuredGeneration(ReservedSpace rs,
assert((uintptr_t(start) & 3) == 0, "bad alignment");
assert((reserved_byte_size & 3) == 0, "bad alignment");
MemRegion reserved_mr(start, heap_word_size(reserved_byte_size));
_bts = new SerialBlockOffsetSharedArray(reserved_mr,
heap_word_size(initial_byte_size));
_bts = new SerialBlockOffsetTable(reserved_mr,
heap_word_size(initial_byte_size));
MemRegion committed_mr(start, heap_word_size(initial_byte_size));
_rs->resize_covered_region(committed_mr);

View File

@ -31,7 +31,7 @@
#include "gc/shared/space.hpp"
#include "utilities/macros.hpp"
class SerialBlockOffsetSharedArray;
class SerialBlockOffsetTable;
class CardTableRS;
class ContiguousSpace;
@ -50,7 +50,7 @@ class TenuredGeneration: public Generation {
// This is shared with other generations.
CardTableRS* _rs;
// This is local to this generation.
SerialBlockOffsetSharedArray* _bts;
SerialBlockOffsetTable* _bts;
// Current shrinking effect: this damps shrinking when the heap gets empty.
size_t _shrink_factor;

View File

@ -40,7 +40,7 @@
nonstatic_field(Generation::StatRecord, accumulated_time, elapsedTimer) \
\
nonstatic_field(TenuredGeneration, _rs, CardTableRS*) \
nonstatic_field(TenuredGeneration, _bts, SerialBlockOffsetSharedArray*) \
nonstatic_field(TenuredGeneration, _bts, SerialBlockOffsetTable*) \
nonstatic_field(TenuredGeneration, _shrink_factor, size_t) \
nonstatic_field(TenuredGeneration, _capacity_at_prologue, size_t) \
nonstatic_field(TenuredGeneration, _used_at_prologue, size_t) \
@ -54,13 +54,11 @@
nonstatic_field(DefNewGeneration, _from_space, ContiguousSpace*) \
nonstatic_field(DefNewGeneration, _to_space, ContiguousSpace*) \
\
nonstatic_field(SerialBlockOffsetTable, _array, SerialBlockOffsetSharedArray*) \
nonstatic_field(SerialBlockOffsetTable, _reserved, MemRegion) \
nonstatic_field(SerialBlockOffsetTable, _vs, VirtualSpace) \
nonstatic_field(SerialBlockOffsetTable, _offset_base, u_char*) \
\
nonstatic_field(SerialBlockOffsetSharedArray, _reserved, MemRegion) \
nonstatic_field(SerialBlockOffsetSharedArray, _vs, VirtualSpace) \
nonstatic_field(SerialBlockOffsetSharedArray, _offset_base, u_char*) \
\
nonstatic_field(TenuredSpace, _offsets, SerialBlockOffsetTable) \
nonstatic_field(TenuredSpace, _offsets, SerialBlockOffsetTable*) \
\
nonstatic_field(SerialHeap, _young_gen, DefNewGeneration*) \
nonstatic_field(SerialHeap, _old_gen, TenuredGeneration*) \
@ -78,7 +76,6 @@
declare_type(CardTableRS, CardTable) \
\
declare_toplevel_type(TenuredGeneration*) \
declare_toplevel_type(SerialBlockOffsetSharedArray) \
declare_toplevel_type(SerialBlockOffsetTable)
#define VM_INT_CONSTANTS_SERIALGC(declare_constant, \

View File

@ -193,7 +193,7 @@ HeapWord* ContiguousSpace::par_allocate(size_t size) {
#if INCLUDE_SERIALGC
HeapWord* TenuredSpace::block_start_const(const void* addr) const {
HeapWord* cur_block = _offsets.block_start_reaching_into_card(addr);
HeapWord* cur_block = _offsets->block_start_reaching_into_card(addr);
while (true) {
HeapWord* next_block = cur_block + cast_to_oop(cur_block)->size();
@ -208,9 +208,9 @@ HeapWord* TenuredSpace::block_start_const(const void* addr) const {
}
}
TenuredSpace::TenuredSpace(SerialBlockOffsetSharedArray* sharedOffsetArray,
TenuredSpace::TenuredSpace(SerialBlockOffsetTable* offsets,
MemRegion mr) :
_offsets(sharedOffsetArray)
_offsets(offsets)
{
initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2024, 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
@ -225,13 +225,13 @@ public:
class TenuredSpace: public ContiguousSpace {
friend class VMStructs;
protected:
SerialBlockOffsetTable _offsets;
SerialBlockOffsetTable* _offsets;
// Mark sweep support
size_t allowed_dead_ratio() const override;
public:
// Constructor
TenuredSpace(SerialBlockOffsetSharedArray* sharedOffsetArray,
TenuredSpace(SerialBlockOffsetTable* offsets,
MemRegion mr);
HeapWord* block_start_const(const void* addr) const override;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2024, 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
@ -38,7 +38,7 @@
inline HeapWord* TenuredSpace::allocate(size_t size) {
HeapWord* res = ContiguousSpace::allocate(size);
if (res != nullptr) {
_offsets.update_for_block(res, res + size);
_offsets->update_for_block(res, res + size);
}
return res;
}
@ -46,13 +46,13 @@ inline HeapWord* TenuredSpace::allocate(size_t size) {
inline HeapWord* TenuredSpace::par_allocate(size_t size) {
HeapWord* res = ContiguousSpace::par_allocate(size);
if (res != nullptr) {
_offsets.update_for_block(res, res + size);
_offsets->update_for_block(res, res + size);
}
return res;
}
inline void TenuredSpace::update_for_block(HeapWord* start, HeapWord* end) {
_offsets.update_for_block(start, end);
_offsets->update_for_block(start, end);
}
#endif // INCLUDE_SERIALGC