xo-gc: refactor: move X1 object storage to new cls GCObjectStore.

This commit is contained in:
Roland Conybeare 2026-04-02 18:55:46 -04:00
commit 9803709df8
7 changed files with 224 additions and 225 deletions

View file

@ -7,6 +7,7 @@
#include "X1CollectorConfig.hpp"
#include "GCObject.hpp"
#include "GCObjectStore.hpp"
#include "MutationLogState.hpp"
#include "X1VerifyStats.hpp"
#include "generation.hpp"
@ -164,11 +165,11 @@ namespace xo {
GCRunState runstate() const noexcept { return runstate_; }
const ObjectTypeTable * get_object_types() const noexcept { return &object_types_; }
const RootSet * get_root_set() const noexcept { return &root_set_; }
const DArena * get_space(role r, Generation g) const noexcept { return space_[r][g]; }
DArena * get_space(role r, Generation g) noexcept { return space_[r][g]; }
DArena * from_space(Generation g) noexcept { return get_space(role::from_space(), g); }
DArena * to_space(Generation g) noexcept { return get_space(role::to_space(), g); }
DArena * new_space() noexcept { return to_space(Generation{0}); }
const DArena * get_space(role r, Generation g) const noexcept { return gco_store_.get_space(r, g); }
DArena * get_space(role r, Generation g) noexcept { return gco_store_.get_space(r, g); }
DArena * from_space(Generation g) noexcept { return this->get_space(role::from_space(), g); }
DArena * to_space(Generation g) noexcept { return this->get_space(role::to_space(), g); }
DArena * new_space() noexcept { return this->to_space(Generation{0}); }
// ----- basic statistics -----
@ -397,8 +398,10 @@ namespace xo {
// ----- book-keeping -----
#ifdef OBSOLETE // see swap_roles()
/** reverse to-space and from-space roles for generation g **/
void reverse_roles(Generation g) noexcept;
#endif
/** discard all allocated memory **/
void clear() noexcept;
@ -410,10 +413,6 @@ namespace xo {
void _init_gc_roots(const X1CollectorConfig & cfg, std::size_t page_z);
/** aux init function: initialize @ref mlog_storage_[][] arenas **/
void _init_mlogs(const X1CollectorConfig & cfg, std::size_t page_z);
#ifdef MOVED
/** aux init function: create mutation log **/
MutationLog _make_mlog(uint32_t igen, char tag_char, size_t mlog_z, std::size_t page_z);
#endif
/** aux init function: initialize @ref space_storage_[][] arenas **/
void _init_space(const X1CollectorConfig & cfg);
@ -493,21 +492,9 @@ namespace xo {
**/
MutationLogState mlog_state_;
/** collector-managed memory here.
* - space_[1] is from-space
* - space_[0] is to-space
* coordinates with role in gc/role.hpp, see also.
/** Collector-managed memory.
**/
/** arena objects for collector managed memory
* 1:1 with roles, but polarity reverses for each collection
**/
std::array<DArena, c_max_generation> space_storage_[c_n_role];
/** arena pointers. The roles of space_storage_[0][g] and space_storage_[1][g]
* are reversed each time generation g gets collected.
**/
std::array<DArena*, c_max_generation> space_[c_n_role];
GCObjectStore gco_store_;
/** counters collected during @ref verify_ok call **/
VerifyStats verify_stats_;

View file

@ -0,0 +1,81 @@
/** @file GCObjectStore.hpp
*
* @author Roland Conybeare, Apr 2026
**/
#pragma once
#include "generation.hpp"
#include <xo/alloc2/role.hpp>
#include <xo/arena/DArena.hpp>
#include <xo/arena/ArenaConfig.hpp>
#include <array>
namespace xo {
namespace mm {
/** @brief container to hold gc-aware objects for X1 collector
**/
class GCObjectStore {
public:
GCObjectStore(const ArenaConfig & arena_cfg, uint32_t ngen, bool debug_flag);
const DArena * get_space(role r, Generation g) const noexcept { return space_[r][g]; }
DArena * get_space(role r, Generation g) noexcept { return space_[r][g]; }
DArena * from_space(Generation g) noexcept { return get_space(role::from_space(), g); }
DArena * to_space(Generation g) noexcept { return get_space(role::to_space(), g); }
DArena * new_space() noexcept { return to_space(Generation{0}); }
/** Call @p visitor for each memory pool owned by this store **/
void visit_pools(const MemorySizeVisitor & visitor) const;
/** For each generation g in [0 ,.., upto)
* swap arenas assigned to {to-space, from-space}.
* Invoked once at the beginning of each gc cycle.
**/
void swap_roles(Generation upto) noexcept;
/** Cleanup at the end of a gc cycle.
* Reset from-space
* (current from-space is former to-space,
* relabeled at the beginning of collector cycle)
* for generations in [0 ,.., upto)
**/
void cleanup_phase(Generation upto,
bool sanitize_flag);
private:
/** auxiliary init function **/
void _init_space();
private:
/** Configuration for collector spaces.
* Will have (2 x G) of these,
* where G is @ref n_generation_.
* Not using name_ member.
*
* REQUIRE:
* - arena_config_.store_header_flag_ must be true
**/
ArenaConfig arena_config_;
/** number of generations in use. Same as @ref X1CollectorConfig::n_generation_ **/
uint32_t n_generation_ = 0;
/** true to enable debug logging **/
bool debug_flag_ = false;
/** arena objects for collector managed memory
* 1:1 with roles, but polarity reverses for each collection
**/
std::array<DArena, c_max_generation> space_storage_[c_n_role];
/** arena pointers. The roles of space_storage_[0][g] and space_storage_[1][g]
* are reversed each time generation g gets collected.
**/
std::array<DArena*, c_max_generation> space_[c_n_role];
};
} /*namespace mm*/
} /*namespace xo*/
/* end GCObjectStore.hpp */

View file

@ -16,6 +16,8 @@ namespace xo {
class DX1Collector;
class VerifyStats;
/** @brief container for X1 collector mutation logs
**/
class MutationLogState {
public:
using MutationLog = DArenaVector<MutationLogEntry>;
@ -133,7 +135,7 @@ namespace xo {
public:
/** number of generations in use. Same as @ref X1CollectorConfig.n_generation_ **/
/** number of generations in use. Same as @ref X1CollectorConfig::n_generation_ **/
uint32_t n_generation_ = 0;
/** true to enable debug logging **/
bool debug_flag_ = false;