xo-gc: generation -> Generation + bugfix idle test
This commit is contained in:
parent
7433c72d1f
commit
04fc5250fd
16 changed files with 125 additions and 145 deletions
|
|
@ -38,11 +38,11 @@ namespace xo {
|
|||
virtual typeseq _typeseq() const noexcept = 0;
|
||||
|
||||
virtual size_type allocated(Copaque d,
|
||||
generation g, role r) const noexcept = 0;
|
||||
Generation g, role r) const noexcept = 0;
|
||||
virtual size_type reserved(Copaque d,
|
||||
generation g, role r) const noexcept = 0;
|
||||
Generation g, role r) const noexcept = 0;
|
||||
virtual size_type committed(Copaque d,
|
||||
generation g, role r) const noexcept = 0;
|
||||
Generation g, role r) const noexcept = 0;
|
||||
virtual bool is_type_installed(Copaque d,
|
||||
typeseq tseq) const noexcept = 0;
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ namespace xo {
|
|||
* 3. if collection is currently disabled,
|
||||
* collection will trigger the next time gc is enabled.
|
||||
**/
|
||||
virtual void request_gc(Opaque d, generation upto) = 0;
|
||||
virtual void request_gc(Opaque d, Generation upto) = 0;
|
||||
|
||||
/** Assign pointer @p p_lhs to destination @p rhs, within parent allocation @p parent
|
||||
*
|
||||
|
|
|
|||
|
|
@ -31,16 +31,16 @@ namespace xo {
|
|||
typeseq _typeseq() const noexcept override { return s_typeseq; }
|
||||
|
||||
// const methods
|
||||
[[noreturn]] size_type allocated(Copaque, generation, role) const noexcept override { _fatal(); }
|
||||
[[noreturn]] size_type reserved(Copaque, generation, role) const noexcept override { _fatal(); }
|
||||
[[noreturn]] size_type committed(Copaque, generation, role) const noexcept override { _fatal(); }
|
||||
[[noreturn]] size_type allocated(Copaque, Generation, role) const noexcept override { _fatal(); }
|
||||
[[noreturn]] size_type reserved(Copaque, Generation, role) const noexcept override { _fatal(); }
|
||||
[[noreturn]] size_type committed(Copaque, Generation, role) const noexcept override { _fatal(); }
|
||||
[[noreturn]] bool is_type_installed(Copaque, typeseq) const noexcept override { _fatal(); }
|
||||
|
||||
// non-const methods
|
||||
[[noreturn]] bool install_type(Opaque, const AGCObject &) noexcept override { _fatal(); }
|
||||
[[noreturn]] void add_gc_root_poly(Opaque, obj<AGCObject> *) override { _fatal(); }
|
||||
[[noreturn]] void remove_gc_root_poly(Opaque, obj<AGCObject> *) override { _fatal(); }
|
||||
[[noreturn]] void request_gc(Opaque, generation) override { _fatal(); }
|
||||
[[noreturn]] void request_gc(Opaque, Generation) override { _fatal(); }
|
||||
[[noreturn]] void assign_member(Opaque, void *,
|
||||
obj<AGCObject> *, obj<AGCObject> &) override { _fatal(); }
|
||||
[[noreturn]] void forward_inplace(Opaque, AGCObject *, void **) override { _fatal(); }
|
||||
|
|
|
|||
|
|
@ -32,13 +32,13 @@ namespace xo {
|
|||
// const methods
|
||||
|
||||
typeseq _typeseq() const noexcept override { return s_typeseq; }
|
||||
size_type allocated(Copaque d, generation g, role r) const noexcept override {
|
||||
size_type allocated(Copaque d, Generation g, role r) const noexcept override {
|
||||
return I::allocated(_dcast(d), g, r);
|
||||
}
|
||||
size_type reserved(Copaque d, generation g, role r) const noexcept override {
|
||||
size_type reserved(Copaque d, Generation g, role r) const noexcept override {
|
||||
return I::reserved(_dcast(d), g, r);
|
||||
}
|
||||
size_type committed(Copaque d, generation g, role r) const noexcept override {
|
||||
size_type committed(Copaque d, Generation g, role r) const noexcept override {
|
||||
return I::committed(_dcast(d), g, r);
|
||||
}
|
||||
bool is_type_installed(Copaque d, typeseq tseq) const noexcept override {
|
||||
|
|
@ -56,7 +56,7 @@ namespace xo {
|
|||
void remove_gc_root_poly(Opaque d, obj<AGCObject> * p_root) override {
|
||||
I::remove_gc_root_poly(_dcast(d), p_root);
|
||||
}
|
||||
void request_gc(Opaque d, generation upto) override {
|
||||
void request_gc(Opaque d, Generation upto) override {
|
||||
I::request_gc(_dcast(d), upto);
|
||||
}
|
||||
void assign_member(Opaque d, void * parent,
|
||||
|
|
|
|||
|
|
@ -42,15 +42,15 @@ namespace xo {
|
|||
void forward_pivot_inplace(obj<AFacet,DRepr> * p_obj);
|
||||
|
||||
int32_t _typeseq() const noexcept { return O::iface()->_typeseq(); }
|
||||
size_type allocated(generation g, role r) const noexcept { return O::iface()->allocated(O::data(), g, r); }
|
||||
size_type reserved(generation g, role r) const noexcept { return O::iface()->reserved(O::data(), g, r); }
|
||||
size_type committed(generation g, role r) const noexcept { return O::iface()->committed(O::data(), g, r); }
|
||||
size_type allocated(Generation g, role r) const noexcept { return O::iface()->allocated(O::data(), g, r); }
|
||||
size_type reserved(Generation g, role r) const noexcept { return O::iface()->reserved(O::data(), g, r); }
|
||||
size_type committed(Generation g, role r) const noexcept { return O::iface()->committed(O::data(), g, r); }
|
||||
bool is_type_installed(typeseq tseq) const noexcept { return O::iface()->is_type_installed(O::data(), tseq); }
|
||||
|
||||
bool install_type(const AGCObject & iface) { return O::iface()->install_type(O::data(), iface); }
|
||||
void add_gc_root_poly(obj<AGCObject> * p_root) { O::iface()->add_gc_root_poly(O::data(), p_root); }
|
||||
void remove_gc_root_poly(obj<AGCObject> * p_root) { O::iface()->remove_gc_root_poly(O::data(), p_root); }
|
||||
void request_gc(generation g) { O::iface()->request_gc(O::data(), g); }
|
||||
void request_gc(Generation g) { O::iface()->request_gc(O::data(), g); }
|
||||
|
||||
void assign_member(void * parent,
|
||||
obj<AGCObject> * p_lhs,
|
||||
|
|
|
|||
|
|
@ -11,38 +11,38 @@
|
|||
namespace xo {
|
||||
namespace mm {
|
||||
/** hard maximum number of generations **/
|
||||
static constexpr uint32_t c_max_generation = 16;
|
||||
static constexpr uint32_t c_max_generation = 2;
|
||||
|
||||
/** @class generation
|
||||
* @brief type-safe generation number
|
||||
**/
|
||||
struct generation {
|
||||
struct Generation {
|
||||
using value_type = std::uint32_t;
|
||||
|
||||
constexpr generation() = default;
|
||||
explicit constexpr generation(value_type x) : value_{x} {}
|
||||
constexpr Generation() = default;
|
||||
explicit constexpr Generation(value_type x) : value_{x} {}
|
||||
|
||||
static generation nursery() { return generation{0}; }
|
||||
static generation sentinel() { return generation(c_max_generation); }
|
||||
static Generation nursery() { return Generation{0}; }
|
||||
static Generation sentinel() { return Generation(c_max_generation); }
|
||||
|
||||
bool is_sentinel() const noexcept { return value_ == c_max_generation; }
|
||||
|
||||
constexpr operator value_type() const { return value_; }
|
||||
|
||||
generation & operator++() { ++value_; return *this; }
|
||||
Generation & operator++() { ++value_; return *this; }
|
||||
|
||||
std::uint32_t value_ = 0;
|
||||
};
|
||||
|
||||
inline bool operator==(generation lhs, generation rhs) {
|
||||
inline bool operator==(Generation lhs, Generation rhs) {
|
||||
return lhs.value_ == rhs.value_;
|
||||
}
|
||||
|
||||
inline bool operator<(generation lhs, generation rhs) {
|
||||
inline bool operator<(Generation lhs, Generation rhs) {
|
||||
return lhs.value_ < rhs.value_;
|
||||
}
|
||||
|
||||
inline bool operator>(generation lhs, generation rhs) {
|
||||
inline bool operator>(Generation lhs, Generation rhs) {
|
||||
return lhs.value_ > rhs.value_;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,26 +23,6 @@ namespace xo {
|
|||
template <typename T>
|
||||
using up = std::unique_ptr<T>;
|
||||
|
||||
#ifdef NOT_YET
|
||||
/** State associated with a single DX1Collector generation
|
||||
**/
|
||||
struct Generation {
|
||||
Generation(uint8_t gen_id, up<DArena> from_space, up<DArena> to_space);
|
||||
~Generation() = default;
|
||||
|
||||
/** identity of this generation. Generations are numbered from
|
||||
* 0 (youngest) to N (oldest), with N <= c_max_generation
|
||||
**/
|
||||
uint8_t gen_id_;
|
||||
/** from-space. empty between collection episodes.
|
||||
* During collection holds former to-space
|
||||
**/
|
||||
up<DArena> from_space_;
|
||||
/** to-space. New allocations occur here **/
|
||||
up<DArena> to_space_;
|
||||
};
|
||||
#endif
|
||||
|
||||
// ----- GCRunState -----
|
||||
|
||||
/** @class GCRunState
|
||||
|
|
@ -58,23 +38,23 @@ namespace xo {
|
|||
verify
|
||||
};
|
||||
|
||||
GCRunState() : gc_upto_{0} {}
|
||||
GCRunState(Mode mode, generation gc_upto);
|
||||
GCRunState() : mode_{Mode::idle}, gc_upto_{0} {}
|
||||
GCRunState(Mode mode, Generation gc_upto);
|
||||
|
||||
static GCRunState idle();
|
||||
static GCRunState verify();
|
||||
static GCRunState gc_upto(generation g);
|
||||
static GCRunState gc_upto(Generation g);
|
||||
|
||||
generation gc_upto() const { return gc_upto_; }
|
||||
Generation gc_upto() const { return gc_upto_; }
|
||||
|
||||
bool is_running() const { return mode_ == Mode::idle; }
|
||||
bool is_running() const { return mode_ == Mode::gc; }
|
||||
bool is_verify() const { return mode_ == Mode::verify; }
|
||||
|
||||
private:
|
||||
/** current collector mode **/
|
||||
Mode mode_;
|
||||
Mode mode_ = Mode::idle;
|
||||
/** running gc collecting all generations gi < gc_upto **/
|
||||
generation gc_upto_;
|
||||
Generation gc_upto_;
|
||||
};
|
||||
|
||||
struct DX1CollectorIterator;
|
||||
|
|
@ -141,11 +121,11 @@ namespace xo {
|
|||
GCRunState runstate() const noexcept { return runstate_; }
|
||||
const DArena * 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 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}); }
|
||||
|
||||
// ----- basic statistics -----
|
||||
|
||||
|
|
@ -180,7 +160,7 @@ namespace xo {
|
|||
/** 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;
|
||||
Generation generation_of(role r, const void * addr) const noexcept;
|
||||
|
||||
/** return details from last error (will be in gen0 to-space) **/
|
||||
AllocError last_error() const noexcept;
|
||||
|
|
@ -238,10 +218,10 @@ namespace xo {
|
|||
* 3. if collection is currently disabled,
|
||||
* collection will trigger the next time gc is enabled.
|
||||
**/
|
||||
void request_gc(generation upto) noexcept;
|
||||
void request_gc(Generation upto) noexcept;
|
||||
|
||||
/** Execute gc immediately, for all generations < @p upto **/
|
||||
void execute_gc(generation upto) noexcept;
|
||||
void execute_gc(Generation upto) noexcept;
|
||||
|
||||
/** Evacuate object at @p *lhs_data to to-space.
|
||||
* Replace original with forwarding pointer to new location
|
||||
|
|
@ -318,7 +298,7 @@ namespace xo {
|
|||
// ----- book-keeping -----
|
||||
|
||||
/** reverse to-space and from-space roles for generation g **/
|
||||
void reverse_roles(generation g) noexcept;
|
||||
void reverse_roles(Generation g) noexcept;
|
||||
|
||||
/** discard all allocated memory **/
|
||||
void clear() noexcept;
|
||||
|
|
@ -336,24 +316,24 @@ namespace xo {
|
|||
void _init_space(const X1CollectorConfig & cfg);
|
||||
|
||||
/** swap from- and to- roles for all generations < @p upto **/
|
||||
void swap_roles(generation upto) noexcept;
|
||||
void swap_roles(Generation upto) noexcept;
|
||||
/** copy roots + everything reachable from them, to to-space **/
|
||||
void copy_roots(generation upto) noexcept;
|
||||
void copy_roots(Generation upto) noexcept;
|
||||
|
||||
/** cleanup after gc **/
|
||||
void cleanup_phase(generation upto);
|
||||
void cleanup_phase(Generation upto);
|
||||
|
||||
/** move root subgraph at @p from_src to to-space.
|
||||
* If not in gc-space, visit immediate children and move them.
|
||||
* Require: runstate_.is_running()
|
||||
**/
|
||||
void * _deep_move_root(obj<AGCObject> from_src, generation upto);
|
||||
void * _deep_move_root(obj<AGCObject> from_src, Generation upto);
|
||||
/** move interior subgraph at @p from_src to to-space.
|
||||
* no-op if not in gc-space.
|
||||
**/
|
||||
void * _deep_move_interior(void * from_src, generation upto);
|
||||
void * _deep_move_interior(void * from_src, Generation upto);
|
||||
/** Common driver for _deep_move_root(), _deep_move_interior() **/
|
||||
void * _deep_move_gc_owned(void * from_src, generation upto);
|
||||
void * _deep_move_gc_owned(void * from_src, Generation upto);
|
||||
/** Evacuate object at @p *lhs_data to to-space.
|
||||
* Replace original with forwarding pointer to new location
|
||||
**/
|
||||
|
|
@ -379,7 +359,7 @@ namespace xo {
|
|||
uint32_t gc_blocked_ = 0;
|
||||
|
||||
/** if > 0: need gc for all generations < gc_pending_upto_ **/
|
||||
generation gc_pending_upto_;
|
||||
Generation gc_pending_upto_;
|
||||
|
||||
/** using arena to get extensible list of root objects.
|
||||
* For each root store one address (type obj<AGCObject>*)
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ namespace xo {
|
|||
struct DX1CollectorIterator {
|
||||
DX1CollectorIterator() = default;
|
||||
DX1CollectorIterator(const DX1Collector * gc,
|
||||
generation gen_ix,
|
||||
generation gen_hi,
|
||||
Generation gen_ix,
|
||||
Generation gen_hi,
|
||||
DArenaIterator arena_ix,
|
||||
DArenaIterator arena_hi);
|
||||
|
||||
|
|
@ -42,8 +42,8 @@ namespace xo {
|
|||
bool is_valid() const noexcept { return (gc_ != nullptr); }
|
||||
bool is_invalid() const noexcept { return !is_valid(); }
|
||||
|
||||
generation gen_ix() const { return gen_ix_; }
|
||||
generation gen_hi() const { return gen_hi_; }
|
||||
Generation gen_ix() const { return gen_ix_; }
|
||||
Generation gen_hi() const { return gen_hi_; }
|
||||
DArenaIterator arena_ix() const { return arena_ix_; }
|
||||
DArenaIterator arena_hi() const { return arena_hi_; }
|
||||
|
||||
|
|
@ -70,8 +70,8 @@ namespace xo {
|
|||
* Current position is within arena for @p gen_ix_ to-space,
|
||||
* Provided @p gen_ix_ < @p gen_hi_
|
||||
**/
|
||||
generation gen_ix_;
|
||||
generation gen_hi_;
|
||||
Generation gen_ix_;
|
||||
Generation gen_hi_;
|
||||
/** Iterating over allocs in [@p arena_ix_, @p arena_hi_).
|
||||
* Current position is at @p arena_ix_
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ namespace xo {
|
|||
**/
|
||||
X1CollectorConfig with_sanitize_flag(bool x);
|
||||
|
||||
generation age2gen(object_age age) const noexcept {
|
||||
return generation(age % n_survive_threshold_);
|
||||
Generation age2gen(object_age age) const noexcept {
|
||||
return Generation(age % n_survive_threshold_);
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -40,15 +40,15 @@ namespace xo {
|
|||
|
||||
// todo: available()
|
||||
|
||||
static size_type allocated(const DX1Collector & d, generation g, role r);
|
||||
static size_type reserved(const DX1Collector & d, generation g, role r);
|
||||
static size_type committed(const DX1Collector & d, generation g, role r);
|
||||
static size_type allocated(const DX1Collector & d, Generation g, role r);
|
||||
static size_type reserved(const DX1Collector & d, Generation g, role r);
|
||||
static size_type committed(const DX1Collector & d, Generation g, role r);
|
||||
static bool is_type_installed(const DX1Collector & d, typeseq tseq);
|
||||
|
||||
static bool install_type(DX1Collector & d, const AGCObject & iface);
|
||||
static void add_gc_root_poly(DX1Collector & d, obj<AGCObject> * p_root);
|
||||
static void remove_gc_root_poly(DX1Collector & d, obj<AGCObject> * p_root);
|
||||
static void request_gc(DX1Collector & d, generation upto);
|
||||
static void request_gc(DX1Collector & d, Generation upto);
|
||||
static void assign_member(DX1Collector & d, void * parent,
|
||||
obj<AGCObject> * p_lhs, obj<AGCObject> & rhs);
|
||||
static void forward_inplace(DX1Collector & d, AGCObject * lhs_iface, void ** lhs_data);
|
||||
|
|
|
|||
|
|
@ -29,26 +29,26 @@ namespace xo {
|
|||
|
||||
// ----- GCRunState -----
|
||||
|
||||
GCRunState::GCRunState(Mode mode, generation gc_upto)
|
||||
GCRunState::GCRunState(Mode mode, Generation gc_upto)
|
||||
: mode_{mode}, gc_upto_{gc_upto}
|
||||
{}
|
||||
|
||||
GCRunState
|
||||
GCRunState::idle()
|
||||
{
|
||||
return GCRunState(Mode::idle, generation::sentinel());
|
||||
return GCRunState(Mode::idle, Generation::sentinel());
|
||||
}
|
||||
|
||||
GCRunState
|
||||
GCRunState::verify()
|
||||
{
|
||||
return GCRunState(Mode::verify, generation::sentinel());
|
||||
return GCRunState(Mode::verify, Generation::sentinel());
|
||||
}
|
||||
|
||||
GCRunState
|
||||
GCRunState::gc_upto(generation g)
|
||||
GCRunState::gc_upto(Generation g)
|
||||
{
|
||||
return GCRunState(Mode::gc, generation(g + 1));
|
||||
return GCRunState(Mode::gc, Generation(g + 1));
|
||||
}
|
||||
|
||||
// ----- DX1Collector -----
|
||||
|
|
@ -197,7 +197,7 @@ namespace xo {
|
|||
bool
|
||||
DX1Collector::contains_allocated(role r, const void * addr) const noexcept
|
||||
{
|
||||
generation g = this->generation_of(r, addr);
|
||||
Generation g = this->generation_of(r, addr);
|
||||
|
||||
if (g.is_sentinel())
|
||||
return false;
|
||||
|
|
@ -205,17 +205,17 @@ namespace xo {
|
|||
return this->get_space(r, g)->contains_allocated(addr);
|
||||
}
|
||||
|
||||
generation
|
||||
Generation
|
||||
DX1Collector::generation_of(role r, const void * addr) const noexcept
|
||||
{
|
||||
for (generation gi{0}; gi < config_.n_generation_; ++gi) {
|
||||
for (Generation gi{0}; gi < config_.n_generation_; ++gi) {
|
||||
const DArena * arena = get_space(r, gi);
|
||||
|
||||
if (arena->contains(addr))
|
||||
return gi;
|
||||
}
|
||||
|
||||
return generation::sentinel();
|
||||
return Generation::sentinel();
|
||||
}
|
||||
|
||||
AllocError
|
||||
|
|
@ -225,7 +225,7 @@ namespace xo {
|
|||
// need to adjust here if runtime errors
|
||||
// encountered during gc.
|
||||
|
||||
return get_space(role::to_space(), generation::nursery())->last_error_;
|
||||
return get_space(role::to_space(), Generation::nursery())->last_error_;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
@ -239,7 +239,7 @@ namespace xo {
|
|||
size_t z3 = 0;
|
||||
|
||||
for (role ri : role::all()) {
|
||||
for (generation gj{0}; gj < d.config_.n_generation_; ++gj) {
|
||||
for (Generation gj{0}; gj < d.config_.n_generation_; ++gj) {
|
||||
const DArena * arena = d.get_space(ri, gj);
|
||||
|
||||
assert(arena);
|
||||
|
|
@ -331,7 +331,7 @@ namespace xo {
|
|||
AllocInfo
|
||||
DX1Collector::alloc_info(value_type mem) const noexcept {
|
||||
for (role ri : role::all()) {
|
||||
for (generation gj{0}; gj < config_.n_generation_; ++gj) {
|
||||
for (Generation gj{0}; gj < config_.n_generation_; ++gj) {
|
||||
const DArena * arena = this->get_space(ri, gj);
|
||||
|
||||
assert(arena);
|
||||
|
|
@ -343,7 +343,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
// deliberately attempt on nursery to-space, to capture error info + return sentinel
|
||||
return this->get_space(role::to_space(), generation{0})->alloc_info(mem);
|
||||
return this->get_space(role::to_space(), Generation{0})->alloc_info(mem);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -445,7 +445,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
DX1Collector::request_gc(generation upto) noexcept
|
||||
DX1Collector::request_gc(Generation upto) noexcept
|
||||
{
|
||||
if (gc_blocked_ > 0) {
|
||||
if (gc_pending_upto_ < upto) {
|
||||
|
|
@ -459,7 +459,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
DX1Collector::execute_gc(generation upto) noexcept
|
||||
DX1Collector::execute_gc(Generation upto) noexcept
|
||||
{
|
||||
scope log(XO_DEBUG(true), xtag("upto", upto));
|
||||
|
||||
|
|
@ -482,8 +482,8 @@ namespace xo {
|
|||
log && log("step 1 : swap from/to roles (now to-space is empty)");
|
||||
this->swap_roles(upto);
|
||||
|
||||
log && log(xtag("from_0", get_space(role::from_space(), generation{0})->lo_),
|
||||
xtag("to_0", get_space(role::to_space(), generation{0})->lo_));
|
||||
log && log(xtag("from_0", get_space(role::from_space(), Generation{0})->lo_),
|
||||
xtag("to_0", get_space(role::to_space(), Generation{0})->lo_));
|
||||
|
||||
log && log("step 2a : copy roots");
|
||||
this->copy_roots(upto);
|
||||
|
|
@ -502,11 +502,11 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
DX1Collector::swap_roles(generation upto) noexcept
|
||||
DX1Collector::swap_roles(Generation upto) noexcept
|
||||
{
|
||||
scope log(XO_DEBUG(true), xtag("upto", upto));
|
||||
|
||||
for (generation g = generation{0}; g < upto; ++g) {
|
||||
for (Generation g = Generation{0}; g < upto; ++g) {
|
||||
log && log("swap roles", xtag("g", g));
|
||||
|
||||
std::swap(space_[role::to_space()][g], space_[role::from_space()][g]);
|
||||
|
|
@ -514,14 +514,14 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
DX1Collector::cleanup_phase(generation upto)
|
||||
DX1Collector::cleanup_phase(Generation upto)
|
||||
{
|
||||
scope log(XO_DEBUG(true), xtag("upto", upto));
|
||||
|
||||
// everything live has been copied out of from-space
|
||||
// -> now set to empty
|
||||
//
|
||||
for (generation g = generation{0}; g < upto; ++g) {
|
||||
for (Generation g = Generation{0}; g < upto; ++g) {
|
||||
if (config_.sanitize_flag_) {
|
||||
space_[role::from_space()][g]->scrub();
|
||||
}
|
||||
|
|
@ -534,7 +534,7 @@ namespace xo {
|
|||
|
||||
void *
|
||||
DX1Collector::_deep_move_root(obj<AGCObject> from_src,
|
||||
generation upto)
|
||||
Generation upto)
|
||||
{
|
||||
// NOTE:
|
||||
// Some roots are non-gc-owned nodes.
|
||||
|
|
@ -561,7 +561,7 @@ namespace xo {
|
|||
|
||||
void *
|
||||
DX1Collector::_deep_move_interior(void * from_src,
|
||||
generation upto)
|
||||
Generation upto)
|
||||
{
|
||||
scope log(XO_DEBUG(config_.debug_flag_));
|
||||
|
||||
|
|
@ -589,7 +589,7 @@ namespace xo {
|
|||
*/
|
||||
void *
|
||||
DX1Collector::_deep_move_gc_owned(void * from_src,
|
||||
generation upto)
|
||||
Generation upto)
|
||||
{
|
||||
scope log(XO_DEBUG(config_.debug_flag_));
|
||||
|
||||
|
|
@ -686,7 +686,7 @@ namespace xo {
|
|||
std::array<std::byte *, c_max_generation> gray_lo_v;
|
||||
{
|
||||
for (uint32_t g = 0; g < upto; ++g) {
|
||||
gray_lo_v[g] = this->to_space(generation{g})->free_;
|
||||
gray_lo_v[g] = this->to_space(Generation{g})->free_;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -706,7 +706,7 @@ namespace xo {
|
|||
do {
|
||||
fixup_work = 0;
|
||||
|
||||
for (generation g = generation{0}; g < upto; ++g) {
|
||||
for (Generation g = Generation{0}; g < upto; ++g) {
|
||||
/** object index for this pass **/
|
||||
size_t i_obj = 0;
|
||||
|
||||
|
|
@ -749,7 +749,7 @@ namespace xo {
|
|||
} /*_deep_move_gc_owned*/
|
||||
|
||||
void
|
||||
DX1Collector::copy_roots(generation upto) noexcept
|
||||
DX1Collector::copy_roots(Generation upto) noexcept
|
||||
{
|
||||
scope log(XO_DEBUG(true));
|
||||
|
||||
|
|
@ -834,7 +834,7 @@ namespace xo {
|
|||
* allocated object data.
|
||||
* Only using this to get alloc header
|
||||
**/
|
||||
DArena * some_arena = this->from_space(generation(0));
|
||||
DArena * some_arena = this->from_space(Generation(0));
|
||||
|
||||
DArena::header_type * p_header
|
||||
= some_arena->obj2hdr(object_data);
|
||||
|
|
@ -969,7 +969,7 @@ namespace xo {
|
|||
(void)iface;
|
||||
(void)data;
|
||||
|
||||
generation g = this->generation_of(role::to_space(), data);
|
||||
Generation g = this->generation_of(role::to_space(), data);
|
||||
|
||||
if (g.is_sentinel()) {
|
||||
g = this->generation_of(role::from_space(), data);
|
||||
|
|
@ -1028,7 +1028,7 @@ namespace xo {
|
|||
|
||||
object_age age = this->header2age(alloc_hdr);
|
||||
|
||||
generation g = config_.age2gen(age);
|
||||
Generation g = config_.age2gen(age);
|
||||
|
||||
assert(runstate_.is_running());
|
||||
|
||||
|
|
@ -1059,8 +1059,8 @@ namespace xo {
|
|||
bool
|
||||
DX1Collector::expand(size_type z) noexcept
|
||||
{
|
||||
if (with_facet<AAllocator>::mkobj(to_space(generation{0})).expand(z))
|
||||
return with_facet<AAllocator>::mkobj(from_space(generation{0})).expand(z);
|
||||
if (with_facet<AAllocator>::mkobj(to_space(Generation{0})).expand(z))
|
||||
return with_facet<AAllocator>::mkobj(from_space(Generation{0})).expand(z);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1091,7 +1091,7 @@ namespace xo {
|
|||
// 1. generation of lhs
|
||||
// 2. generation of rhs
|
||||
|
||||
generation src_g = this->generation_of(role::to_space(), p_lhs);
|
||||
Generation src_g = this->generation_of(role::to_space(), p_lhs);
|
||||
|
||||
if (src_g.is_sentinel()) {
|
||||
// only need mlog entries for gc-owned pointers.
|
||||
|
|
@ -1099,7 +1099,7 @@ namespace xo {
|
|||
return;
|
||||
}
|
||||
|
||||
generation dest_g = this->generation_of(role::to_space(), rhs.data());
|
||||
Generation dest_g = this->generation_of(role::to_space(), rhs.data());
|
||||
|
||||
if (dest_g.is_sentinel()) {
|
||||
// similarly, don't need mlog entry to non-gc-owned destination
|
||||
|
|
@ -1161,11 +1161,11 @@ namespace xo {
|
|||
|
||||
const DArena * arena
|
||||
= get_space(role::to_space(),
|
||||
generation{0});
|
||||
Generation{0});
|
||||
|
||||
return DX1CollectorIterator(this,
|
||||
generation{0},
|
||||
generation{config_.n_generation_},
|
||||
Generation{0},
|
||||
Generation{config_.n_generation_},
|
||||
arena->begin(),
|
||||
arena->end());
|
||||
}
|
||||
|
|
@ -1174,7 +1174,7 @@ namespace xo {
|
|||
DX1Collector::end() const noexcept {
|
||||
scope log(XO_DEBUG(false));
|
||||
|
||||
generation gen_hi = generation{config_.n_generation_};
|
||||
Generation gen_hi = Generation{config_.n_generation_};
|
||||
|
||||
/** valid iterator for end points to end of last DArena.
|
||||
* otherwise will interfere with working compare
|
||||
|
|
@ -1183,7 +1183,7 @@ namespace xo {
|
|||
|
||||
const DArena * arena
|
||||
= get_space(role::to_space(),
|
||||
generation(config_.n_generation_ - 1));
|
||||
Generation(config_.n_generation_ - 1));
|
||||
DArenaIterator arena_end = arena->end();
|
||||
|
||||
return DX1CollectorIterator(this,
|
||||
|
|
@ -1194,7 +1194,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
DX1Collector::reverse_roles(generation g) noexcept {
|
||||
DX1Collector::reverse_roles(Generation g) noexcept {
|
||||
assert(g < config_.n_generation_);
|
||||
|
||||
std::swap(space_[role::from_space()][g], space_[role::to_space()][g]);
|
||||
|
|
@ -1203,7 +1203,7 @@ namespace xo {
|
|||
void
|
||||
DX1Collector::clear() noexcept {
|
||||
for (role ri : role::all()) {
|
||||
for (generation gj{0}; gj < config_.n_generation_; ++gj) {
|
||||
for (Generation gj{0}; gj < config_.n_generation_; ++gj) {
|
||||
DArena * arena = this->get_space(ri, gj);
|
||||
|
||||
assert(arena);
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@
|
|||
namespace xo {
|
||||
namespace mm {
|
||||
DX1CollectorIterator::DX1CollectorIterator(const DX1Collector * gc,
|
||||
generation gen_ix,
|
||||
generation gen_hi,
|
||||
Generation gen_ix,
|
||||
Generation gen_hi,
|
||||
DArenaIterator arena_ix,
|
||||
DArenaIterator arena_hi) : gc_{gc},
|
||||
gen_ix_{gen_ix},
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace xo {
|
|||
size_type
|
||||
stat_helper(const DX1Collector & d,
|
||||
size_type (DArena::* getter)() const,
|
||||
generation g,
|
||||
Generation g,
|
||||
role r)
|
||||
{
|
||||
const DArena * arena = d.get_space(r, g);
|
||||
|
|
@ -30,19 +30,19 @@ namespace xo {
|
|||
}
|
||||
|
||||
size_type
|
||||
ICollector_DX1Collector::reserved(const DX1Collector & d, generation g, role r)
|
||||
ICollector_DX1Collector::reserved(const DX1Collector & d, Generation g, role r)
|
||||
{
|
||||
return stat_helper(d, &DArena::reserved, g, r);
|
||||
}
|
||||
|
||||
size_type
|
||||
ICollector_DX1Collector::allocated(const DX1Collector & d, generation g, role r)
|
||||
ICollector_DX1Collector::allocated(const DX1Collector & d, Generation g, role r)
|
||||
{
|
||||
return stat_helper(d, &DArena::allocated, g, r);
|
||||
}
|
||||
|
||||
size_type
|
||||
ICollector_DX1Collector::committed(const DX1Collector & d, generation g, role r)
|
||||
ICollector_DX1Collector::committed(const DX1Collector & d, Generation g, role r)
|
||||
{
|
||||
return stat_helper(d, &DArena::committed, g, r);
|
||||
}
|
||||
|
|
@ -76,7 +76,7 @@ namespace xo {
|
|||
|
||||
void
|
||||
ICollector_DX1Collector::request_gc(DX1Collector & d,
|
||||
generation upto)
|
||||
Generation upto)
|
||||
{
|
||||
d.request_gc(upto);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace xo {
|
|||
using xo::mm::DX1Collector;
|
||||
using xo::mm::ArenaConfig;
|
||||
using xo::mm::AllocHeaderConfig;
|
||||
using xo::mm::generation;
|
||||
using xo::mm::Generation;
|
||||
using xo::mm::c_max_generation;
|
||||
using xo::facet::with_facet;
|
||||
using xo::scope;
|
||||
|
|
@ -74,13 +74,13 @@ namespace xo {
|
|||
|
||||
DX1Collector gc = DX1Collector{cfg};
|
||||
|
||||
generation g0 = generation{0};
|
||||
Generation g0 = Generation{0};
|
||||
REQUIRE(gc.to_space(g0));
|
||||
REQUIRE(gc.from_space(g0));
|
||||
REQUIRE(gc.to_space(g0)->is_mapped());
|
||||
REQUIRE(gc.from_space(g0)->is_mapped());
|
||||
|
||||
generation g1 = generation{1};
|
||||
Generation g1 = Generation{1};
|
||||
REQUIRE(gc.to_space(g1));
|
||||
REQUIRE(gc.from_space(g1));
|
||||
REQUIRE(gc.to_space(g1)->is_mapped());
|
||||
|
|
@ -92,7 +92,7 @@ namespace xo {
|
|||
REQUIRE(gc.from_space(g1) != gc.from_space(g0));
|
||||
REQUIRE(gc.to_space(g0) != gc.from_space(g1));
|
||||
|
||||
for (generation gi = generation(2); gi < c_max_generation; ++gi) {
|
||||
for (Generation gi = Generation(2); gi < c_max_generation; ++gi) {
|
||||
INFO(xtag("gi", gi));
|
||||
|
||||
REQUIRE(!gc.to_space(gi));
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ namespace ut {
|
|||
using xo::mm::DArena;
|
||||
using xo::mm::X1CollectorConfig;
|
||||
using xo::mm::ArenaConfig;
|
||||
using xo::mm::generation;
|
||||
using xo::mm::Generation;
|
||||
using xo::mm::role;
|
||||
using xo::mm::padding;
|
||||
using xo::facet::with_facet;
|
||||
|
|
@ -137,7 +137,7 @@ namespace ut {
|
|||
REQUIRE(roots->store()->reserved() >= cfg.object_roots_z_);
|
||||
REQUIRE(roots->store()->reserved() < cfg.object_roots_z_ + roots->store()->page_z_);
|
||||
|
||||
const DArena * from_0 = gc.get_space(role::from_space(), generation{0});
|
||||
const DArena * from_0 = gc.get_space(role::from_space(), Generation{0});
|
||||
|
||||
REQUIRE(from_0 != nullptr);
|
||||
REQUIRE(from_0->reserved() >= tc.tenured_z_);
|
||||
|
|
@ -145,29 +145,29 @@ namespace ut {
|
|||
REQUIRE(from_0->reserved() % from_0->page_z_ == 0);
|
||||
REQUIRE(from_0->allocated() == 0);
|
||||
|
||||
const DArena * from_1 = gc.get_space(role::from_space(), generation{1});
|
||||
const DArena * from_1 = gc.get_space(role::from_space(), Generation{1});
|
||||
|
||||
REQUIRE(from_1 != nullptr);
|
||||
REQUIRE(from_1->reserved() == from_0->reserved());
|
||||
REQUIRE(from_1->allocated() == 0);
|
||||
|
||||
to_0 = gc.get_space(role::to_space(), generation{0});
|
||||
to_0 = gc.get_space(role::to_space(), Generation{0});
|
||||
|
||||
REQUIRE(to_0 != nullptr);
|
||||
REQUIRE(to_0->reserved() == from_0->reserved());
|
||||
REQUIRE(to_0->allocated() == 0);
|
||||
|
||||
const DArena * to_1 = gc.get_space(role::to_space(), generation{1});
|
||||
const DArena * to_1 = gc.get_space(role::to_space(), Generation{1});
|
||||
|
||||
REQUIRE(to_1 != nullptr);
|
||||
REQUIRE(to_1->reserved() == to_0->reserved());
|
||||
REQUIRE(to_1->allocated() == 0);
|
||||
|
||||
const DArena * from_2 = gc.get_space(role::from_space(), generation{2});
|
||||
const DArena * from_2 = gc.get_space(role::from_space(), Generation{2});
|
||||
|
||||
REQUIRE(from_2 == nullptr);
|
||||
|
||||
const DArena * to_2 = gc.get_space(role::to_space(), generation{2});
|
||||
const DArena * to_2 = gc.get_space(role::to_space(), Generation{2});
|
||||
|
||||
REQUIRE(to_2 == nullptr);
|
||||
|
||||
|
|
@ -257,7 +257,7 @@ namespace ut {
|
|||
}
|
||||
|
||||
/* no GC roots, so GC is trivial */
|
||||
c_o.request_gc(generation{1});
|
||||
c_o.request_gc(Generation{1});
|
||||
|
||||
log && log(xtag("l0_o.data()", l0_o.data()));
|
||||
log && log(xtag("l0_o.data()->head_.data()", l0_o.data()->head_.data()));
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include <xo/alloc2/generation.hpp>
|
||||
|
||||
namespace xo {
|
||||
using xo::mm::generation;
|
||||
using xo::mm::Generation;
|
||||
|
||||
namespace scm {
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ namespace xo {
|
|||
bool have_gc = false;
|
||||
|
||||
if (rcx.collector()) {
|
||||
generation upto(obj<AGCObject,DInteger>::from(upto_gco));
|
||||
Generation upto(obj<AGCObject,DInteger>::from(upto_gco));
|
||||
|
||||
rcx.collector().request_gc(upto);
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ namespace xo {
|
|||
using xo::mm::AGCObject;
|
||||
using xo::mm::DArena;
|
||||
using xo::mm::DX1Collector;
|
||||
using xo::mm::generation;
|
||||
using xo::mm::Generation;
|
||||
using xo::mm::X1CollectorConfig;
|
||||
using xo::mm::CollectorTypeRegistry;
|
||||
using xo::mm::MemorySizeInfo;
|
||||
|
|
@ -241,7 +241,7 @@ namespace xo {
|
|||
if (fixture->gc_flag_) {
|
||||
REQUIRE(expr_gc);
|
||||
|
||||
expr_gc.request_gc(generation(2));
|
||||
expr_gc.request_gc(Generation(2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue