xo-alloc, xo-object: fix alloc,gc unit tests after gc improvements
This commit is contained in:
parent
212a1fdc8c
commit
db32b58052
14 changed files with 149 additions and 46 deletions
|
|
@ -130,6 +130,7 @@ namespace xo {
|
|||
std::size_t reserved() const { return hi_ - lo_; };
|
||||
|
||||
std::size_t page_size() const { return page_z_; }
|
||||
std::size_t hugepage_z() const { return hugepage_z_; }
|
||||
std::byte * free_ptr() const { return free_ptr_; }
|
||||
void set_free_ptr(std::byte * x);
|
||||
|
||||
|
|
|
|||
|
|
@ -177,6 +177,8 @@ namespace xo {
|
|||
|
||||
/** @return pagesize (will be the same for {nursery, tenured} spaces) **/
|
||||
std::size_t pagesize() const;
|
||||
/** @return hugepage size (will be the same for {nursery, tenured} spaces) **/
|
||||
std::size_t hugepage_z() const;
|
||||
|
||||
/** @return allocation portion of Nursery to-space **/
|
||||
std::size_t nursery_to_allocated() const;
|
||||
|
|
|
|||
|
|
@ -16,12 +16,15 @@ namespace xo {
|
|||
|
||||
namespace gc {
|
||||
/** @class IAllocator
|
||||
* @brief memory allocation interface with limited garbage collector support
|
||||
* @brief arena allocation interface with limited garbage collector support
|
||||
*
|
||||
* Garbage collector support methods:
|
||||
* - checkpoint()
|
||||
* - assign_member()
|
||||
* - alloc_gc_copy()
|
||||
*
|
||||
* See class GC for copying incremental collector.
|
||||
* See class ArenaAlloc for arena allocator
|
||||
**/
|
||||
class IAlloc {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ namespace xo {
|
|||
/** page size used by underlying ArenaAlloc **/
|
||||
std::size_t page_size() const;
|
||||
|
||||
/** hugepage size used by underlying ArenaAlloc **/
|
||||
std::size_t hugepage_z() const;
|
||||
|
||||
/** reset to have at least @p z bytes of storage **/
|
||||
bool reset(std::size_t z);
|
||||
|
||||
|
|
|
|||
|
|
@ -233,6 +233,12 @@ namespace xo {
|
|||
return nursery_to()->page_size();
|
||||
}
|
||||
|
||||
std::size_t
|
||||
GC::hugepage_z() const
|
||||
{
|
||||
return nursery_to()->hugepage_z();
|
||||
}
|
||||
|
||||
std::size_t
|
||||
GC::nursery_from_allocated() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -75,6 +75,11 @@ namespace xo {
|
|||
return hd_->page_size();
|
||||
}
|
||||
|
||||
std::size_t
|
||||
ListAlloc::hugepage_z() const {
|
||||
return hd_->hugepage_z();
|
||||
}
|
||||
|
||||
std::size_t
|
||||
ListAlloc::size() const {
|
||||
return total_z_;
|
||||
|
|
@ -336,6 +341,7 @@ namespace xo {
|
|||
|
||||
std::unique_ptr<ArenaAlloc> new_alloc = ArenaAlloc::make(name,
|
||||
cz, debug_flag_);
|
||||
cz = new_alloc->size();
|
||||
|
||||
if (!new_alloc)
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -13,17 +13,16 @@ namespace xo {
|
|||
|
||||
namespace {
|
||||
struct testcase_alloc {
|
||||
testcase_alloc(std::size_t rz, std::size_t z)
|
||||
explicit testcase_alloc(std::size_t z)
|
||||
:
|
||||
arena_z_{z} {}
|
||||
|
||||
std::size_t arena_z_;
|
||||
|
||||
};
|
||||
|
||||
std::vector<testcase_alloc>
|
||||
s_testcase_v = {
|
||||
testcase_alloc(0, 4096)
|
||||
testcase_alloc(4096)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -37,11 +36,12 @@ namespace xo {
|
|||
|
||||
auto alloc = ArenaAlloc::make("linearalloc",
|
||||
tc.arena_z_, c_debug_flag);
|
||||
alloc->expand(tc.arena_z_);
|
||||
|
||||
REQUIRE(alloc.get());
|
||||
REQUIRE(alloc->name() == "linearalloc");
|
||||
REQUIRE(alloc->size() == tc.arena_z_);
|
||||
REQUIRE(alloc->available() == tc.arena_z_);
|
||||
REQUIRE(alloc->size() == std::max(tc.arena_z_, alloc->hugepage_z()));
|
||||
REQUIRE(alloc->available() == std::max(tc.arena_z_, alloc->hugepage_z()));
|
||||
REQUIRE(alloc->allocated() == 0);
|
||||
REQUIRE(alloc->is_before_checkpoint(alloc->free_ptr()) == false);
|
||||
REQUIRE(alloc->before_checkpoint() == 0);
|
||||
|
|
@ -49,23 +49,23 @@ namespace xo {
|
|||
|
||||
auto free0 = alloc->free_ptr();
|
||||
|
||||
auto mem = alloc->alloc(tc.arena_z_);
|
||||
auto mem = alloc->alloc(std::max(tc.arena_z_, alloc->hugepage_z()));
|
||||
|
||||
REQUIRE(mem != nullptr);
|
||||
|
||||
REQUIRE(mem == free0);
|
||||
|
||||
REQUIRE(alloc->size() == tc.arena_z_);
|
||||
REQUIRE(alloc->size() == std::max(tc.arena_z_, alloc->hugepage_z()));
|
||||
REQUIRE(alloc->available() == 0);
|
||||
REQUIRE(alloc->allocated() == tc.arena_z_);
|
||||
REQUIRE(alloc->allocated() == std::max(tc.arena_z_, alloc->hugepage_z()));
|
||||
REQUIRE(alloc->is_before_checkpoint(mem) == false);
|
||||
REQUIRE(alloc->before_checkpoint() == 0);
|
||||
REQUIRE(alloc->after_checkpoint() == tc.arena_z_);
|
||||
REQUIRE(alloc->after_checkpoint() == std::max(tc.arena_z_, alloc->hugepage_z()));
|
||||
|
||||
alloc->clear();
|
||||
|
||||
REQUIRE(alloc->free_ptr() == free0);
|
||||
REQUIRE(alloc->available() == tc.arena_z_);
|
||||
REQUIRE(alloc->available() == std::max(tc.arena_z_, alloc->hugepage_z()));
|
||||
REQUIRE(alloc->allocated() == 0);
|
||||
REQUIRE(alloc->is_before_checkpoint(free0) == false);
|
||||
REQUIRE(alloc->before_checkpoint() == 0);
|
||||
|
|
@ -74,8 +74,8 @@ namespace xo {
|
|||
mem = alloc->alloc(1);
|
||||
|
||||
auto used = sizeof(void*);
|
||||
REQUIRE(alloc->size() == tc.arena_z_);
|
||||
REQUIRE(alloc->available() == tc.arena_z_ - used);
|
||||
REQUIRE(alloc->size() == std::max(tc.arena_z_, alloc->hugepage_z()));
|
||||
REQUIRE(alloc->available() == std::max(tc.arena_z_, alloc->hugepage_z()) - used);
|
||||
REQUIRE(alloc->allocated() == used);
|
||||
REQUIRE(alloc->is_before_checkpoint(free0) == false);
|
||||
REQUIRE(alloc->before_checkpoint() == 0);
|
||||
|
|
|
|||
|
|
@ -26,8 +26,11 @@ namespace xo {
|
|||
|
||||
std::vector<testcase_gc>
|
||||
s_testcase_v = {
|
||||
// n_gct: nursery gc threshold
|
||||
// t_gct: tenured gc threshold
|
||||
//
|
||||
// nz tz n_gct t_gct
|
||||
testcase_gc(1024, 4096, 1024, 4096)
|
||||
testcase_gc(1024, 4096, 1024, 1024)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -49,9 +52,9 @@ namespace xo {
|
|||
REQUIRE(gc->nursery_to_allocated() == 0);
|
||||
REQUIRE(gc->nursery_to_committed() >= tc.nursery_z_);
|
||||
REQUIRE(gc->nursery_to_reserved() >= tc.nursery_z_);
|
||||
REQUIRE(gc->nursery_to_reserved() < tc.nursery_z_ + gc->pagesize());
|
||||
REQUIRE(gc->nursery_to_reserved() < tc.nursery_z_ + gc->hugepage_z());
|
||||
REQUIRE(gc->size() >= tc.nursery_z_ + tc.tenured_z_);
|
||||
REQUIRE(gc->size() < tc.nursery_z_ + gc->pagesize() + tc.tenured_z_ + gc->pagesize());
|
||||
REQUIRE(gc->size() < tc.nursery_z_ + gc->hugepage_z() + tc.tenured_z_ + gc->hugepage_z());
|
||||
REQUIRE(gc->allocated() == 0);
|
||||
REQUIRE(gc->available() == gc->nursery_to_reserved());
|
||||
REQUIRE(gc->before_checkpoint() == 0);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ namespace xo {
|
|||
using xo::gc::ListAlloc;
|
||||
|
||||
namespace ut {
|
||||
#ifdef NOT_USING // ListAlloc probably permanently retired. Not maintaining
|
||||
|
||||
TEST_CASE("ListAlloc", "[alloc][gc]")
|
||||
{
|
||||
/** teeny weeny allocator.
|
||||
|
|
@ -27,7 +29,7 @@ namespace xo {
|
|||
std::byte * mem1 = alloc->alloc(20);
|
||||
|
||||
REQUIRE(mem1);
|
||||
REQUIRE(alloc->size() == alloc->page_size());
|
||||
REQUIRE(alloc->size() == std::max(alloc->page_size(), alloc->hugepage_z()));
|
||||
/* round up to multiple of 8 */
|
||||
REQUIRE(alloc->before_checkpoint() == 24);
|
||||
REQUIRE(alloc->after_checkpoint() == 0);
|
||||
|
|
@ -54,6 +56,7 @@ namespace xo {
|
|||
REQUIRE(alloc->is_before_checkpoint(mem2) == false);
|
||||
REQUIRE(alloc->is_before_checkpoint(mem3) == false);
|
||||
}
|
||||
#endif
|
||||
|
||||
} /*namespace ut*/
|
||||
} /*namespace xo*/
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@ namespace xo {
|
|||
{
|
||||
up<GC> gc = GC::make(
|
||||
{ .initial_nursery_z_ = 1024,
|
||||
.initial_tenured_z_ = 1024
|
||||
.initial_tenured_z_ = 2048,
|
||||
.incr_gc_threshold_ = 512,
|
||||
.full_gc_threshold_ = 512
|
||||
});
|
||||
|
||||
REQUIRE(gc.get());
|
||||
|
|
|
|||
|
|
@ -42,10 +42,13 @@ namespace xo {
|
|||
{
|
||||
up<GC> gc = GC::make(
|
||||
{
|
||||
.initial_nursery_z_ = 1024,
|
||||
.initial_tenured_z_ = 2048,
|
||||
.initial_nursery_z_ = 2024,
|
||||
.initial_tenured_z_ = 4048,
|
||||
.incr_gc_threshold_ = 512,
|
||||
.full_gc_threshold_ = 1024,
|
||||
.debug_flag_ = false
|
||||
});
|
||||
gc->disable_gc();
|
||||
|
||||
REQUIRE(gc->native_gc_statistics().n_mutation_ == 0);
|
||||
REQUIRE(gc->native_gc_statistics().n_logged_mutation_ == 0);
|
||||
|
|
@ -88,11 +91,13 @@ namespace xo {
|
|||
REQUIRE(gc->native_gc_statistics().n_xckp_mutation_ == 0);
|
||||
REQUIRE(gc->mlog_size() == 0);
|
||||
|
||||
REQUIRE(gc->is_gc_enabled() == true);
|
||||
REQUIRE(gc->is_gc_enabled() == false);
|
||||
|
||||
}
|
||||
|
||||
gc->request_gc(generation::nursery);
|
||||
gc->enable_gc_once();
|
||||
|
||||
{
|
||||
REQUIRE(gc->is_before_checkpoint(l.ptr()) == true);
|
||||
REQUIRE(gc->is_before_checkpoint(l->head().ptr()) == true);
|
||||
|
|
@ -123,6 +128,7 @@ namespace xo {
|
|||
// gc promotes parent, still need mutation log for xgen ptr
|
||||
|
||||
gc->request_gc(generation::nursery);
|
||||
gc->enable_gc_once();
|
||||
{
|
||||
REQUIRE(l->size() == 1);
|
||||
REQUIRE(Integer::from(l->head()).ptr());
|
||||
|
|
@ -144,6 +150,7 @@ namespace xo {
|
|||
// gc promotes child, no longer need mutation log entry
|
||||
|
||||
gc->request_gc(generation::nursery);
|
||||
gc->enable_gc_once();
|
||||
{
|
||||
REQUIRE(l->size() == 1);
|
||||
REQUIRE(Integer::from(l->head()).ptr());
|
||||
|
|
@ -522,15 +529,19 @@ namespace xo {
|
|||
|
||||
struct testcase_stresstest {
|
||||
testcase_stresstest(std::size_t nz, std::size_t tz,
|
||||
std::size_t ngct, std::size_t tgct,
|
||||
std::size_t m, std::size_t n,
|
||||
std::size_t r, std::size_t rr, std::size_t k,
|
||||
bool gc_stats_flag, bool debug_flag)
|
||||
: nursery_z_{nz}, tenured_z_{tz}, m_{m}, n_{n}, r_{r}, rr_{rr}, k_{k},
|
||||
gc_stats_flag_{gc_stats_flag}, debug_flag_{debug_flag}
|
||||
{}
|
||||
: nursery_z_{nz}, tenured_z_{tz}, nursery_gc_threshold_{ngct}, tenured_gc_threshold_{tgct},
|
||||
m_{m}, n_{n}, r_{r}, rr_{rr}, k_{k},
|
||||
gc_stats_flag_{gc_stats_flag}, debug_flag_{debug_flag}
|
||||
{}
|
||||
|
||||
std::size_t nursery_z_;
|
||||
std::size_t tenured_z_;
|
||||
std::size_t nursery_gc_threshold_;
|
||||
std::size_t tenured_gc_threshold_;
|
||||
|
||||
/* #of random list cells to create */
|
||||
std::size_t m_;
|
||||
|
|
@ -553,18 +564,19 @@ namespace xo {
|
|||
|
||||
/* nz: nursery size
|
||||
* tz: tenured size
|
||||
* ngct: nursery gc threshold
|
||||
* tgct: tenured gc threshold
|
||||
* m: #of random list cells to create
|
||||
* n: #of random integers to create
|
||||
* r: #of gc roots to create
|
||||
* rr: #of gc roots to replace between iterations
|
||||
* k: #of random mutations to apply
|
||||
*
|
||||
* nz tz m n r rr k stats, debug */
|
||||
testcase_stresstest( 16, 1024, 2, 0, 0, 0, 0, false, false),
|
||||
testcase_stresstest( 32, 1024, 2, 1, 5, 0, 0, false, false),
|
||||
testcase_stresstest( 64, 1024, 5, 2, 5, 2, 10, false, false),
|
||||
// testcase_stresstest( 128, 1024, 5, 2, 5, 2, 10, true, true), // segfault bad list cell
|
||||
testcase_stresstest(1024, 1024, 10, 10, 5, 2, 10, true, false)
|
||||
* nz tz ngct tgct m n r rr k stats, debug */
|
||||
testcase_stresstest(1024, 2048, 256, 1024, 2, 0, 0, 0, 0, false, false),
|
||||
testcase_stresstest(1024, 2048, 256, 1024, 2, 1, 5, 0, 0, false, false),
|
||||
testcase_stresstest(1024, 2048, 256, 1024, 5, 2, 5, 2, 10, false, false),
|
||||
testcase_stresstest(1024, 2048, 256, 1024, 10, 10, 5, 2, 10, false, false)
|
||||
};
|
||||
} /*namespace*/
|
||||
|
||||
|
|
@ -579,9 +591,12 @@ namespace xo {
|
|||
{
|
||||
.initial_nursery_z_ = tc.nursery_z_,
|
||||
.initial_tenured_z_ = tc.tenured_z_,
|
||||
.incr_gc_threshold_ = tc.nursery_gc_threshold_,
|
||||
.full_gc_threshold_ = tc.tenured_gc_threshold_,
|
||||
.stats_flag_ = tc.gc_stats_flag_,
|
||||
.debug_flag_ = tc.debug_flag_
|
||||
});
|
||||
gc->disable_gc();
|
||||
|
||||
REQUIRE(gc->native_gc_statistics().n_mutation_ == 0);
|
||||
REQUIRE(gc->native_gc_statistics().n_logged_mutation_ == 0);
|
||||
|
|
@ -594,7 +609,7 @@ namespace xo {
|
|||
// Plan:
|
||||
// - create vector of m cons cells w1[].
|
||||
// - prepend w1[] to a vector of n integers; call this w2[].
|
||||
// - create vector root_v[] of r gc roots. Assign each root_v[j] to some random w2[i]
|
||||
// - create vector root_v[] of r gc roots. Assign each root_v[j] to some random w2[i]
|
||||
// - make some random mutations.
|
||||
// - traverse root_v[] to construct model from_model for reachable objects
|
||||
// - run gc
|
||||
|
|
@ -610,6 +625,7 @@ namespace xo {
|
|||
//REQUIRE(tc.n_ > 0);
|
||||
//REQUIRE(tc.r_ > 0);
|
||||
|
||||
// data_model: generate some random data, to exercise GC
|
||||
RandomMutationModel data_model(tc.m_, tc.n_, tc.r_, tc.rr_, tc.k_);
|
||||
|
||||
for (std::size_t cycle = 0; cycle < 3; ++cycle) {
|
||||
|
|
@ -640,6 +656,7 @@ namespace xo {
|
|||
from_model.from_root_vector(data_model.root_v_);
|
||||
|
||||
gc->request_gc(generation::nursery);
|
||||
gc->enable_gc_once();
|
||||
|
||||
/* collector cycle changed object addresses.
|
||||
* build a new object model, and verify consiste1ncy with from_model
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@ namespace xo {
|
|||
{
|
||||
up<GC> gc = GC::make(
|
||||
{ .initial_nursery_z_ = 1024,
|
||||
.initial_tenured_z_ = 1024
|
||||
.initial_tenured_z_ = 2048,
|
||||
.incr_gc_threshold_ = 512,
|
||||
.full_gc_threshold_ = 512,
|
||||
});
|
||||
|
||||
REQUIRE(gc.get());
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
#include "xo/alloc/GC.hpp"
|
||||
#include "xo/alloc/ArenaAlloc.hpp"
|
||||
#include "xo/indentlog/scope.hpp"
|
||||
#include "xo/indentlog/print/vector.hpp"
|
||||
#include "xo/indentlog/print/tag.hpp"
|
||||
#include <catch2/catch.hpp>
|
||||
#include <ranges>
|
||||
#include <vector>
|
||||
|
|
@ -26,13 +28,15 @@ namespace xo {
|
|||
|
||||
namespace {
|
||||
struct Testcase_List {
|
||||
Testcase_List(std::size_t nz, std::size_t tz,
|
||||
Testcase_List(std::size_t nz, std::size_t tz, std::size_t ngct, std::size_t tgct,
|
||||
const std::vector<std::vector<std::string>> & v)
|
||||
: nursery_z_{nz}, tenured_z_{tz}, v_{v}
|
||||
: nursery_z_{nz}, tenured_z_{tz}, incr_gc_threshold_{ngct}, full_gc_threshold_{tgct}, v_{v}
|
||||
{}
|
||||
|
||||
std::size_t nursery_z_;
|
||||
std::size_t tenured_z_;
|
||||
std::size_t incr_gc_threshold_;
|
||||
std::size_t full_gc_threshold_;
|
||||
|
||||
std::vector<std::vector<std::string>> v_;
|
||||
|
||||
|
|
@ -41,10 +45,10 @@ namespace xo {
|
|||
|
||||
std::vector<Testcase_List>
|
||||
s_testcase_v = {
|
||||
Testcase_List( 512, 1024, {{}}),
|
||||
Testcase_List( 512, 1024, {{"hello", ", ", " world!"}}),
|
||||
Testcase_List(1024, 2048, {{"the", " quick", " brown", "fox", "jumps"},
|
||||
{"over", " the", " lazy", " dog!"}})
|
||||
Testcase_List(1024, 2048, 512, 1024, {{}}),
|
||||
Testcase_List(2048, 4096, 512, 1024, {{"hello", ", ", " world!"}}),
|
||||
Testcase_List(2048, 4096, 512, 1024, {{"the", " quick", " brown", "fox", "jumps"},
|
||||
{"over", " the", " lazy", " dog!"}})
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -58,7 +62,10 @@ namespace xo {
|
|||
up<GC> gc = GC::make(
|
||||
{.initial_nursery_z_ = tc.nursery_z_,
|
||||
.initial_tenured_z_ = tc.tenured_z_,
|
||||
.debug_flag_ = c_debug_flag});
|
||||
.incr_gc_threshold_ = tc.incr_gc_threshold_,
|
||||
.full_gc_threshold_ = tc.full_gc_threshold_,
|
||||
.debug_flag_ = c_debug_flag});
|
||||
gc->disable_gc();
|
||||
|
||||
REQUIRE(gc.get());
|
||||
|
||||
|
|
@ -72,24 +79,45 @@ namespace xo {
|
|||
std::vector<gp<List>> root_v(tc.v_.size());
|
||||
std::size_t i = 0;
|
||||
|
||||
/* auditing List::_shallow_size(), String::_shallow_size()
|
||||
* vs GC::allocated()
|
||||
*/
|
||||
std::size_t expected_alloc_z = 0;
|
||||
|
||||
// TODO: consolidate: root setup shared with "List" unit test
|
||||
|
||||
REQUIRE(gc->allocated() == expected_alloc_z);
|
||||
|
||||
/* construct example Lists from testcase info */
|
||||
for (const std::vector<std::string> & v : tc.v_)
|
||||
{
|
||||
INFO(xtag("v", v));
|
||||
|
||||
/* building l1 in reverse order */
|
||||
gp<List> l1 = List::nil;
|
||||
|
||||
for (std::size_t ip1 = v.size(); ip1 > 0; --ip1) {
|
||||
INFO(xtag("ip1", ip1));
|
||||
|
||||
const std::string & si = v.at(ip1 - 1);
|
||||
|
||||
log && log(xtag("i", ip1-1), xtag("si", si));
|
||||
|
||||
gp<String> sobj = String::copy(si.c_str());
|
||||
|
||||
std::size_t sobj_z = sobj->_shallow_size();
|
||||
expected_alloc_z += sobj_z;
|
||||
|
||||
REQUIRE(gc->allocated() == expected_alloc_z);
|
||||
|
||||
l1 = List::cons(sobj, l1);
|
||||
|
||||
log && log(xtag("l1.size", l1->size()));
|
||||
|
||||
std::size_t alloc_z = l1->_shallow_size() + l1->head()->_shallow_size();
|
||||
expected_alloc_z += alloc_z;
|
||||
std::size_t l1_z = l1->_shallow_size();
|
||||
expected_alloc_z += l1_z;
|
||||
|
||||
REQUIRE(gc->allocated() == expected_alloc_z);
|
||||
}
|
||||
|
||||
REQUIRE(l1->is_nil() == (v.size() == 0));
|
||||
|
|
@ -108,6 +136,7 @@ namespace xo {
|
|||
* all are roots and should be preserved
|
||||
*/
|
||||
gc->request_gc(generation::nursery);
|
||||
gc->enable_gc_once();
|
||||
|
||||
REQUIRE(gc->native_gc_statistics().gen_v_[gen2int(generation::nursery)].n_gc_ == 1);
|
||||
REQUIRE(gc->native_gc_statistics().gen_v_[gen2int(generation::tenured)].n_gc_ == 0);
|
||||
|
|
@ -133,6 +162,7 @@ namespace xo {
|
|||
|
||||
/* every has survived one GC cycle. collect again should promote */
|
||||
gc->request_gc(generation::nursery);
|
||||
gc->enable_gc_once();
|
||||
|
||||
REQUIRE(gc->native_gc_statistics().gen_v_[gen2int(generation::nursery)].n_gc_ == 2);
|
||||
REQUIRE(gc->native_gc_statistics().gen_v_[gen2int(generation::tenured)].n_gc_ == 0);
|
||||
|
|
@ -159,6 +189,7 @@ namespace xo {
|
|||
REQUIRE(gc->native_gc_statistics().total_promoted_ == gc->allocated());
|
||||
|
||||
gc->request_gc(generation::tenured);
|
||||
gc->enable_gc_once();
|
||||
|
||||
REQUIRE(gc->native_gc_statistics().gen_v_[gen2int(generation::nursery)].n_gc_ == 2);
|
||||
REQUIRE(gc->native_gc_statistics().gen_v_[gen2int(generation::tenured)].n_gc_ == 1);
|
||||
|
|
@ -197,10 +228,14 @@ namespace xo {
|
|||
up<GC> gc = GC::make(
|
||||
{.initial_nursery_z_ = tc.nursery_z_,
|
||||
.initial_tenured_z_ = tc.tenured_z_,
|
||||
.incr_gc_threshold_ = tc.incr_gc_threshold_,
|
||||
.full_gc_threshold_ = tc.full_gc_threshold_,
|
||||
.debug_flag_ = c_debug_flag});
|
||||
|
||||
REQUIRE(gc.get());
|
||||
|
||||
gc->disable_gc();
|
||||
|
||||
/* use gc for all Object allocs */
|
||||
Object::mm = gc.get();
|
||||
|
||||
|
|
@ -224,10 +259,14 @@ namespace xo {
|
|||
|
||||
for (std::size_t ip1 = v.size(); ip1 > 0; --ip1) {
|
||||
const std::string & si = v.at(ip1 - 1);
|
||||
|
||||
log && log(xtag("i", ip1-1), xtag("si", si));
|
||||
gp<String> sobj = String::copy(si.c_str());
|
||||
|
||||
l1 = List::cons(sobj, l1);
|
||||
|
||||
log && log(xtag("l1.size", l1->size()));
|
||||
|
||||
if (ip1 == v.size()) {
|
||||
// capture last
|
||||
last = l1;
|
||||
|
|
@ -255,6 +294,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
gc->request_gc(generation::nursery);
|
||||
gc->enable_gc_once();
|
||||
|
||||
REQUIRE(gc->native_gc_statistics().gen_v_[gen2int(generation::nursery)].n_gc_ == 1);
|
||||
REQUIRE(gc->native_gc_statistics().gen_v_[gen2int(generation::tenured)].n_gc_ == 0);
|
||||
|
|
|
|||
|
|
@ -23,20 +23,28 @@ namespace xo {
|
|||
|
||||
namespace {
|
||||
struct Testcase_String {
|
||||
Testcase_String(std::size_t nz, std::size_t tz,
|
||||
const std::vector<std::string> & v)
|
||||
: nursery_z_{nz}, tenured_z_{tz}, v_{v} {}
|
||||
Testcase_String(std::size_t nz,
|
||||
std::size_t tz,
|
||||
std::size_t ngct,
|
||||
std::size_t tgct,
|
||||
const std::vector<std::string> & v) : nursery_z_{nz},
|
||||
tenured_z_{tz},
|
||||
incr_gc_threshold_{ngct},
|
||||
full_gc_threshold_{tgct},
|
||||
v_{v} {}
|
||||
|
||||
std::size_t nursery_z_;
|
||||
std::size_t tenured_z_;
|
||||
std::size_t incr_gc_threshold_;
|
||||
std::size_t full_gc_threshold_;
|
||||
|
||||
std::vector<std::string> v_;
|
||||
};
|
||||
|
||||
std::vector<Testcase_String>
|
||||
s_testcase_v = {
|
||||
Testcase_String(1024, 4096, {"hello"}),
|
||||
Testcase_String(1024, 4096, {"hello", ", world!"})
|
||||
Testcase_String(1024, 4096, 512, 512, {"hello"}),
|
||||
Testcase_String(1024, 4096, 512, 512, {"hello", ", world!"})
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -48,10 +56,14 @@ namespace xo {
|
|||
up<GC> gc = GC::make(
|
||||
{.initial_nursery_z_ = tc.nursery_z_,
|
||||
.initial_tenured_z_ = tc.tenured_z_,
|
||||
.incr_gc_threshold_ = tc.incr_gc_threshold_,
|
||||
.full_gc_threshold_ = tc.full_gc_threshold_,
|
||||
.debug_flag_ = false});
|
||||
|
||||
REQUIRE(gc.get());
|
||||
|
||||
gc->disable_gc();
|
||||
|
||||
/* use gc for all Object allocs */
|
||||
Object::mm = gc.get();
|
||||
|
||||
|
|
@ -77,6 +89,7 @@ namespace xo {
|
|||
|
||||
/* gc has n_string objects. Nothing refers to them, so gc going to kill all */
|
||||
gc->request_gc(generation::nursery);
|
||||
gc->enable_gc_once();
|
||||
|
||||
REQUIRE(gc->gc_in_progress() == false);
|
||||
REQUIRE(gc->native_gc_statistics().gen_v_[gen2int(generation::nursery)].n_gc_ == 1);
|
||||
|
|
@ -95,6 +108,8 @@ namespace xo {
|
|||
up<GC> gc = GC::make(
|
||||
{.initial_nursery_z_ = tc.nursery_z_,
|
||||
.initial_tenured_z_ = tc.tenured_z_,
|
||||
.incr_gc_threshold_ = tc.incr_gc_threshold_,
|
||||
.full_gc_threshold_ = tc.full_gc_threshold_,
|
||||
.debug_flag_ = false});
|
||||
|
||||
REQUIRE(gc.get());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue