xo-gc stack: + ACollector.shallow_copy()

This commit is contained in:
Roland Conybeare 2026-04-03 18:33:09 -04:00
commit 116dfa2306
8 changed files with 76 additions and 2 deletions

View file

@ -267,6 +267,22 @@
noexcept: false,
attributes: [],
},
// void alloc_copy(void * src)
{
name: "alloc_copy",
doc: [
"allocate copy of source object at address @p src.",
"Source must be owned by this collector.",
"Increments object age"
],
return_type: "void *",
args: [
{type: "std::byte *", name: "src"},
],
const: false,
noexcept: false,
attributes: [],
},
// void forward_inplace(AGCObject * lhs_iface, void ** lhs_data);
{
name: "forward_inplace",
@ -288,7 +304,23 @@
},
],
router_facet_explicit_content: [
"/** forward op in place. Defined in GCObject.hpp to avoid #include cycle **/",
"/** convenience template for gc object copy **/",
"template <typename T>",
"void * alloc_copy_for(const T * src) noexcept {",
" return O::iface()->alloc_copy(O::data(), (std::byte *)const_cast<T *>(src));",
"}",
"",
"/** convenience template for move-constructible T (this is common) **/",
"template <typename T>",
"void * std_copy_for(const T * src) noexcept {",
" void * mem = this->alloc_copy_for(src);",
" if (mem) {",
" new (mem) T(std::move(*src));",
" }",
" return (T *)mem;",
"}",
"",
"/** forward faceted object pointer in place. Defined in GCObject.hpp to avoid #include cycle **/",
"template <typename DRepr>",
"void forward_inplace(obj<AGCObject,DRepr> * p_obj);",
"",

View file

@ -119,6 +119,10 @@ Return false if installation fails (e.g. memory exhausted) **/
Require: gc not in progress **/
virtual void assign_member(Opaque data, void * parent, obj<AGCObject> * p_lhs, obj<AGCObject> & rhs) = 0;
/** 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;
/** evacuate @p *lhs, that refers to state with interface @p lhs_iface,
to collector @p d's to-space. Replace *lhs_data with forwarding pointer

View file

@ -75,6 +75,7 @@ namespace mm {
[[noreturn]] void remove_gc_root_poly(Opaque, obj<AGCObject> *) override;
[[noreturn]] void request_gc(Opaque, Generation) override;
[[noreturn]] void assign_member(Opaque, void *, obj<AGCObject> *, obj<AGCObject> &) override;
[[noreturn]] void * alloc_copy(Opaque, std::byte *) override;
[[noreturn]] void forward_inplace(Opaque, AGCObject *, void **) override;
///@}

View file

@ -90,6 +90,9 @@ namespace mm {
void assign_member(Opaque data, void * parent, obj<AGCObject> * p_lhs, obj<AGCObject> & rhs) override {
return I::assign_member(_dcast(data), parent, p_lhs, rhs);
}
void * alloc_copy(Opaque data, std::byte * src) override {
return I::alloc_copy(_dcast(data), src);
}
void forward_inplace(Opaque data, AGCObject * lhs_iface, void ** lhs_data) override {
return I::forward_inplace(_dcast(data), lhs_iface, lhs_data);
}

View file

@ -47,7 +47,23 @@ public:
///@{
// explicit injected content
/** forward op in place. Defined in GCObject.hpp to avoid #include cycle **/
/** convenience template for gc object copy **/
template <typename T>
void * alloc_copy_for(const T * src) noexcept {
return O::iface()->alloc_copy(O::data(), (std::byte *)const_cast<T *>(src));
}
/** convenience template for move-constructible T (this is common) **/
template <typename T>
void * std_copy_for(const T * src) noexcept {
void * mem = this->alloc_copy_for(src);
if (mem) {
new (mem) T(std::move(*src));
}
return (T *)mem;
}
/** forward faceted object pointer in place. Defined in GCObject.hpp to avoid #include cycle **/
template <typename DRepr>
void forward_inplace(obj<AGCObject,DRepr> * p_obj);
@ -123,6 +139,9 @@ public:
void assign_member(void * parent, obj<AGCObject> * p_lhs, obj<AGCObject> & rhs) {
return O::iface()->assign_member(O::data(), parent, p_lhs, rhs);
}
void * alloc_copy(std::byte * src) {
return O::iface()->alloc_copy(O::data(), src);
}
void forward_inplace(AGCObject * lhs_iface, void ** lhs_data) {
return O::iface()->forward_inplace(O::data(), lhs_iface, lhs_data);
}

View file

@ -65,6 +65,12 @@ ICollector_Any::assign_member(Opaque, void *, obj<AGCObject> *, obj<AGCObject> &
_fatal();
}
auto
ICollector_Any::alloc_copy(Opaque, std::byte *) -> void *
{
_fatal();
}
auto
ICollector_Any::forward_inplace(Opaque, AGCObject *, void **) -> void
{