From eec5bc098186f9bea236d0d0be438cc763897283 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 23 Nov 2025 21:41:14 -0500 Subject: [PATCH] xo-interpreter: + toplevel env in VSM --- include/xo/alloc/GC.hpp | 13 +++++++++++++ src/alloc/GC.cpp | 21 +++++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/include/xo/alloc/GC.hpp b/include/xo/alloc/GC.hpp index ce7b0f85..8e12990e 100644 --- a/include/xo/alloc/GC.hpp +++ b/include/xo/alloc/GC.hpp @@ -7,6 +7,7 @@ #include "ArenaAlloc.hpp" #include "GcStatistics.hpp" +#include "Object.hpp" #include "xo/callback/UpCallbackSet.hpp" #include "xo/indentlog/print/array.hpp" #include @@ -154,6 +155,9 @@ namespace xo { **/ static up make(const Config & config); + /** runtime downcast **/ + static GC * from(IAlloc * mm); + const Config & config() const { return config_; } std::uint8_t nursery_polarity() const { return nursery_polarity_; } std::uint8_t tenured_polarity() const { return tenured_polarity_; } @@ -230,6 +234,15 @@ namespace xo { * from @c *addr **/ void add_gc_root(Object ** addr); + /** reverse the effect of previous call to @ref add_gc_root **/ + void remove_gc_root(Object ** addr); + + /** convenience wrapper **/ + template + void add_gc_root_dwim(gp * p) { this->add_gc_root(reinterpret_cast(p->ptr_address())); } + template + void remove_gc_root_dwim(gp * p) { this->remove_gc_root(reinterpret_cast(p->ptr_address())); } + /** may optionally use this to observe GC copy phase. * Will be invoked once _per surviving object_, so not cheap. * Intended for GC visualization. diff --git a/src/alloc/GC.cpp b/src/alloc/GC.cpp index 22654700..c78768fb 100644 --- a/src/alloc/GC.cpp +++ b/src/alloc/GC.cpp @@ -132,11 +132,15 @@ namespace xo { up GC::make(const Config & config) { - //GC * gc = new GC(config); - return std::make_unique(config); } + GC * + GC::from(IAlloc * mm) + { + return dynamic_cast(mm); + } + const std::string & GC::name() const { @@ -390,6 +394,19 @@ namespace xo { gc_root_v_.push_back(addr); } + void + GC::remove_gc_root(Object ** addr) + { + /* Multithreaded GC not supported */ + + assert(!this->gc_in_progress()); + + auto new_end_ix = std::remove(gc_root_v_.begin(), gc_root_v_.end(), addr); + + /* erase now-unused slots */ + gc_root_v_.erase(new_end_ix, gc_root_v_.end()); + } + auto GC::add_gc_copy_callback(up fn) -> CallbackId {