diff --git a/include/xo/gc/DX1Collector.hpp b/include/xo/gc/DX1Collector.hpp index 86ee992..2eead63 100644 --- a/include/xo/gc/DX1Collector.hpp +++ b/include/xo/gc/DX1Collector.hpp @@ -23,26 +23,6 @@ namespace xo { template using up = std::unique_ptr; -#ifdef NOT_YET - /** State associated with a single DX1Collector generation - **/ - struct Generation { - Generation(uint8_t gen_id, up from_space, up 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 from_space_; - /** to-space. New allocations occur here **/ - up 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 from_src, generation upto); + void * _deep_move_root(obj 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*) diff --git a/include/xo/gc/DX1CollectorIterator.hpp b/include/xo/gc/DX1CollectorIterator.hpp index 98a1f1d..82944ff 100644 --- a/include/xo/gc/DX1CollectorIterator.hpp +++ b/include/xo/gc/DX1CollectorIterator.hpp @@ -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_ **/ diff --git a/include/xo/gc/X1CollectorConfig.hpp b/include/xo/gc/X1CollectorConfig.hpp index db96a43..83f0371 100644 --- a/include/xo/gc/X1CollectorConfig.hpp +++ b/include/xo/gc/X1CollectorConfig.hpp @@ -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: diff --git a/include/xo/gc/detail/ICollector_DX1Collector.hpp b/include/xo/gc/detail/ICollector_DX1Collector.hpp index 6984cd2..02c0902 100644 --- a/include/xo/gc/detail/ICollector_DX1Collector.hpp +++ b/include/xo/gc/detail/ICollector_DX1Collector.hpp @@ -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 * p_root); static void remove_gc_root_poly(DX1Collector & d, obj * 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 * p_lhs, obj & rhs); static void forward_inplace(DX1Collector & d, AGCObject * lhs_iface, void ** lhs_data); diff --git a/src/gc/DX1Collector.cpp b/src/gc/DX1Collector.cpp index 03a53f6..ef419cc 100644 --- a/src/gc/DX1Collector.cpp +++ b/src/gc/DX1Collector.cpp @@ -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 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 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::mkobj(to_space(generation{0})).expand(z)) - return with_facet::mkobj(from_space(generation{0})).expand(z); + if (with_facet::mkobj(to_space(Generation{0})).expand(z)) + return with_facet::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); diff --git a/src/gc/DX1CollectorIterator.cpp b/src/gc/DX1CollectorIterator.cpp index 7980d31..9780aca 100644 --- a/src/gc/DX1CollectorIterator.cpp +++ b/src/gc/DX1CollectorIterator.cpp @@ -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}, diff --git a/src/gc/ICollector_DX1Collector.cpp b/src/gc/ICollector_DX1Collector.cpp index fd0c811..09ec8ba 100644 --- a/src/gc/ICollector_DX1Collector.cpp +++ b/src/gc/ICollector_DX1Collector.cpp @@ -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); } diff --git a/utest/Collector.test.cpp b/utest/Collector.test.cpp index cf82fa9..8b464a2 100644 --- a/utest/Collector.test.cpp +++ b/utest/Collector.test.cpp @@ -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));