117 lines
4.5 KiB
C++
117 lines
4.5 KiB
C++
/** @file GCObjectStore.hpp
|
|
*
|
|
* @author Roland Conybeare, Apr 2026
|
|
**/
|
|
|
|
#pragma once
|
|
|
|
#include "GCObjectStoreConfig.hpp"
|
|
#include "generation.hpp"
|
|
#include "object_age.hpp"
|
|
#include <xo/alloc2/role.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:
|
|
using header_type = DArena::header_type;
|
|
using value_type = DArena::value_type;
|
|
using size_type = DArena::size_type;
|
|
|
|
public:
|
|
explicit GCObjectStore(const GCObjectStoreConfig & cfg);
|
|
|
|
const GCObjectStoreConfig & config() const noexcept { return config_; }
|
|
|
|
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}); }
|
|
|
|
/** generation to which pointer @p addr belongs, given role @p r;
|
|
* sentinel if not found in this collector
|
|
**/
|
|
Generation generation_of(role r, const void * addr) const noexcept;
|
|
|
|
/** get allocation size from header **/
|
|
std::size_t header2size(header_type hdr) const noexcept;
|
|
/** get generation counter from alloc header **/
|
|
object_age header2age(header_type hdr) const noexcept;
|
|
/** get tseq from alloc header **/
|
|
uint32_t header2tseq(header_type hdr) const noexcept;
|
|
|
|
/** true iff original alloc has been replaced by a forwarding pointer **/
|
|
bool is_forwarding_header(header_type hdr) const noexcept;
|
|
|
|
/** Retreive bookkeeping info for allocation at @p mem. **/
|
|
AllocInfo alloc_info(value_type mem) const noexcept;
|
|
|
|
/** Call @p visitor for each memory pool owned by this store **/
|
|
void visit_pools(const MemorySizeVisitor & visitor) const;
|
|
|
|
/** true iff address @p addr allocated from this collector
|
|
* in role @p r (according to current GC state)
|
|
**/
|
|
bool contains(role r, const void * addr) const noexcept;
|
|
|
|
/** true iff address @p addr allocated from this collector and currently live
|
|
* in role @p r (according to current GC state)
|
|
*
|
|
* (i.e. in [lo,free) for an arena)
|
|
**/
|
|
bool contains_allocated(role r, const void * addr) const noexcept;
|
|
|
|
/** true iff {@p alloc_hdr, @p object_data} should move for
|
|
* a collection of all generations strictly younger than @p upto.
|
|
*
|
|
* Require: runstate_.is_running()
|
|
**/
|
|
bool check_move_policy(Generation upto,
|
|
header_type alloc_hdr,
|
|
void * gco_data) const noexcept;
|
|
|
|
/** 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 gc-aware object store **/
|
|
GCObjectStoreConfig config_;
|
|
|
|
/** 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 */
|