xo-interpreter2 stack: + reason arg to visit_gco_children()
Helps streamline DX1Collector in xo-gc/. Want both forward and verify entry points for the same representation.
This commit is contained in:
parent
518a3d637a
commit
dc31e0f772
10 changed files with 55 additions and 35 deletions
|
|
@ -274,20 +274,13 @@ namespace xo {
|
|||
/** Execute gc immediately, for all generations < @p upto **/
|
||||
void execute_gc(Generation upto) noexcept;
|
||||
|
||||
#ifdef OBSOLETE // replaced by visit_child()
|
||||
/** Evacuate object at @p *lhs_data to to-space.
|
||||
* Replace original with forwarding pointer to new location
|
||||
**/
|
||||
void forward_inplace(AGCObject * lhs_iface, void ** lhs_data);
|
||||
#endif
|
||||
|
||||
/** Supports GCObjectVisitor facet.
|
||||
* During gc phase:
|
||||
* During gc phase (@p reason is 'forward')
|
||||
* 1. evacuate object at @p *lhs_data to to-space.
|
||||
* 2. replace @p *lhs_data with forwarding pointer
|
||||
* to new location.
|
||||
**/
|
||||
void visit_child(AGCObject * lhs_iface, void ** lhs_data);
|
||||
void visit_child(VisitReason reason, AGCObject * lhs_iface, void ** lhs_data);
|
||||
|
||||
// ----- allocation -----
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ Source must be owned by this collector.
|
|||
Increments object age **/
|
||||
static void * alloc_copy(DX1Collector & self, std::byte * src);
|
||||
/** visit child of a gc-aware object. May update child in-place! **/
|
||||
static void visit_child(DX1Collector & self, AGCObject * iface, void ** pp_data) noexcept;
|
||||
static void visit_child(DX1Collector & self, VisitReason reason, AGCObject * iface, void ** pp_data) noexcept;
|
||||
///@}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -404,7 +404,7 @@ namespace xo {
|
|||
// - X1Collector::forward_inplace() -> _verify_aux()
|
||||
//
|
||||
|
||||
gco.visit_gco_children(self);
|
||||
gco.visit_gco_children(VisitReason::verify(), self);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -585,21 +585,28 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
DX1Collector::visit_child(AGCObject * lhs_iface,
|
||||
DX1Collector::visit_child(VisitReason reason,
|
||||
AGCObject * lhs_iface,
|
||||
void ** lhs_data)
|
||||
{
|
||||
// MAYBE: adapter distinct from DX1Collector that supports GCObjectVisitor facet,
|
||||
// calls DX1Collector::_verify_aux()
|
||||
|
||||
if (runstate_.is_running()) {
|
||||
switch (reason.code()) {
|
||||
case VisitReason::code::forward:
|
||||
{
|
||||
Generation upto = runstate_.gc_upto();
|
||||
|
||||
// called during collection phase
|
||||
gco_store_.forward_inplace_aux(this->ref<AGCObjectVisitor>(), lhs_iface, lhs_data, upto);
|
||||
} else if (runstate_.is_verify()) {
|
||||
gco_store_.forward_inplace_aux
|
||||
(this->ref<AGCObjectVisitor>(), lhs_iface, lhs_data, upto);
|
||||
break;
|
||||
}
|
||||
case VisitReason::code::verify:
|
||||
// called during verify_ok
|
||||
this->_verify_aux(lhs_iface, *lhs_data);
|
||||
} else {
|
||||
break;
|
||||
default:
|
||||
// should be unreachable
|
||||
assert(false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -501,7 +501,7 @@ namespace xo {
|
|||
log && log("disposition: not in from-space. Don't forward, but check children");
|
||||
|
||||
obj<AGCObject> gco(lhs_iface, object_data);
|
||||
gco.visit_gco_children(gc);
|
||||
gco.visit_gco_children(VisitReason::forward(), gc);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -714,7 +714,7 @@ namespace xo {
|
|||
// Nested control reenters
|
||||
// X1Collector::forward_inplace() -> _verify_aux()
|
||||
//
|
||||
gco.visit_gco_children(gc);
|
||||
gco.visit_gco_children(VisitReason::forward(), gc);
|
||||
} else {
|
||||
++(p_verify_stats->n_no_iface_);
|
||||
continue;
|
||||
|
|
@ -783,7 +783,7 @@ namespace xo {
|
|||
GCMoveCheckpoint gray_lo_v
|
||||
= this->snap_move_checkpoint(upto);
|
||||
|
||||
from_src.visit_gco_children(gc);
|
||||
from_src.visit_gco_children(VisitReason::forward(), gc);
|
||||
|
||||
// For each generation g:
|
||||
// traverse objects newer than gray_lo_v[g], to make sure children
|
||||
|
|
@ -1013,7 +1013,7 @@ namespace xo {
|
|||
|
||||
assert(iface->_has_null_vptr() == false);
|
||||
|
||||
iface->visit_gco_children(src, gc);
|
||||
iface->visit_gco_children(src, VisitReason::forward(), gc);
|
||||
|
||||
gray_lo_v[g] = ((std::byte *)src) + z;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@ namespace xo {
|
|||
return self.alloc_copy(src);
|
||||
}
|
||||
auto
|
||||
IGCObjectVisitor_DX1Collector::visit_child(DX1Collector & self, AGCObject * iface, void ** pp_data) noexcept -> void
|
||||
IGCObjectVisitor_DX1Collector::visit_child(DX1Collector & self, VisitReason reason, AGCObject * iface, void ** pp_data) noexcept -> void
|
||||
{
|
||||
self.visit_child(iface, pp_data);
|
||||
self.visit_child(reason, iface, pp_data);
|
||||
}
|
||||
|
||||
} /*namespace mm*/
|
||||
|
|
|
|||
|
|
@ -21,9 +21,12 @@ namespace xo {
|
|||
}
|
||||
|
||||
void
|
||||
DMockCollector::visit_child(AGCObject * lhs_iface, void ** lhs_data)
|
||||
DMockCollector::visit_child(VisitReason reason, AGCObject * lhs_iface, void ** lhs_data)
|
||||
{
|
||||
p_gco_store_->forward_inplace_aux(this->ref<AGCObjectVisitor>(), lhs_iface, lhs_data, upto_);
|
||||
(void)reason;
|
||||
|
||||
p_gco_store_->forward_inplace_aux
|
||||
(this->ref<AGCObjectVisitor>(), lhs_iface, lhs_data, upto_);
|
||||
}
|
||||
|
||||
std::byte *
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ namespace xo {
|
|||
Generation generation_of(Role r, const void * addr) const noexcept;
|
||||
AllocInfo alloc_info(void * mem) const noexcept;
|
||||
|
||||
void visit_child(AGCObject * lhs_iface, void ** lhs_data);
|
||||
void visit_child(VisitReason reason, AGCObject * lhs_iface, void ** lhs_data);
|
||||
std::byte * alloc_copy(void * src) noexcept;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -295,7 +295,8 @@ namespace ut {
|
|||
* 2. arena2 doesn't have concept of installed types.
|
||||
* It doesn't have or require any builtin ability to traverse an object model
|
||||
**/
|
||||
DArena arena2 = DArena::map(ArenaConfig().with_name("arena2-reference")
|
||||
DArena arena2
|
||||
= DArena::map(ArenaConfig().with_name("arena2-reference")
|
||||
.with_size(tc.gc_size_ * tc.n_gen_)
|
||||
.with_store_header_flag(true));
|
||||
|
||||
|
|
@ -325,7 +326,7 @@ namespace ut {
|
|||
}
|
||||
}
|
||||
|
||||
// verify basic arena partitioning
|
||||
// verify basic arena partitioning + sizing
|
||||
{
|
||||
REQUIRE(g0 != g1);
|
||||
REQUIRE(gcos.new_space());
|
||||
|
|
@ -371,7 +372,7 @@ namespace ut {
|
|||
}
|
||||
}
|
||||
|
||||
// allocator
|
||||
// allocator api
|
||||
auto alloc = obj<AAllocator,DArena>(gcos.new_space());
|
||||
|
||||
// create object(s).
|
||||
|
|
@ -420,6 +421,7 @@ namespace ut {
|
|||
REQUIRE(gcos.header2size(obj_info.header()) == obj_info.size());
|
||||
REQUIRE(gcos.header2age(obj_info.header()) == object_age{0});
|
||||
REQUIRE(gcos.header2tseq(obj_info.header()) == obj_info.tseq());
|
||||
REQUIRE(gcos.is_forwarding_header(obj_info.header()) == false);
|
||||
}
|
||||
|
||||
// new objects appear in to-space for generation 0
|
||||
|
|
@ -441,6 +443,7 @@ namespace ut {
|
|||
for (size_t i = 0, n = x1_v.size(); i < n; ++i) {
|
||||
const auto & x1 = x1_v.at(i);
|
||||
|
||||
REQUIRE(gcos.contains(Role::from_space(), x1.gco_.data()));
|
||||
REQUIRE(gcos.contains_allocated(Role::from_space(), x1.gco_.data()));
|
||||
AllocInfo obj_info = gcos.alloc_info((std::byte *)x1.gco_.data());
|
||||
REQUIRE(obj_info.size() >= x1.alloc_z_);
|
||||
|
|
@ -578,7 +581,8 @@ namespace ut {
|
|||
// can still try to move something.
|
||||
// but will fail since type isn't registered
|
||||
|
||||
auto x1p_data = gcos.deep_move_root(mock_gc_visitor, x1.gco_, g1);
|
||||
auto x1p_data
|
||||
= gcos.deep_move_root(mock_gc_visitor, x1.gco_, g1);
|
||||
|
||||
// control here under normal GC use
|
||||
// would represent a configuration fail
|
||||
|
|
@ -590,10 +594,23 @@ namespace ut {
|
|||
// Things to test:
|
||||
// - deep_move_interior() // used from MutationLogStore
|
||||
// - forward_inplace_aux() // used from DX1Collector.visit_child
|
||||
// - cleanup_phase() // used from DX1Collector._cleanup_phase
|
||||
|
||||
// - report_object_types
|
||||
// - report_object_ages()
|
||||
|
||||
bool sanitize_flag = true;
|
||||
|
||||
// swaps to- and from- spaces again
|
||||
// Now from-space will be empty, all live objects in to-space
|
||||
|
||||
gcos.cleanup_phase(g1, sanitize_flag);
|
||||
|
||||
#ifdef NOT_YET
|
||||
gcos.verify_ok(xxx objectvisitor,
|
||||
xxx &verify_stats);
|
||||
#endif
|
||||
|
||||
// - verify_ok
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@ namespace xo {
|
|||
return self.alloc_copy(src);
|
||||
}
|
||||
auto
|
||||
IGCObjectVisitor_DMockCollector::visit_child(DMockCollector & self, AGCObject * iface, void ** pp_data) noexcept -> void
|
||||
IGCObjectVisitor_DMockCollector::visit_child(DMockCollector & self, VisitReason reason, AGCObject * iface, void ** pp_data) noexcept -> void
|
||||
{
|
||||
self.visit_child(iface, pp_data);
|
||||
self.visit_child(reason, iface, pp_data);
|
||||
}
|
||||
|
||||
} /*namespace mm*/
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ Source must be owned by this collector.
|
|||
Increments object age **/
|
||||
static void * alloc_copy(DMockCollector & self, std::byte * src);
|
||||
/** visit child of a gc-aware object. May update child in-place! **/
|
||||
static void visit_child(DMockCollector & self, AGCObject * iface, void ** pp_data) noexcept;
|
||||
static void visit_child(DMockCollector & self, VisitReason reason, AGCObject * iface, void ** pp_data) noexcept;
|
||||
///@}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue