From caf2cb3e9be5afaf186b89b84aaaba8d166ce17a Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 29 Mar 2026 19:47:15 -0400 Subject: [PATCH] xo-gc stack: + gc-location-of() primitive --- include/xo/gc/DX1Collector.hpp | 3 +++ .../xo/gc/detail/ICollector_DX1Collector.hpp | 4 ++++ src/gc/DX1Collector.cpp | 22 +++++++++++++++++++ src/gc/facet/ICollector_DX1Collector.cpp | 6 +++++ 4 files changed, 35 insertions(+) diff --git a/include/xo/gc/DX1Collector.hpp b/include/xo/gc/DX1Collector.hpp index c1e1669..8279c8e 100644 --- a/include/xo/gc/DX1Collector.hpp +++ b/include/xo/gc/DX1Collector.hpp @@ -223,6 +223,9 @@ namespace xo { /** memory (virtual addresses) reserved for generation @p g in role @p r **/ size_type reserved(Generation g, role r) const noexcept; + /** very similar to generation_of(), but satisfies ACollector api **/ + std::int32_t locate_address(const void * addr) const noexcept; + // ----- full statistics ----- /** Report gc statistics as a dictionary. diff --git a/include/xo/gc/detail/ICollector_DX1Collector.hpp b/include/xo/gc/detail/ICollector_DX1Collector.hpp index f7db4b9..f73cb01 100644 --- a/include/xo/gc/detail/ICollector_DX1Collector.hpp +++ b/include/xo/gc/detail/ICollector_DX1Collector.hpp @@ -53,6 +53,10 @@ namespace xo { static size_type committed(const DX1Collector & self, Generation g, role r) noexcept; /** address space reserved for this collector **/ static size_type reserved(const DX1Collector & self, Generation g, role r) noexcept; + /** Location of object in collector. -1 if not in collector memory. +Other negative values represent collector error states (good luck!). +Exact meaning of non-negative values up to collector implementation **/ + static std::int32_t locate_address(const DX1Collector & self, const void * addr) noexcept; /** true if gc responsible for data at @p addr, and data belongs to role @p r **/ static bool contains(const DX1Collector & self, role r, const void * addr) noexcept; /** true iff gc-aware object of type @p tseq is installed in this collector **/ diff --git a/src/gc/DX1Collector.cpp b/src/gc/DX1Collector.cpp index d9f09b8..8a90a0b 100644 --- a/src/gc/DX1Collector.cpp +++ b/src/gc/DX1Collector.cpp @@ -342,6 +342,27 @@ namespace xo { return stat_helper(*this, &DArena::reserved, g, r); } + std::int32_t + DX1Collector::locate_address(const void * addr) const noexcept + { + Generation g; + + g = this->generation_of(role::to_space(), addr); + + if (!g.is_sentinel()) + return g; + + g = this->generation_of(role::from_space(), addr); + + if (!g.is_sentinel()) { + // use negative values for + + return -1 - g; + } + + return -1; + } + // editor bait: report-gc-statistics bool DX1Collector::report_statistics(obj mm, @@ -362,6 +383,7 @@ namespace xo { // ok &= rpt->upsert_cstr(mm, "n-generation", DInteger::box(mm, config_.n_generation_)); ok &= rpt->upsert_cstr(mm, "n-survive-threshold", DInteger::box(mm, config_.n_survive_threshold_)); + ok &= rpt->upsert_cstr(mm, "allow-incremental-gc", DBoolean::box(mm, config_.allow_incremental_gc_)); ok &= rpt->upsert_cstr(mm, "allocated", DInteger::box(mm, this->allocated())); ok &= rpt->upsert_cstr(mm, "committed", DInteger::box(mm, this->committed())); ok &= rpt->upsert_cstr(mm, "reserved", DInteger::box(mm, this->reserved())); diff --git a/src/gc/facet/ICollector_DX1Collector.cpp b/src/gc/facet/ICollector_DX1Collector.cpp index 2e3f55f..b07f169 100644 --- a/src/gc/facet/ICollector_DX1Collector.cpp +++ b/src/gc/facet/ICollector_DX1Collector.cpp @@ -33,6 +33,12 @@ namespace xo { return self.reserved(g, r); } + auto + ICollector_DX1Collector::locate_address(const DX1Collector & self, const void * addr) noexcept -> std::int32_t + { + return self.locate_address(addr); + } + auto ICollector_DX1Collector::contains(const DX1Collector & self, role r, const void * addr) noexcept -> bool {