From c91fc4fbed9d3449b308c3595ca8e2cc9d3fde56 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 30 Mar 2026 14:51:51 -0400 Subject: [PATCH] xo-procedure2 stack: + report-gc-object-ages() primitive --- idl/Collector.json5 | 20 ++++++++++++++++++++ include/xo/alloc2/gc/ACollector.hpp | 6 ++++++ include/xo/alloc2/gc/ICollector_Any.hpp | 1 + include/xo/alloc2/gc/ICollector_Xfer.hpp | 3 +++ include/xo/alloc2/gc/RCollector.hpp | 3 +++ 5 files changed, 33 insertions(+) diff --git a/idl/Collector.json5 b/idl/Collector.json5 index 19c44907..97ca2ce0 100644 --- a/idl/Collector.json5 +++ b/idl/Collector.json5 @@ -155,6 +155,26 @@ noexcept: true, attributes: [], }, + // bool report_object_ages(obj report_mm, obj error_mm, obj * output); + { + name: "report_object_ages", + doc: [ + "Report gc object ages, at discretion of collector implementation.", + "Creates array of dictionaries using memory from @p report_mm.", + "Each dictionary has keys n-live and bytes, indexed by object age.", + "If unable to comply (e.g. oom), return runtime error allocated from @p error_mm.", + "Avoiding obj return type to avoid #include cycle", + ], + return_type: "bool", + args: [ + {type: "obj", name: "report_mm"}, + {type: "obj", name: "error_mm"}, + {type: "obj *", name: "output"}, + ], + const: true, + noexcept: true, + attributes: [], + }, ], nonconst_methods: [ // bool install_type(const AGCObject & iface) diff --git a/include/xo/alloc2/gc/ACollector.hpp b/include/xo/alloc2/gc/ACollector.hpp index e682222b..9fc4a583 100644 --- a/include/xo/alloc2/gc/ACollector.hpp +++ b/include/xo/alloc2/gc/ACollector.hpp @@ -83,6 +83,12 @@ Creates dictionary using memory from @p report_mm. If unable to comply (e.g. oom), return runtime error allocated from @p error_mm. Avoiding obj return type to avoid #include cycle **/ virtual bool report_object_types(Copaque data, obj report_mm, obj error_mm, obj * output) const noexcept = 0; + /** Report gc object ages, at discretion of collector implementation. +Creates array of dictionaries using memory from @p report_mm. +Each dictionary has keys n-live and bytes, indexed by object age. +If unable to comply (e.g. oom), return runtime error allocated from @p error_mm. +Avoiding obj return type to avoid #include cycle **/ + virtual bool report_object_ages(Copaque data, obj report_mm, obj error_mm, obj * output) const noexcept = 0; // nonconst methods /** install interface @p iface for representation with typeseq @p tseq diff --git a/include/xo/alloc2/gc/ICollector_Any.hpp b/include/xo/alloc2/gc/ICollector_Any.hpp index 3847243b..7d36415d 100644 --- a/include/xo/alloc2/gc/ICollector_Any.hpp +++ b/include/xo/alloc2/gc/ICollector_Any.hpp @@ -67,6 +67,7 @@ namespace mm { [[noreturn]] bool is_type_installed(Copaque, typeseq) const noexcept override { _fatal(); } [[noreturn]] bool report_statistics(Copaque, obj, obj, obj *) const noexcept override { _fatal(); } [[noreturn]] bool report_object_types(Copaque, obj, obj, obj *) const noexcept override { _fatal(); } + [[noreturn]] bool report_object_ages(Copaque, obj, obj, obj *) const noexcept override { _fatal(); } // nonconst methods [[noreturn]] bool install_type(Opaque, const AGCObject &) override; diff --git a/include/xo/alloc2/gc/ICollector_Xfer.hpp b/include/xo/alloc2/gc/ICollector_Xfer.hpp index 4293817c..bce805bc 100644 --- a/include/xo/alloc2/gc/ICollector_Xfer.hpp +++ b/include/xo/alloc2/gc/ICollector_Xfer.hpp @@ -70,6 +70,9 @@ namespace mm { bool report_object_types(Copaque data, obj report_mm, obj error_mm, obj * output) const noexcept override { return I::report_object_types(_dcast(data), report_mm, error_mm, output); } + bool report_object_ages(Copaque data, obj report_mm, obj error_mm, obj * output) const noexcept override { + return I::report_object_ages(_dcast(data), report_mm, error_mm, output); + } // non-const methods bool install_type(Opaque data, const AGCObject & iface) override { diff --git a/include/xo/alloc2/gc/RCollector.hpp b/include/xo/alloc2/gc/RCollector.hpp index 47dac461..4580f059 100644 --- a/include/xo/alloc2/gc/RCollector.hpp +++ b/include/xo/alloc2/gc/RCollector.hpp @@ -103,6 +103,9 @@ public: bool report_object_types(obj report_mm, obj error_mm, obj * output) const noexcept { return O::iface()->report_object_types(O::data(), report_mm, error_mm, output); } + bool report_object_ages(obj report_mm, obj error_mm, obj * output) const noexcept { + return O::iface()->report_object_ages(O::data(), report_mm, error_mm, output); + } // non-const methods (still const in router!) bool install_type(const AGCObject & iface) {