diff --git a/xo-alloc2/idl/GCObjectVisitor.json5 b/xo-alloc2/idl/GCObjectVisitor.json5 index e029417e..201623bd 100644 --- a/xo-alloc2/idl/GCObjectVisitor.json5 +++ b/xo-alloc2/idl/GCObjectVisitor.json5 @@ -4,11 +4,9 @@ output_hpp_dir: "include/xo/alloc2", output_impl_subdir: "gc", includes: [ + "", + "", "", -// "", -// "", -// "", -// "", ], // extra includes in GCObject.hpp, if any user_hpp_includes: [ @@ -38,7 +36,7 @@ // }, ], const_methods: [ - // AllocInfo alloc_info(void * gco); + // AllocInfo alloc_info(void * gco) const noexcept; { name: "alloc_info", doc: [ @@ -53,7 +51,22 @@ noexcept: false, attributes: [], }, - // Generation generation_of(...); + // Generation generation_of(role r, const void * addr) const noexcept; + { + name: "generation_of", + doc: [ + "generation to which pointer @p addr belongs, given role @p r;", + "sentinel if @p addr is not owned by collector", + ], + return_type: "Generation", + args: [ + {type: "role", name: "r"}, + {type: "const void *", name: "addr"}, + ], + const: true, + noexcept: true, + attributes: [], + }, ], nonconst_methods: [ // void alloc_copy(void * src) diff --git a/xo-alloc2/include/xo/alloc2/Generation.hpp b/xo-alloc2/include/xo/alloc2/Generation.hpp index 2c83485b..a311c606 100644 --- a/xo-alloc2/include/xo/alloc2/Generation.hpp +++ b/xo-alloc2/include/xo/alloc2/Generation.hpp @@ -16,7 +16,8 @@ namespace xo { /** @class generation * @brief type-safe generation number **/ - struct Generation { + class Generation { + public: using value_type = std::uint32_t; constexpr Generation() = default; diff --git a/xo-alloc2/include/xo/alloc2/gc/AGCObjectVisitor.hpp b/xo-alloc2/include/xo/alloc2/gc/AGCObjectVisitor.hpp index 71603d1a..df5d1f47 100644 --- a/xo-alloc2/include/xo/alloc2/gc/AGCObjectVisitor.hpp +++ b/xo-alloc2/include/xo/alloc2/gc/AGCObjectVisitor.hpp @@ -14,6 +14,8 @@ #pragma once // includes (via {facet_includes}) +#include +#include #include #include #include @@ -22,6 +24,7 @@ // see GCObject.hpp, also in xo-alloc2/ namespace xo { namespace mm { class AGCObject; }} namespace xo { namespace mm { class AllocInfo; }} +namespace xo { namespace mm { class Generation; }} namespace xo { namespace mm { @@ -58,6 +61,9 @@ public: /** allocation metadata for gc-aware data at address @p gco. @p gco must be the result of a call to collector's alloc() function **/ virtual AllocInfo alloc_info(Copaque data, void * addr) const = 0; + /** generation to which pointer @p addr belongs, given role @p r; +sentinel if @p addr is not owned by collector **/ + virtual Generation generation_of(Copaque data, role r, const void * addr) const noexcept = 0; // nonconst methods /** allocate copy of source object at address @p src. diff --git a/xo-alloc2/include/xo/alloc2/gc/IGCObjectVisitor_Any.hpp b/xo-alloc2/include/xo/alloc2/gc/IGCObjectVisitor_Any.hpp index 5e48ef43..7cb7f6d9 100644 --- a/xo-alloc2/include/xo/alloc2/gc/IGCObjectVisitor_Any.hpp +++ b/xo-alloc2/include/xo/alloc2/gc/IGCObjectVisitor_Any.hpp @@ -59,6 +59,7 @@ namespace mm { // const methods [[noreturn]] AllocInfo alloc_info(Copaque, void *) const override { _fatal(); } + [[noreturn]] Generation generation_of(Copaque, role, const void *) const noexcept override { _fatal(); } // nonconst methods [[noreturn]] void * alloc_copy(Opaque, std::byte *) const override; diff --git a/xo-alloc2/include/xo/alloc2/gc/IGCObjectVisitor_Xfer.hpp b/xo-alloc2/include/xo/alloc2/gc/IGCObjectVisitor_Xfer.hpp index 8daaee44..c457c557 100644 --- a/xo-alloc2/include/xo/alloc2/gc/IGCObjectVisitor_Xfer.hpp +++ b/xo-alloc2/include/xo/alloc2/gc/IGCObjectVisitor_Xfer.hpp @@ -13,6 +13,8 @@ #pragma once +#include +#include #include namespace xo { @@ -46,6 +48,9 @@ namespace mm { AllocInfo alloc_info(Copaque data, void * addr) const override { return I::alloc_info(_dcast(data), addr); } + Generation generation_of(Copaque data, role r, const void * addr) const noexcept override { + return I::generation_of(_dcast(data), r, addr); + } // non-const methods void * alloc_copy(Opaque data, std::byte * src) const override { diff --git a/xo-alloc2/include/xo/alloc2/gc/RGCObjectVisitor.hpp b/xo-alloc2/include/xo/alloc2/gc/RGCObjectVisitor.hpp index 461790a8..bba6756c 100644 --- a/xo-alloc2/include/xo/alloc2/gc/RGCObjectVisitor.hpp +++ b/xo-alloc2/include/xo/alloc2/gc/RGCObjectVisitor.hpp @@ -91,6 +91,9 @@ public: AllocInfo alloc_info(void * addr) const { return O::iface()->alloc_info(O::data(), addr); } + Generation generation_of(role r, const void * addr) const noexcept { + return O::iface()->generation_of(O::data(), r, addr); + } // non-const methods (still const in router!) void * alloc_copy(std::byte * src) { diff --git a/xo-arena/include/xo/arena/AllocInfo.hpp b/xo-arena/include/xo/arena/AllocInfo.hpp index 30113e46..599e0b78 100644 --- a/xo-arena/include/xo/arena/AllocInfo.hpp +++ b/xo-arena/include/xo/arena/AllocInfo.hpp @@ -17,7 +17,8 @@ namespace xo { * {@ref AAllocator::alloc, @ref AAllocator::alloc_super} * **/ - struct AllocInfo { + class AllocInfo { + public: /** @defgroup mm-allocinfo-traits **/ ///@{ diff --git a/xo-gc/include/xo/gc/detail/IGCObjectVisitor_DX1Collector.hpp b/xo-gc/include/xo/gc/detail/IGCObjectVisitor_DX1Collector.hpp index ce01500b..d1c09228 100644 --- a/xo-gc/include/xo/gc/detail/IGCObjectVisitor_DX1Collector.hpp +++ b/xo-gc/include/xo/gc/detail/IGCObjectVisitor_DX1Collector.hpp @@ -48,6 +48,9 @@ namespace xo { /** allocation metadata for gc-aware data at address @p gco. @p gco must be the result of a call to collector's alloc() function **/ static AllocInfo alloc_info(const DX1Collector & self, void * addr); + /** generation to which pointer @p addr belongs, given role @p r; +sentinel if @p addr is not owned by collector **/ + static Generation generation_of(const DX1Collector & self, role r, const void * addr) noexcept; // non-const methods /** allocate copy of source object at address @p src. diff --git a/xo-gc/src/gc/MutationLogStore.cpp b/xo-gc/src/gc/MutationLogStore.cpp index b96e2981..24cbf86c 100644 --- a/xo-gc/src/gc/MutationLogStore.cpp +++ b/xo-gc/src/gc/MutationLogStore.cpp @@ -376,8 +376,8 @@ namespace xo { /* here: mlog current */ - Generation parent_gen_to = gc->generation_of(role::to_space(), - from_entry.parent()); + Generation parent_gen_to = gc.generation_of(role::to_space(), + from_entry.parent()); if (parent_gen_to.is_sentinel()) { void * parent_fr = *from_entry.p_data(); @@ -393,8 +393,8 @@ namespace xo { // TODO: method on AllocInfo to streamline this void * parent_to = *(void **)parent_fr; - parent_gen_to = gc->generation_of(role::to_space(), - parent_to); + parent_gen_to = gc.generation_of(role::to_space(), + parent_to); parent_info = gc.alloc_info((std::byte *)parent_to); assert(!parent_gen_to.sentinel()); diff --git a/xo-gc/src/gc/facet/IGCObjectVisitor_DX1Collector.cpp b/xo-gc/src/gc/facet/IGCObjectVisitor_DX1Collector.cpp index 5dd9d3d6..129ba422 100644 --- a/xo-gc/src/gc/facet/IGCObjectVisitor_DX1Collector.cpp +++ b/xo-gc/src/gc/facet/IGCObjectVisitor_DX1Collector.cpp @@ -21,6 +21,12 @@ namespace xo { return self.alloc_info(addr); } + auto + IGCObjectVisitor_DX1Collector::generation_of(const DX1Collector & self, role r, const void * addr) noexcept -> Generation + { + return self.generation_of(r, addr); + } + auto IGCObjectVisitor_DX1Collector::alloc_copy(DX1Collector & self, std::byte * src) -> void * {