diff --git a/src/hotspot/share/gc/serial/serialBlockOffsetTable.cpp b/src/hotspot/share/gc/serial/serialBlockOffsetTable.cpp index 95a1c451fbb..6a04b65e9aa 100644 --- a/src/hotspot/share/gc/serial/serialBlockOffsetTable.cpp +++ b/src/hotspot/share/gc/serial/serialBlockOffsetTable.cpp @@ -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(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"); diff --git a/src/hotspot/share/gc/serial/serialBlockOffsetTable.hpp b/src/hotspot/share/gc/serial/serialBlockOffsetTable.hpp index 4765c36908d..1c720cfaf87 100644 --- a/src/hotspot/share/gc/serial/serialBlockOffsetTable.hpp +++ b/src/hotspot/share/gc/serial/serialBlockOffsetTable.hpp @@ -36,9 +36,12 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" -class SerialBlockOffsetSharedArray: public CHeapObj { +// 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 { 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 { 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 diff --git a/src/hotspot/share/gc/serial/serialBlockOffsetTable.inline.hpp b/src/hotspot/share/gc/serial/serialBlockOffsetTable.inline.hpp index 5ca0a73ac65..fe003774eae 100644 --- a/src/hotspot/share/gc/serial/serialBlockOffsetTable.inline.hpp +++ b/src/hotspot/share/gc/serial/serialBlockOffsetTable.inline.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), diff --git a/src/hotspot/share/gc/serial/tenuredGeneration.cpp b/src/hotspot/share/gc/serial/tenuredGeneration.cpp index 61eed1994b9..4a91f255ae9 100644 --- a/src/hotspot/share/gc/serial/tenuredGeneration.cpp +++ b/src/hotspot/share/gc/serial/tenuredGeneration.cpp @@ -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); diff --git a/src/hotspot/share/gc/serial/tenuredGeneration.hpp b/src/hotspot/share/gc/serial/tenuredGeneration.hpp index 2700c888619..c0c3c7fcf60 100644 --- a/src/hotspot/share/gc/serial/tenuredGeneration.hpp +++ b/src/hotspot/share/gc/serial/tenuredGeneration.hpp @@ -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; diff --git a/src/hotspot/share/gc/serial/vmStructs_serial.hpp b/src/hotspot/share/gc/serial/vmStructs_serial.hpp index bd2ff4b109a..f7bb570b601 100644 --- a/src/hotspot/share/gc/serial/vmStructs_serial.hpp +++ b/src/hotspot/share/gc/serial/vmStructs_serial.hpp @@ -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, \ diff --git a/src/hotspot/share/gc/shared/space.cpp b/src/hotspot/share/gc/shared/space.cpp index 7d141710d47..6ab5eec200e 100644 --- a/src/hotspot/share/gc/shared/space.cpp +++ b/src/hotspot/share/gc/shared/space.cpp @@ -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); } diff --git a/src/hotspot/share/gc/shared/space.hpp b/src/hotspot/share/gc/shared/space.hpp index 6eb8fe9818c..d0a6348d50d 100644 --- a/src/hotspot/share/gc/shared/space.hpp +++ b/src/hotspot/share/gc/shared/space.hpp @@ -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; diff --git a/src/hotspot/share/gc/shared/space.inline.hpp b/src/hotspot/share/gc/shared/space.inline.hpp index e34f833775a..e73a7b478bf 100644 --- a/src/hotspot/share/gc/shared/space.inline.hpp +++ b/src/hotspot/share/gc/shared/space.inline.hpp @@ -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