mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-22 16:26:05 +00:00
8328352: Serial: Inline SerialBlockOffsetSharedArray
Reviewed-by: ayang, aboldtch
This commit is contained in:
parent
bea493bcb8
commit
ee09801afd
@ -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");
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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, \
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user