xo-object2: obj<ACollector> argument to DArray::push_back()

This commit is contained in:
Roland Conybeare 2026-04-28 23:17:00 -04:00
commit a845bc17f3
5 changed files with 210 additions and 13 deletions

View file

@ -7,12 +7,15 @@
* see xo-object2/utest
**/
#include <xo/alloc2/Allocator.hpp>
#include "Collector.hpp"
//#include <xo/alloc2/Allocator.hpp>
#include "random_allocs.hpp"
#include "detail/ICollector_DX1Collector.hpp"
#include "detail/IAllocator_DX1Collector.hpp"
//#include "gc/DX1Collector.hpp"
#include <xo/gc/X1Collector.hpp>
#include <xo/object2/Array.hpp>
#include <xo/object2/List.hpp>
#include <xo/object2/Integer.hpp>
//#include "detail/ICollector_DX1Collector.hpp"
//#include "detail/IAllocator_DX1Collector.hpp"
#include <xo/alloc2/Allocator.hpp>
#include <xo/randomgen/xoshiro256.hpp>
#include <xo/randomgen/random_seed.hpp>
#include <xo/indentlog/scope.hpp>
@ -21,10 +24,15 @@
#include <catch2/catch.hpp>
namespace xo {
using xo::scm::DList;
using xo::scm::DArray;
using xo::scm::DInteger;
using xo::mm::AAllocator;
using xo::mm::ACollector;
using xo::mm::AGCObject;
using xo::mm::X1CollectorConfig;
using xo::mm::DX1Collector;
using xo::mm::Role;
using xo::mm::ArenaConfig;
using xo::mm::AllocHeaderConfig;
using xo::mm::Generation;
@ -263,8 +271,163 @@ namespace xo {
auto rng = rng::xoshiro256ss(seed);
// 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));
}
namespace {
class Testcase {
public:
Testcase(uint32_t ng, uint32_t ns, size_t gcz, uint32_t otz, bool dbg_flag)
: n_gen_{ng},
n_survive_{ns},
gc_halfspace_z_{gcz},
object_type_z_{otz},
debug_flag_{dbg_flag}
{}
public:
/** number of generations in gco store **/
uint32_t n_gen_ = 0;
/** promote to next gen on surviving this number of gc cycles **/
uint32_t n_survive_ = 0;
/** size of each generations' half-space, in bytes **/
size_t gc_halfspace_z_ = 0;
/** storage for object type array, in bytes
* one 8-byte facet pointer per type
**/
uint32_t object_type_z_;
#ifdef NOT_YET
/** size for error output arena **/
size_t error_size_ = 0;
#endif
/** true to enable debug output for this test case **/
bool debug_flag_ = false;
};
class X1Fixture {
public:
explicit X1Fixture(uint32_t i_tc, const Testcase & tc);
#ifdef NOT_IN_USE
DArena error_arena_;
#endif
DX1Collector gc_;
};
X1Fixture::X1Fixture(uint32_t i_tc, const Testcase & tc)
: gc_(X1CollectorConfig()
.with_name("collector-x1-gc-" + std::to_string(i_tc))
.with_n_gen(tc.n_gen_)
.with_n_survive(tc.n_survive_)
.with_size(tc.gc_halfspace_z_)
.with_debug_flag(tc.debug_flag_))
{}
# define nil nullptr
# define T true
# define F false
static std::vector<Testcase> s_testcase_v = {
/**
* debug_flag
* object_type_z |
* gc_halfspace_z | |
* n_survive | | |
* n_gen | | | |
* v v v v v
**/
Testcase(1, 2, 16 * 1024, 128, F),
};
# undef T
# undef F
# undef nil
} /*namespace*/
// full collector test.
TEST_CASE("collector-x1-gc", "[alloc2][gc]")
{
scope log(XO_DEBUG(true),
"DX1Collector gc test");
//std::uint64_t seed = 7988747704879432247ul;
//random_seed(&seed);
for (size_t i_tc = 0, n_tc = s_testcase_v.size(); i_tc < n_tc; ++i_tc) {
// auto rgen = xoshiro256ss(seed + i_tc);
const Testcase & tc = s_testcase_v[i_tc];
scope log1(XO_DEBUG(tc.debug_flag_),
"testcase loop",
xtag("i_tc", i_tc));
INFO(tostr(xtag("i_tc", i_tc), xtag("n_tc", n_tc)));
X1Fixture fixture(i_tc, tc);
auto & x1 = fixture.gc_;
REQUIRE(x1.verify_ok());
auto mm = x1.ref<AAllocator>();
auto gc = mm.to_facet<ACollector>();
Generation g1{1};
{
auto roots = DArray::_empty(mm, 1)->ref<AGCObject>();
REQUIRE(mm->contains_allocated(Role::to_space(), roots.data()));
gc.add_gc_root(&roots);
{
auto x1 = DInteger::box(mm, 42);
auto x1_gco = obj<AGCObject>(x1);
auto l1 = DList::cons(mm, x1, DList::_nil());
#ifdef NOT_YET
REQUIRE(roots->push_back(l1));
REQUIRE(mm->contains_allocated(Role::to_space(), x1.data()));
REQUIRE(mm->contains_allocated(Role::to_space(), l1.data()));
gc->add_gc_root_poly(&(*roots.operator->())[0]);
gc->request_gc(g1); // 1st GC
// x1 target got moved, og locn now relabeled from-space
REQUIRE(mm->contains(Role::from_space(), x1.data()));
REQUIRE(!mm->contains_allocated(Role::from_space(), x1.data()));
// l1 target got moved, og locn now relabeled from-space
REQUIRE(mm->contains(Role::from_space(), l1.data()));
REQUIRE(!mm->contains_allocated(Role::from_space(), l1.data()));
#endif
}
REQUIRE(mm->contains_allocated(Role::to_space(), roots.data()));
}
}
#ifdef NOT_YET
/* typed collector i/face */
auto x1gc = with_facet<ACollector>::mkobj(&x1state);
/* typed allocator i/face */
auto x1alloc = with_facet<AAllocator>::mkobj(&x1state);
REQUIRE(x1gc.iface());
REQUIRE(x1gc.data());
REQUIRE(x1alloc.iface());
REQUIRE(x1alloc.data());
rng::Seed<rng::xoshiro256ss> seed;
log && log("ratio: seed=", seed);
auto rng = rng::xoshiro256ss(seed);
// 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));
#endif
}
}
}