xo-alloc2 xo-gc: assorted utest-guided cleanup ++ coverage
This commit is contained in:
parent
d0496a3245
commit
08df9a5635
6 changed files with 57 additions and 16 deletions
11
include/xo/gc/X1CollectorIterator.hpp
Normal file
11
include/xo/gc/X1CollectorIterator.hpp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/** @file X1CollectorIterator.hpp
|
||||
*
|
||||
* @author Roland Conybeare, May 2026
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DX1CollectorIterator.hpp"
|
||||
#include "detail/IAllocIterator_DX1CollectorIterator.hpp"
|
||||
|
||||
/* end X1CollectorIterator.hpp */
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "setup_gc.hpp"
|
||||
#include "X1Collector.hpp"
|
||||
#include "X1CollectorIterator.hpp"
|
||||
#include "GCObjectStoreVisitor.hpp"
|
||||
#include <xo/facet/FacetRegistry.hpp>
|
||||
#include <xo/indentlog/scope.hpp>
|
||||
|
|
@ -25,10 +26,12 @@ namespace xo {
|
|||
|
||||
FacetRegistry::register_impl<AAllocator, DX1Collector>();
|
||||
FacetRegistry::register_impl<ACollector, DX1Collector>();
|
||||
FacetRegistry::register_impl<AAllocIterator, DX1CollectorIterator>();
|
||||
|
||||
FacetRegistry::register_impl<AGCObjectVisitor, DGCObjectStoreVisitor>();
|
||||
|
||||
log && log(xtag("DX1Collector.tseq", typeseq::id<DX1Collector>()));
|
||||
log && log(xtag("DX1CollectorIterator.tseq", typeseq::id<DX1CollectorIterator>()));
|
||||
log && log(xtag("DGCObjectStoreVisitor.tseq", typeseq::id<DGCObjectStoreVisitor>()));
|
||||
|
||||
log && log(xtag("ACollector.tseq", typeseq::id<ACollector>()));
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ namespace xo {
|
|||
using xo::mm::AllocHeader;
|
||||
using xo::mm::Generation;
|
||||
using xo::mm::c_max_generation;
|
||||
using xo::facet::DVariantPlaceholder;
|
||||
using xo::facet::with_facet;
|
||||
using xo::reflect::typeseq;
|
||||
using xo::scope;
|
||||
|
|
@ -60,7 +61,7 @@ namespace xo {
|
|||
REQUIRE(!gc1);
|
||||
REQUIRE(gc1.iface() != nullptr);
|
||||
REQUIRE(gc1.data() == nullptr);
|
||||
REQUIRE(gc1._typeseq() == typeseq::id<ICollector_Any>());
|
||||
REQUIRE(gc1._typeseq() == typeseq::id<DVariantPlaceholder>());
|
||||
}
|
||||
|
||||
TEST_CASE("DX1Collector-1", "[alloc2][gc][DX1Collector]")
|
||||
|
|
@ -187,6 +188,15 @@ namespace xo {
|
|||
{
|
||||
scope log(XO_DEBUG(false), "DX1Collector alloc test");
|
||||
|
||||
constexpr uint32_t c_n_alloc = 25;
|
||||
constexpr uint32_t c_reserved_z = 4*1024*1024;
|
||||
constexpr uint32_t c_max_alloc = c_reserved_z / c_n_alloc;
|
||||
// allowance for per-alloc overhead
|
||||
constexpr uint32_t c_max_alloc_payload = c_max_alloc - 32;
|
||||
|
||||
static_assert(c_max_alloc > 0);
|
||||
static_assert(c_max_alloc_payload < c_max_alloc);
|
||||
|
||||
ArenaConfig arena_cfg = { .name_ = "_test_unused",
|
||||
.size_ = 4*1024*1024,
|
||||
.store_header_flag_ = true,
|
||||
|
|
@ -226,22 +236,31 @@ namespace xo {
|
|||
auto rng = rng::xoshiro256ss(seed);
|
||||
|
||||
bool catch_flag = false;
|
||||
REQUIRE(utest::AllocUtil::random_allocs(25, catch_flag, &rng, x1alloc));
|
||||
REQUIRE(utest::AllocUtil::random_allocs(c_n_alloc, c_max_alloc_payload,
|
||||
catch_flag, &rng, x1alloc));
|
||||
}
|
||||
|
||||
TEST_CASE("collector-x1-alloc2", "[alloc2][gc]")
|
||||
{
|
||||
scope log(XO_DEBUG(false),
|
||||
constexpr bool c_debug_flag = true;
|
||||
scope log(XO_DEBUG(c_debug_flag),
|
||||
"DX1Collector alloc test2");
|
||||
|
||||
ArenaConfig arena_cfg = { .name_ = "_test_unused",
|
||||
.size_ = 4*1024*1024,
|
||||
.store_header_flag_ = true,
|
||||
.header_ = AllocHeaderConfig(8 /*guard_z*/,
|
||||
0xfd /*guard-byte*/,
|
||||
0 /*tseq-bits*/,
|
||||
0 /*age-bits*/,
|
||||
16 /*size-bits*/),
|
||||
constexpr uint32_t c_n_alloc = 25;
|
||||
constexpr uint32_t c_reserved_z = 4*1024*1024;
|
||||
constexpr uint32_t c_max_alloc = c_reserved_z / c_n_alloc;
|
||||
// allowance for per-alloc overhead
|
||||
constexpr uint32_t c_max_alloc_payload = c_max_alloc - 32;
|
||||
|
||||
ArenaConfig arena_cfg = {
|
||||
.name_ = "_test_unused",
|
||||
.size_ = c_reserved_z,
|
||||
.store_header_flag_ = true,
|
||||
.header_ = AllocHeaderConfig(8 /*guard_z*/,
|
||||
0xfd /*guard-byte*/,
|
||||
0 /*tseq-bits*/,
|
||||
0 /*age-bits*/,
|
||||
16 /*size-bits*/),
|
||||
};
|
||||
|
||||
/* collector with one generation collapses to a non-generational copying collector */
|
||||
|
|
@ -277,7 +296,8 @@ namespace xo {
|
|||
|
||||
// these are not gc-aware objects.
|
||||
// just testing ability to work as a low-level allocator
|
||||
REQUIRE(utest::AllocUtil::random_allocs(25, false, &rng, x1alloc));
|
||||
REQUIRE(utest::AllocUtil::random_allocs(c_n_alloc, c_max_alloc_payload,
|
||||
c_debug_flag, &rng, x1alloc));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
|
|||
|
|
@ -179,8 +179,8 @@ namespace xo {
|
|||
obj<AAllocIterator> ix = range.begin();
|
||||
obj<AAllocIterator> end_ix = range.end();
|
||||
|
||||
REQUIRE(ix._typeseq() == typeseq::id<DArenaIterator>());
|
||||
REQUIRE(end_ix._typeseq() == typeseq::id<DArenaIterator>());
|
||||
REQUIRE(ix._typeseq() == typeseq::id<DX1CollectorIterator>());
|
||||
REQUIRE(end_ix._typeseq() == typeseq::id<DX1CollectorIterator>());
|
||||
REQUIRE(ix.iface());
|
||||
REQUIRE(ix.data());
|
||||
REQUIRE(end_ix.iface());
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ namespace utest {
|
|||
|
||||
bool
|
||||
AllocUtil::random_allocs(uint32_t n_alloc,
|
||||
uint32_t max_alloc_z,
|
||||
bool catch_flag,
|
||||
xoshiro256ss * p_rgen,
|
||||
obj<AAllocator> mm)
|
||||
|
|
@ -64,6 +65,8 @@ namespace utest {
|
|||
double si = ngen(*p_rgen);
|
||||
double zi = ::pow(2.0, si);
|
||||
std::size_t z = ::ceil(zi);
|
||||
if (z > max_alloc_z)
|
||||
z = max_alloc_z;
|
||||
|
||||
bool ok_flag = true;
|
||||
|
||||
|
|
@ -132,7 +135,7 @@ namespace utest {
|
|||
for (const byte * p = info.guard_lo().first;
|
||||
p != info.guard_lo().second; ++p)
|
||||
{
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, (char)*p == info.guard_byte());
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, (uint8_t)*p == info.guard_byte());
|
||||
}
|
||||
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag,
|
||||
|
|
@ -146,7 +149,7 @@ namespace utest {
|
|||
for (const byte * p = info.guard_hi().first;
|
||||
p != info.guard_hi().second; ++p)
|
||||
{
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, (char)*p == info.guard_byte());
|
||||
REQUIRE_ORFAIL(ok_flag, catch_flag, (uint8_t)*p == info.guard_byte());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -34,8 +34,12 @@ namespace utest {
|
|||
|
||||
/** generate a random sequence of allocations.
|
||||
* verify allocator behavior
|
||||
*
|
||||
* Will not alloc more than n_alloc * max_alloc_z bytes
|
||||
* (not counting allocator overhead)
|
||||
**/
|
||||
static bool random_allocs(std::uint32_t n_alloc,
|
||||
std::uint32_t max_alloc_z,
|
||||
bool catch_flag,
|
||||
xo::rng::xoshiro256ss * p_rgen,
|
||||
xo::facet::obj<AAllocator> alloc);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue