diff --git a/idl/GCObjectVisitor.json5 b/idl/GCObjectVisitor.json5 index efe14a7..ce7efdc 100644 --- a/idl/GCObjectVisitor.json5 +++ b/idl/GCObjectVisitor.json5 @@ -4,6 +4,7 @@ output_hpp_dir: "include/xo/alloc2", output_impl_subdir: "gc", includes: [ + "", // "", // "", // "", @@ -18,6 +19,7 @@ pretext: [ "// see GCObject.hpp, also in xo-alloc2/", "namespace xo { namespace mm { class AGCObject; }}", + "namespace xo { namespace mm { class AllocInfo; }}", ], facet: "GCObjectVisitor", detail_subdir: "gc", @@ -45,16 +47,21 @@ // }, ], const_methods: [ - // size_type shallow_size() const noexcept -// { -// name: "shallow_size", -// doc: ["memory consumption for this instance"], -// return_type: "size_type", -// args: [], -// const: true, -// noexcept: true, -// attributes: [], -// }, + // AllocInfo alloc_info(void * gco); + { + name: "alloc_info", + doc: [ + "allocation metadata for gc-aware data at address @p gco.", + "@p gco must be the result of a call to collector's alloc() function", + ], + return_type: "AllocInfo", + args: [ + {type: "void *", name: "addr"}, + ], + const: true, + noexcept: false, + attributes: [], + }, ], nonconst_methods: [ // void alloc_copy(void * src) @@ -69,7 +76,7 @@ args: [ {type: "std::byte *", name: "src"}, ], - const: false, + const: true, // refers to interface. noexcept: false, attributes: [], }, diff --git a/include/xo/alloc2/gc/AGCObjectVisitor.hpp b/include/xo/alloc2/gc/AGCObjectVisitor.hpp index efedbfe..71603d1 100644 --- a/include/xo/alloc2/gc/AGCObjectVisitor.hpp +++ b/include/xo/alloc2/gc/AGCObjectVisitor.hpp @@ -14,12 +14,14 @@ #pragma once // includes (via {facet_includes}) +#include #include #include #include // see GCObject.hpp, also in xo-alloc2/ namespace xo { namespace mm { class AGCObject; }} +namespace xo { namespace mm { class AllocInfo; }} namespace xo { namespace mm { @@ -53,12 +55,15 @@ public: virtual typeseq _typeseq() const noexcept = 0; /** destroy instance @p d; calls c++ dtor only for actual runtime type; does not recover memory **/ virtual void _drop(Opaque d) const noexcept = 0; + /** 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; // nonconst methods /** allocate copy of source object at address @p src. Source must be owned by this collector. Increments object age **/ - virtual void * alloc_copy(Opaque data, std::byte * src) = 0; + virtual void * alloc_copy(Opaque data, std::byte * src) const = 0; /** visit child of a gc-aware object. May update child in-place! **/ virtual void visit_child(Opaque data, AGCObject * iface, void ** pp_data) const noexcept = 0; ///@} diff --git a/include/xo/alloc2/gc/IGCObjectVisitor_Any.hpp b/include/xo/alloc2/gc/IGCObjectVisitor_Any.hpp index 7297239..5e48ef4 100644 --- a/include/xo/alloc2/gc/IGCObjectVisitor_Any.hpp +++ b/include/xo/alloc2/gc/IGCObjectVisitor_Any.hpp @@ -58,9 +58,10 @@ namespace mm { [[noreturn]] void _drop(Opaque) const noexcept override { _fatal(); } // const methods + [[noreturn]] AllocInfo alloc_info(Copaque, void *) const override { _fatal(); } // nonconst methods - [[noreturn]] void * alloc_copy(Opaque, std::byte *) override; + [[noreturn]] void * alloc_copy(Opaque, std::byte *) const override; [[noreturn]] void visit_child(Opaque, AGCObject *, void **) const noexcept override; ///@} diff --git a/include/xo/alloc2/gc/IGCObjectVisitor_Xfer.hpp b/include/xo/alloc2/gc/IGCObjectVisitor_Xfer.hpp index 2786ed4..8daaee4 100644 --- a/include/xo/alloc2/gc/IGCObjectVisitor_Xfer.hpp +++ b/include/xo/alloc2/gc/IGCObjectVisitor_Xfer.hpp @@ -13,6 +13,7 @@ #pragma once +#include namespace xo { namespace mm { @@ -42,9 +43,12 @@ namespace mm { void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); } // const methods + AllocInfo alloc_info(Copaque data, void * addr) const override { + return I::alloc_info(_dcast(data), addr); + } // non-const methods - void * alloc_copy(Opaque data, std::byte * src) override { + void * alloc_copy(Opaque data, std::byte * src) const override { return I::alloc_copy(_dcast(data), src); } void visit_child(Opaque data, AGCObject * iface, void ** pp_data) const noexcept override { diff --git a/include/xo/alloc2/gc/RGCObjectVisitor.hpp b/include/xo/alloc2/gc/RGCObjectVisitor.hpp index 0b120a8..461790a 100644 --- a/include/xo/alloc2/gc/RGCObjectVisitor.hpp +++ b/include/xo/alloc2/gc/RGCObjectVisitor.hpp @@ -88,6 +88,9 @@ public: void _drop() const noexcept { O::iface()->_drop(O::data()); } // const methods + AllocInfo alloc_info(void * addr) const { + return O::iface()->alloc_info(O::data(), addr); + } // non-const methods (still const in router!) void * alloc_copy(std::byte * src) { diff --git a/src/alloc2/facet/IGCObjectVisitor_Any.cpp b/src/alloc2/facet/IGCObjectVisitor_Any.cpp index e60cc31..0946acd 100644 --- a/src/alloc2/facet/IGCObjectVisitor_Any.cpp +++ b/src/alloc2/facet/IGCObjectVisitor_Any.cpp @@ -36,7 +36,7 @@ IGCObjectVisitor_Any::_valid // nonconst methods auto -IGCObjectVisitor_Any::alloc_copy(Opaque, std::byte *) -> void * +IGCObjectVisitor_Any::alloc_copy(Opaque, std::byte *) const -> void * { _fatal(); }