xo-gc: refactor: move some aux method impls to GCObjectStore
This commit is contained in:
parent
55c5838f4a
commit
08b313f25c
9 changed files with 131 additions and 34 deletions
|
|
@ -26,6 +26,8 @@ namespace xo {
|
|||
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); }
|
||||
|
|
@ -53,6 +55,27 @@ namespace xo {
|
|||
/** 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.
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "generation.hpp"
|
||||
#include "object_age.hpp"
|
||||
#include <xo/arena/DArena.hpp>
|
||||
|
||||
namespace xo {
|
||||
|
|
@ -15,8 +17,30 @@ namespace xo {
|
|||
public:
|
||||
GCObjectStoreConfig(const ArenaConfig & arena_cfg,
|
||||
std::uint32_t ngen,
|
||||
std::uint32_t nsurvive,
|
||||
bool debug_flag);
|
||||
|
||||
/** generation that would contain an object that has survived
|
||||
* @p age collections. Equals the number of times object
|
||||
* has been promoted.
|
||||
*
|
||||
* Must be consistent
|
||||
**/
|
||||
Generation age2gen(object_age age) const noexcept {
|
||||
return Generation(age % n_survive_threshold_);
|
||||
}
|
||||
|
||||
/** age threshold for promotion to generation @p g **/
|
||||
uint32_t promotion_threshold(Generation g) const noexcept {
|
||||
|
||||
// TODO: may consider replacing with table-lookup
|
||||
// Require: if two distinct ages promote to some gen g at the same time,
|
||||
// then they also promote to gen g+k at the same time for all k>0.
|
||||
|
||||
return g * n_survive_threshold_;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
/** Configuration for collector spaces.
|
||||
* Will have (2 x G) of these,
|
||||
|
|
@ -27,8 +51,16 @@ namespace xo {
|
|||
* - arena_config_.store_header_flag_ must be true
|
||||
**/
|
||||
ArenaConfig arena_config_;
|
||||
|
||||
/** number of generations in use. Same as @ref X1CollectorConfig::n_generation_ **/
|
||||
std::uint32_t n_generation_ = 0;
|
||||
|
||||
/** Number of promotion steps.
|
||||
* An object that survives this number of collections
|
||||
* advances to the next generation.
|
||||
**/
|
||||
std::uint32_t n_survive_threshold_ = 2;
|
||||
|
||||
/** true to enable debug logging **/
|
||||
bool debug_flag_ = false;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "object_age.hpp"
|
||||
#include "generation.hpp"
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
|
@ -16,10 +17,25 @@ namespace xo {
|
|||
class MutationLogConfig {
|
||||
public:
|
||||
MutationLogConfig(std::uint32_t ngen,
|
||||
#ifdef OBSOLETE // in GCObjectStore
|
||||
std::uint32_t survive,
|
||||
#endif
|
||||
std::size_t mlog_z,
|
||||
bool debug_flag);
|
||||
|
||||
#ifdef OBSOLETE
|
||||
/** generation that would contain an object that has survived
|
||||
* @p age collections. Equals the number of times object
|
||||
* has been promoted.
|
||||
*
|
||||
* Must be consistent
|
||||
**/
|
||||
Generation age2gen(object_age age) const noexcept {
|
||||
return Generation(age % n_survive_threshold_);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef OBSOLETE
|
||||
/** age threshold for promotion to generation @p g **/
|
||||
uint32_t promotion_threshold(Generation g) const noexcept {
|
||||
|
||||
|
|
@ -29,7 +45,7 @@ namespace xo {
|
|||
|
||||
return g * n_survive_threshold_;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
public:
|
||||
/** number of generations in use.
|
||||
|
|
@ -37,11 +53,13 @@ namespace xo {
|
|||
**/
|
||||
std::uint32_t n_generation_ = 0;
|
||||
|
||||
#ifdef OBSOLETE
|
||||
/** Number of promotion steps.
|
||||
* An object that survives this number of collections
|
||||
* advances to the next generation.
|
||||
**/
|
||||
uint32_t n_survive_threshold_ = 2;
|
||||
#endif
|
||||
|
||||
/** storage for xgen pointer bookkeeping (aka remembered sets).
|
||||
* Use 3x this value per generation
|
||||
|
|
|
|||
|
|
@ -42,24 +42,27 @@ namespace xo {
|
|||
GCObjectStoreConfig gco_store_config() const noexcept {
|
||||
return GCObjectStoreConfig(arena_config_,
|
||||
n_generation_,
|
||||
n_survive_threshold_,
|
||||
debug_flag_);
|
||||
}
|
||||
|
||||
/** fetch configuration for mutation log store **/
|
||||
MutationLogConfig mlog_config() const noexcept {
|
||||
return MutationLogConfig(n_generation_,
|
||||
#ifdef OBSOLETE
|
||||
n_survive_threshold_,
|
||||
#endif
|
||||
mutation_log_z_,
|
||||
debug_flag_);
|
||||
}
|
||||
|
||||
Generation age2gen(object_age age) const noexcept {
|
||||
return Generation(age % n_survive_threshold_);
|
||||
return this->gco_store_config().age2gen(age);
|
||||
}
|
||||
|
||||
/** age threshold for promotion to generation @p g **/
|
||||
uint32_t promotion_threshold(Generation g) const noexcept {
|
||||
return mlog_config().promotion_threshold(g);
|
||||
return this->gco_store_config().promotion_threshold(g);
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -124,18 +124,13 @@ namespace xo {
|
|||
bool
|
||||
DX1Collector::contains(role r, const void * addr) const noexcept
|
||||
{
|
||||
return !(this->generation_of(r, addr).is_sentinel());
|
||||
return gco_store_.contains(r, addr);
|
||||
}
|
||||
|
||||
bool
|
||||
DX1Collector::contains_allocated(role r, const void * addr) const noexcept
|
||||
{
|
||||
Generation g = this->generation_of(r, addr);
|
||||
|
||||
if (g.is_sentinel())
|
||||
return false;
|
||||
|
||||
return this->get_space(r, g)->contains_allocated(addr);
|
||||
return gco_store_.contains_allocated(r, addr);
|
||||
}
|
||||
|
||||
Generation
|
||||
|
|
@ -212,16 +207,6 @@ namespace xo {
|
|||
DX1Collector::mutation_log_entries() const noexcept
|
||||
{
|
||||
return mlog_state_.mutation_log_entries();
|
||||
|
||||
#ifdef MOVED
|
||||
size_type z = 0;
|
||||
|
||||
for (Generation gj{0}; gj + 1 < config_.n_generation_; ++gj) {
|
||||
z += mlog_[role::to_space()][gj]->size();
|
||||
}
|
||||
|
||||
return z;
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
@ -1397,19 +1382,11 @@ namespace xo {
|
|||
DX1Collector::check_move_policy(header_type alloc_hdr,
|
||||
void * object_data) const noexcept
|
||||
{
|
||||
(void)object_data;
|
||||
|
||||
// when gc is moving objects, to- and from- spaces have been
|
||||
// reversed: forwarding pointers are located in from-space and
|
||||
// refer to to-space.
|
||||
|
||||
object_age age = this->header2age(alloc_hdr);
|
||||
|
||||
Generation g = config_.age2gen(age);
|
||||
|
||||
assert(runstate_.is_running());
|
||||
|
||||
return (g < runstate_.gc_upto());
|
||||
return gco_store_.check_move_policy(runstate_.gc_upto(),
|
||||
alloc_hdr,
|
||||
object_data);
|
||||
}
|
||||
|
||||
auto
|
||||
|
|
|
|||
|
|
@ -133,10 +133,48 @@ namespace xo {
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
GCObjectStore::contains(role r, const void * addr) const noexcept
|
||||
{
|
||||
return !(this->generation_of(r, addr).is_sentinel());
|
||||
}
|
||||
|
||||
bool
|
||||
GCObjectStore::contains_allocated(role r, const void * addr) const noexcept
|
||||
{
|
||||
Generation g = this->generation_of(r, addr);
|
||||
|
||||
if (g.is_sentinel())
|
||||
return false;
|
||||
|
||||
return this->get_space(r, g)->contains_allocated(addr);
|
||||
}
|
||||
|
||||
bool
|
||||
GCObjectStore::check_move_policy(Generation upto,
|
||||
header_type alloc_hdr,
|
||||
void * object_data) const noexcept
|
||||
{
|
||||
(void)object_data;
|
||||
|
||||
// when gc is moving objects, to- and from- spaces have been
|
||||
// reversed: forwarding pointers are located in from-space and
|
||||
// refer to to-space.
|
||||
|
||||
object_age age = this->header2age(alloc_hdr);
|
||||
|
||||
Generation g = config_.age2gen(age);
|
||||
|
||||
//assert(runstate_.is_running());
|
||||
|
||||
return (g < upto);
|
||||
}
|
||||
|
||||
void
|
||||
GCObjectStore::swap_roles(Generation upto) noexcept
|
||||
{
|
||||
scope log(XO_DEBUG(config_.debug_flag_), xtag("upto", upto));
|
||||
scope log(XO_DEBUG(config_.debug_flag_),
|
||||
xtag("upto", upto));
|
||||
|
||||
for (Generation g = Generation{0}; g < upto; ++g) {
|
||||
log && log("swap roles", xtag("g", g));
|
||||
|
|
|
|||
|
|
@ -10,9 +10,11 @@ namespace xo {
|
|||
|
||||
GCObjectStoreConfig::GCObjectStoreConfig(const ArenaConfig & arena_cfg,
|
||||
std::uint32_t ngen,
|
||||
std::uint32_t nsurvive,
|
||||
bool debug_flag)
|
||||
: arena_config_{arena_cfg},
|
||||
n_generation_{ngen},
|
||||
n_survive_threshold_{nsurvive},
|
||||
debug_flag_{debug_flag}
|
||||
{}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,11 +9,15 @@ namespace xo {
|
|||
namespace mm {
|
||||
|
||||
MutationLogConfig::MutationLogConfig(std::uint32_t ngen,
|
||||
#ifdef OBSOLETE
|
||||
std::uint32_t survive,
|
||||
#endif
|
||||
std::size_t mlog_z,
|
||||
bool debug_flag)
|
||||
: n_generation_{ngen},
|
||||
#ifdef OBSOLETE
|
||||
n_survive_threshold_{survive},
|
||||
#endif
|
||||
mutation_log_z_{mlog_z},
|
||||
debug_flag_{debug_flag}
|
||||
{}
|
||||
|
|
|
|||
|
|
@ -426,8 +426,8 @@ namespace xo {
|
|||
|
||||
bool need_mlog_entry
|
||||
= ((child_gen_to + 1 < config_.n_generation_)
|
||||
&& (config_.promotion_threshold(parent_gen_to)
|
||||
> config_.promotion_threshold(child_gen_to)));
|
||||
&& (gco_store.config().promotion_threshold(parent_gen_to)
|
||||
> gco_store.config().promotion_threshold(child_gen_to)));
|
||||
|
||||
if (need_mlog_entry) {
|
||||
// 1. P->C pointer is still cross-age (xage), and
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue