xo-gc stack: + request-gc-statistics() primitive
1. xo-gc now depends on xo-object2. 2. use genfacet for ICollector_DX1Collector 3. moves xo-gc utest previously in xo-object2 to more natural location in xo-gc/
This commit is contained in:
parent
7916971dc1
commit
f7c269a505
13 changed files with 74 additions and 11 deletions
|
|
@ -61,6 +61,15 @@
|
|||
noexcept: true,
|
||||
attributes: [],
|
||||
},
|
||||
{
|
||||
name: "error_allocator",
|
||||
doc: [ "last-resort allocator for erros. e.g. regular allocator exhausted" ],
|
||||
return_type: "obj<AAllocator>",
|
||||
args: [],
|
||||
const: true,
|
||||
noexcept: true,
|
||||
attributes: [],
|
||||
},
|
||||
{
|
||||
name: "stringtable",
|
||||
doc: [ "stringtable for unique symbols" ],
|
||||
|
|
|
|||
|
|
@ -23,16 +23,19 @@ namespace xo {
|
|||
using MemorySizeVisitor = xo::mm::MemorySizeVisitor;
|
||||
|
||||
public:
|
||||
DSimpleRcx(obj<AAllocator> mm, StringTable * st)
|
||||
: allocator_{mm}, stringtable_{st} {}
|
||||
DSimpleRcx(obj<AAllocator> mm, obj<AAllocator> error_mm, StringTable * st)
|
||||
: allocator_{mm}, error_allocator_{error_mm},
|
||||
stringtable_{st} {}
|
||||
|
||||
obj<AAllocator> allocator() const noexcept { return allocator_; }
|
||||
obj<ACollector> collector() const noexcept;
|
||||
obj<AAllocator> error_allocator() const noexcept { return error_allocator_; }
|
||||
StringTable * stringtable() const noexcept { return stringtable_; }
|
||||
void visit_pools(const MemorySizeVisitor & visitor) const;
|
||||
|
||||
private:
|
||||
obj<AAllocator> allocator_;
|
||||
obj<AAllocator> error_allocator_;
|
||||
StringTable * stringtable_ = nullptr;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "Primitive_gco_0.hpp"
|
||||
#include "Primitive_gco_1_gco.hpp"
|
||||
|
||||
namespace xo {
|
||||
|
|
@ -18,6 +19,10 @@ namespace xo {
|
|||
using AAllocator = xo::mm::AAllocator;
|
||||
|
||||
public:
|
||||
/** create primitive: report gc statistics **/
|
||||
static DPrimitive_gco_0 * make_report_gc_statistics_pm(obj<AAllocator> mm,
|
||||
StringTable * stbl);
|
||||
|
||||
/** create primitive: request collection **/
|
||||
static DPrimitive_gco_1_gco * make_request_gc_pm(obj<AAllocator> mm,
|
||||
StringTable * stbl);
|
||||
|
|
|
|||
|
|
@ -47,6 +47,11 @@ public:
|
|||
/** @defgroup scm-procedure-methods **/
|
||||
///@{
|
||||
// const methods
|
||||
/** An uninitialized AProcedure instance will have zero vtable pointer (per {linux,osx} abi).
|
||||
* Use case for this is narrow. We go to some lengths to avoid null vtable pointers. For example
|
||||
* obj<AFacet> will have non-null vtable (via IFacet_Any) with all methods terminating.
|
||||
**/
|
||||
bool _has_null_vptr() const noexcept { return *reinterpret_cast<const void * const *>(this) == nullptr; }
|
||||
/** RTTI: unique id# for actual runtime data representation **/
|
||||
virtual typeseq _typeseq() const noexcept = 0;
|
||||
/** destroy instance @p d; calls c++ dtor only for actual runtime type; does not recover memory **/
|
||||
|
|
|
|||
|
|
@ -51,6 +51,11 @@ public:
|
|||
/** @defgroup scm-runtimecontext-methods **/
|
||||
///@{
|
||||
// const methods
|
||||
/** An uninitialized ARuntimeContext instance will have zero vtable pointer (per {linux,osx} abi).
|
||||
* Use case for this is narrow. We go to some lengths to avoid null vtable pointers. For example
|
||||
* obj<AFacet> will have non-null vtable (via IFacet_Any) with all methods terminating.
|
||||
**/
|
||||
bool _has_null_vptr() const noexcept { return *reinterpret_cast<const void * const *>(this) == nullptr; }
|
||||
/** RTTI: unique id# for actual runtime data representation **/
|
||||
virtual typeseq _typeseq() const noexcept = 0;
|
||||
/** destroy instance @p d; calls c++ dtor only for actual runtime type; does not recover memory **/
|
||||
|
|
@ -59,6 +64,8 @@ public:
|
|||
virtual obj<AAllocator> allocator(Copaque data) const noexcept = 0;
|
||||
/** collector facet for allocator. If non-null, same data pointer as allocator **/
|
||||
virtual obj<ACollector> collector(Copaque data) const noexcept = 0;
|
||||
/** last-resort allocator for erros. e.g. regular allocator exhausted **/
|
||||
virtual obj<AAllocator> error_allocator(Copaque data) const noexcept = 0;
|
||||
/** stringtable for unique symbols **/
|
||||
virtual StringTable * stringtable(Copaque data) const noexcept = 0;
|
||||
/** invoke visitor for each distinct memory pool **/
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ namespace scm {
|
|||
// const methods
|
||||
[[noreturn]] obj<AAllocator> allocator(Copaque) const noexcept override { _fatal(); }
|
||||
[[noreturn]] obj<ACollector> collector(Copaque) const noexcept override { _fatal(); }
|
||||
[[noreturn]] obj<AAllocator> error_allocator(Copaque) const noexcept override { _fatal(); }
|
||||
[[noreturn]] StringTable * stringtable(Copaque) const noexcept override { _fatal(); }
|
||||
[[noreturn]] void visit_pools(Copaque, MemorySizeVisitor) const override { _fatal(); }
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ namespace xo {
|
|||
static obj<AAllocator> allocator(const DSimpleRcx & self) noexcept;
|
||||
/** collector facet for allocator. If non-null, same data pointer as allocator **/
|
||||
static obj<ACollector> collector(const DSimpleRcx & self) noexcept;
|
||||
/** last-resort allocator for erros. e.g. regular allocator exhausted **/
|
||||
static obj<AAllocator> error_allocator(const DSimpleRcx & self) noexcept;
|
||||
/** stringtable for unique symbols **/
|
||||
static StringTable * stringtable(const DSimpleRcx & self) noexcept;
|
||||
/** invoke visitor for each distinct memory pool **/
|
||||
|
|
|
|||
|
|
@ -54,6 +54,9 @@ namespace scm {
|
|||
obj<ACollector> collector(Copaque data) const noexcept override {
|
||||
return I::collector(_dcast(data));
|
||||
}
|
||||
obj<AAllocator> error_allocator(Copaque data) const noexcept override {
|
||||
return I::error_allocator(_dcast(data));
|
||||
}
|
||||
StringTable * stringtable(Copaque data) const noexcept override {
|
||||
return I::stringtable(_dcast(data));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,6 +61,9 @@ public:
|
|||
obj<ACollector> collector() const noexcept {
|
||||
return O::iface()->collector(O::data());
|
||||
}
|
||||
obj<AAllocator> error_allocator() const noexcept {
|
||||
return O::iface()->error_allocator(O::data());
|
||||
}
|
||||
StringTable * stringtable() const noexcept {
|
||||
return O::iface()->stringtable(O::data());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,23 +21,35 @@ namespace xo {
|
|||
|
||||
// ----- report-gc-status -----
|
||||
|
||||
#ifdef NOT_YET
|
||||
obj<AGCObject>
|
||||
xfer_report_gc_status(obj<ARuntimeContext> rcx)
|
||||
xfer_report_gc_statistics(obj<ARuntimeContext> rcx)
|
||||
{
|
||||
bool have_gc = false;
|
||||
|
||||
if (rcx.collector()) {
|
||||
// status currently only implemented for X1 collector
|
||||
|
||||
auto gc = obj<ACollector,DX1Collector>::from(rcx.collector());
|
||||
|
||||
obj<AGCObject> stats;
|
||||
bool ok = rcx.collector().report_statistics(rcx.allocator(),
|
||||
rcx.error_allocator(),
|
||||
&stats);
|
||||
|
||||
if (ok && stats)
|
||||
return stats;
|
||||
}
|
||||
|
||||
return DBoolean::box(rcx.allocator(), false);
|
||||
}
|
||||
#endif
|
||||
|
||||
DPrimitive_gco_0 *
|
||||
GcPrimitives::make_report_gc_statistics_pm(obj<AAllocator> mm,
|
||||
StringTable * stbl)
|
||||
{
|
||||
(void)stbl;
|
||||
|
||||
auto any_ty = DAtomicType::make(mm, Metatype::t_any());
|
||||
auto pm_ty = obj<AType,DFunctionType>(DFunctionType::_make(mm, any_ty));
|
||||
|
||||
return DPrimitive_gco_0::_make(mm, "report-gc-statistics", pm_ty, &xfer_report_gc_statistics);
|
||||
}
|
||||
|
||||
// ----- request-gc -----
|
||||
|
||||
|
|
|
|||
|
|
@ -130,6 +130,13 @@ namespace xo {
|
|||
ObjectPrimitives::make_fn_n_args_pm(mm, stbl),
|
||||
flags & InstallFlags::f_generalpurpose));
|
||||
|
||||
// ----- gc primitives -----
|
||||
|
||||
ok = ok & (PrimitiveRegistry::install_aux
|
||||
(sink,
|
||||
GcPrimitives::make_report_gc_statistics_pm(mm, stbl),
|
||||
flags & InstallFlags::f_generalpurpose));
|
||||
|
||||
ok = ok & (PrimitiveRegistry::install_aux
|
||||
(sink,
|
||||
GcPrimitives::make_request_gc_pm(mm, stbl),
|
||||
|
|
|
|||
|
|
@ -27,6 +27,12 @@ namespace xo {
|
|||
return self.collector();
|
||||
}
|
||||
|
||||
auto
|
||||
IRuntimeContext_DSimpleRcx::error_allocator(const DSimpleRcx & self) noexcept -> obj<AAllocator>
|
||||
{
|
||||
return self.error_allocator();
|
||||
}
|
||||
|
||||
auto
|
||||
IRuntimeContext_DSimpleRcx::stringtable(const DSimpleRcx & self) noexcept -> StringTable *
|
||||
{
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ namespace xo {
|
|||
auto stbl = StringTable(1024 /*hint_max_capacity*/,
|
||||
false /*!debug_flag*/);
|
||||
|
||||
DSimpleRcx rcx(alloc, &stbl);
|
||||
DSimpleRcx rcx(alloc, alloc, &stbl);
|
||||
|
||||
REQUIRE((void*)rcx.allocator().data() == (void*)alloc.data());
|
||||
REQUIRE(rcx.stringtable() == &stbl);
|
||||
|
|
@ -54,7 +54,7 @@ namespace xo {
|
|||
auto stbl = StringTable(1024 /*hint_max_capacity*/,
|
||||
false /*!debug_flag*/);
|
||||
|
||||
DSimpleRcx rcx(alloc, &stbl);
|
||||
DSimpleRcx rcx(alloc, alloc, &stbl);
|
||||
obj<ARuntimeContext> rcx_obj = with_facet<ARuntimeContext>::mkobj(&rcx);
|
||||
|
||||
// verify we can recover allocator from obj<ARuntimeContext>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue