From b4c89d8624e4a1050d86b7eaade93202aa46738e Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 16 Nov 2025 20:10:23 -0500 Subject: [PATCH] xo-interpreter adds + explict mm arg to ctors (retiring Object::mm) --- include/xo/alloc/GC.hpp | 2 + include/xo/alloc/Object.hpp | 3 +- src/alloc/ArenaAlloc.cpp | 71 +++++++++++++++++++++++------------ src/alloc/CMakeLists.txt | 4 +- src/alloc/GC.cpp | 74 ++++++++++++++++++++++++------------- src/alloc/Object.cpp | 2 +- utest/Forwarding1.test.cpp | 2 +- 7 files changed, 105 insertions(+), 53 deletions(-) diff --git a/include/xo/alloc/GC.hpp b/include/xo/alloc/GC.hpp index 1e73362e..abbb9657 100644 --- a/include/xo/alloc/GC.hpp +++ b/include/xo/alloc/GC.hpp @@ -54,6 +54,8 @@ namespace xo { bool allow_incremental_gc_ = true; /** true to report statistics **/ bool stats_flag_ = false; + /** true to capture per-type object statistics **/ + bool object_stats_flag_ = false; /** remember basic gc statistics for this many GC's; separately for incremental + full GCs **/ std::size_t stats_history_z_ = 256; /** true to enable debug logging **/ diff --git a/include/xo/alloc/Object.hpp b/include/xo/alloc/Object.hpp index 8d74f5af..5a981998 100644 --- a/include/xo/alloc/Object.hpp +++ b/include/xo/alloc/Object.hpp @@ -258,8 +258,9 @@ namespace xo { **/ class Cpof { public: - explicit Cpof(const Object * src) : src_{src} {} + explicit Cpof(gc::IAlloc * mm, const Object * src) : mm_{mm}, src_{src} {} + gc::IAlloc * mm_ = nullptr; const void * src_ = nullptr; }; } /*namespace xo*/ diff --git a/src/alloc/ArenaAlloc.cpp b/src/alloc/ArenaAlloc.cpp index 4fdcefe8..febbcb61 100644 --- a/src/alloc/ArenaAlloc.cpp +++ b/src/alloc/ArenaAlloc.cpp @@ -26,6 +26,11 @@ namespace xo { void * base = mmap(nullptr, z, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + log && log("acquired memory [lo,hi) using mmap", + xtag("lo", base), + xtag("z", z), + xtag("hi", reinterpret_cast(base) + z)); + // could use this as fallback.. //base = (new std::byte [z]); @@ -39,7 +44,7 @@ namespace xo { this->checkpoint_ = lo_; this->free_ptr_ = lo_; this->limit_ = lo_ + z; - this->hi_ = limit_; + this->hi_ = lo_ + z; this->debug_flag_ = debug_flag; if (!lo_) { @@ -52,22 +57,25 @@ namespace xo { ArenaAlloc::~ArenaAlloc() { + scope log(XO_DEBUG(debug_flag_)); // hygiene.. if (lo_) { + log && log("unmap [lo,hi)", xtag("lo", lo_), xtag("z", hi_ - lo_), xtag("hi", hi_)); + munmap(lo_, hi_ - lo_); } - // could use this as fallback if not using uncommitted technique + // could use this as fallback if we dropped the uncommitted technique //delete [] this->lo_; - this->lo_ = nullptr; + this->lo_ = nullptr; this->committed_z_ = 0; - this->checkpoint_ = nullptr; - this->free_ptr_ = nullptr; - this->limit_ = nullptr; - this->hi_ = nullptr; - this->debug_flag_ = false; + this->checkpoint_ = nullptr; + this->free_ptr_ = nullptr; + this->limit_ = nullptr; + this->hi_ = nullptr; + this->debug_flag_ = false; } up @@ -94,26 +102,41 @@ namespace xo { } bool - ArenaAlloc::expand(size_t offset_z) { + ArenaAlloc::expand(size_t offset_z) + { scope log(XO_DEBUG(debug_flag_), xtag("offset_z", offset_z), xtag("committed_z", committed_z_)); - if (offset_z <= committed_z_) + if (offset_z <= committed_z_) { + log && log("trivial success, offset within committed range", + xtag("offset_z", offset_z), + xtag("committed_z", committed_z_)); return true; - - std::size_t align_offset_z = align_lub(offset_z, page_z_); - std::byte * commit_start = lo_ + committed_z_; - std::size_t new_commit_z = align_offset_z - committed_z_; - - log && log(xtag("align_offset_z", align_offset_z), - xtag("new_commit_z", new_commit_z)); - - if (mprotect(commit_start, new_commit_z, PROT_READ | PROT_WRITE) != 0) { - throw std::runtime_error(tostr("ArenaAlloc::expand: commit failure", - xtag("committed_z", committed_z_), - xtag("new_commit_z", new_commit_z))); } - this->committed_z_ = align_offset_z; + if (lo_ + offset_z > limit_) { + throw std::runtime_error(tostr("ArenaAlloc::expand: requested size exceeds reserved size", + xtag("requested", offset_z), xtag("reserved", reserved()))); + } + + std::size_t aligned_offset_z = align_lub(offset_z, page_z_); + std::byte * commit_start = lo_ + committed_z_; + std::size_t add_commit_z = aligned_offset_z - committed_z_; + + log && log(xtag("aligned_offset_z", aligned_offset_z), + xtag("add_commit_z", add_commit_z)); + + log && log("expand committed range", + xtag("commit_start", commit_start), + xtag("add_commit_z", add_commit_z), + xtag("commit_end", commit_start + add_commit_z)); + + if (mprotect(commit_start, add_commit_z, PROT_READ | PROT_WRITE) != 0) { + throw std::runtime_error(tostr("ArenaAlloc::expand: commit failure", + xtag("committed_z", committed_z_), + xtag("add_commit_z", add_commit_z))); + } + + this->committed_z_ = aligned_offset_z; this->limit_ = this->lo_ + committed_z_; return true; @@ -167,6 +190,8 @@ namespace xo { std::byte * p = lo_; while (p < free_ptr_) { + log && log(xtag("p", (void *)p)); + Object * obj = reinterpret_cast(p); TaggedPtr tp = obj->self_tp(); std::size_t z = obj->_shallow_size(); diff --git a/src/alloc/CMakeLists.txt b/src/alloc/CMakeLists.txt index 5645b717..6bbc2f32 100644 --- a/src/alloc/CMakeLists.txt +++ b/src/alloc/CMakeLists.txt @@ -15,9 +15,9 @@ set(SELF_SRCS xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) # xo-unit used for time measurement -xo_dependency(${SELF_LIB} xo_unit) +xo_headeronly_dependency(${SELF_LIB} xo_unit) xo_dependency(${SELF_LIB} indentlog) xo_dependency(${SELF_LIB} reflect) -xo_dependency(${SELF_LIB} callback) +xo_headeronly_dependency(${SELF_LIB} callback) #end CMakeLists.txt diff --git a/src/alloc/GC.cpp b/src/alloc/GC.cpp index 051a68b3..8181cbb1 100644 --- a/src/alloc/GC.cpp +++ b/src/alloc/GC.cpp @@ -66,16 +66,36 @@ namespace xo { std::size_t nursery_size = config.initial_nursery_z_; std::size_t tenured_size = config.initial_tenured_z_; - nursery_[role2int(role::from_space)] + if (config_.incr_gc_threshold_ > nursery_size) { + throw std::runtime_error(tostr("GC::ctor: expected nursery gc threshold < nursery size", + xtag("nursery-gc-threshold", config_.incr_gc_threshold_), + xtag("nursery-size", nursery_size))); + } + + if (nursery_size + config_.full_gc_threshold_ > tenured_size) { + throw std::runtime_error(tostr("GC::ctor: expected nursery size + tennured gc threshold < tenured size", + xtag("nursery-size", nursery_size), + xtag("tenured-size", tenured_size), + xtag("full-gc-threshold", config_.full_gc_threshold_) + )); + } + + if (config_.incr_gc_threshold_ > nursery_size) + this->config_.incr_gc_threshold_ = nursery_size; + + if (config_.full_gc_threshold_ > tenured_size) + this->config_.full_gc_threshold_ = tenured_size; + + this->nursery_[role2int(role::from_space)] = ArenaAlloc::make("NA", nursery_size, config.debug_flag_); - nursery_[role2int(role::to_space) ] + this->nursery_[role2int(role::to_space) ] = ArenaAlloc::make("NB", nursery_size, config.debug_flag_); - tenured_[role2int(role::from_space)] + this->tenured_[role2int(role::from_space)] = ArenaAlloc::make("TA", tenured_size, config.debug_flag_); - tenured_[role2int(role::to_space) ] + this->tenured_[role2int(role::to_space) ] = ArenaAlloc::make("TB", tenured_size, config.debug_flag_); nursery_[role2int(role::from_space)]->expand(config.incr_gc_threshold_); @@ -83,9 +103,9 @@ namespace xo { tenured_[role2int(role::from_space)]->expand(config.full_gc_threshold_); tenured_[role2int(role::to_space) ]->expand(config.full_gc_threshold_); - mutation_log_[role2int(role::from_space)] = std::make_unique(); - mutation_log_[role2int(role::to_space )] = std::make_unique(); - defer_mutation_log_ = std::make_unique(); + this->mutation_log_[role2int(role::from_space)] = std::make_unique(); + this->mutation_log_[role2int(role::to_space )] = std::make_unique(); + this->defer_mutation_log_ = std::make_unique(); this->gc_history_ = CircularBuffer(config.stats_history_z_); @@ -96,23 +116,25 @@ namespace xo { /* hygiene */ this->clear(); - nursery_[role2int(role::from_space)].reset(); - nursery_[role2int(role::to_space) ].reset(); + this->nursery_[role2int(role::from_space)].reset(); + this->nursery_[role2int(role::to_space) ].reset(); - tenured_[role2int(role::from_space)].reset(); - tenured_[role2int(role::to_space) ].reset(); + this->tenured_[role2int(role::from_space)].reset(); + this->tenured_[role2int(role::to_space) ].reset(); - mutation_log_[role2int(role::from_space)].reset(); - mutation_log_[role2int(role::to_space) ].reset(); - defer_mutation_log_.reset(); + this->gc_root_v_.clear(); + + this->mutation_log_[role2int(role::from_space)].reset(); + this->mutation_log_[role2int(role::to_space) ].reset(); + this->defer_mutation_log_.reset(); } up GC::make(const Config & config) { - GC * gc = new GC(config); + //GC * gc = new GC(config); - return up{gc}; + return std::make_unique(config); } const std::string & @@ -608,16 +630,18 @@ namespace xo { void GC::capture_object_statistics(generation upto, capture_phase phase) { - /* scan nursery */ - this->nursery_[role2int(role::to_space)]->capture_object_statistics - (phase, - &object_statistics_sab_[gen2int(generation::nursery)]); - - if (upto == generation::tenured) { - /* scan tenured */ - this->tenured_[role2int(role::to_space)]->capture_object_statistics + if (config_.object_stats_flag_) { + /* scan nursery */ + this->nursery_[role2int(role::to_space)]->capture_object_statistics (phase, - &object_statistics_sab_[gen2int(generation::tenured)]); + &object_statistics_sab_[gen2int(generation::nursery)]); + + if (upto == generation::tenured) { + /* scan tenured */ + this->tenured_[role2int(role::to_space)]->capture_object_statistics + (phase, + &object_statistics_sab_[gen2int(generation::tenured)]); + } } } diff --git a/src/alloc/Object.cpp b/src/alloc/Object.cpp index b3db11ca..475d84ad 100644 --- a/src/alloc/Object.cpp +++ b/src/alloc/Object.cpp @@ -14,7 +14,7 @@ operator new (std::size_t z, const xo::Cpof & cpof) { using xo::gc::GC; - GC * gc = reinterpret_cast(xo::Object::mm); + GC * gc = reinterpret_cast(cpof.mm_); return gc->alloc_gc_copy(z, cpof.src_); } diff --git a/utest/Forwarding1.test.cpp b/utest/Forwarding1.test.cpp index e5dfb1fe..b39c35a1 100644 --- a/utest/Forwarding1.test.cpp +++ b/utest/Forwarding1.test.cpp @@ -33,7 +33,7 @@ namespace xo { void display(std::ostream & os) const final override { os << data_; } virtual std::size_t _shallow_size() const final override { return sizeof(*this); } - virtual Object * _shallow_copy() const final override { return new (Cpof(this)) DummyObject(*this); } + virtual Object * _shallow_copy() const final override { return new (Cpof(Object::mm, this)) DummyObject(*this); } virtual std::size_t _forward_children() final override { return _shallow_size(); } private: