diff --git a/include/xo/gc/DX1Collector.hpp b/include/xo/gc/DX1Collector.hpp index 84e04c5c..e8b930fe 100644 --- a/include/xo/gc/DX1Collector.hpp +++ b/include/xo/gc/DX1Collector.hpp @@ -307,7 +307,9 @@ namespace xo { // ----- mutation ----- - /** Modify a gc-owned pointer @p *p_lhs, within allocation @p parent, + /** DEPRECATED. Prefer .barrier_assign_aux(). + * + * Modify a gc-owned pointer @p *p_lhs, within allocation @p parent, * to point to @p rhs. * * Motivation: need special handling for cross-generational pointers with diff --git a/include/xo/gc/MutationLogStore.hpp b/include/xo/gc/MutationLogStore.hpp index 018b2869..cc389555 100644 --- a/include/xo/gc/MutationLogStore.hpp +++ b/include/xo/gc/MutationLogStore.hpp @@ -55,14 +55,22 @@ namespace xo { void verify_ok() noexcept; /** on behalf of gc-aware object store @p gc, - * change the value of a child pointer at @p p_lhs - * with parent object @p parent. p_lhs and parent must belong - * to the same allocation. + * change the value of a child pointer {@p lhs_iface, @p *lhs_data} + * with parent object @p parent, to point to {@p rhs_iface, @p rhs_data} + * p_lhs and parent must belong to the same allocation. + * + * @p lhs_iface can be nullptr, if parent holds ordinary pointer + * instead of fop (i.e. DRepr* instead of obj). + * + * @p rhs_iface must be non-null, it's load-bearing for mlog entry + * snapshot member. **/ - void assign_member(GCObjectStore * gc, - void * parent, - obj * p_lhs, - obj rhs); + void assign_member_aux(GCObjectStore * gc, + void * parent, + AGCObject * lhs_iface, + void ** lhs_data, + AGCObject * rhs_iface, + void * rhs_data); /** swap {to, from} roles **/ diff --git a/include/xo/gc/detail/ICollector_DX1Collector.hpp b/include/xo/gc/detail/ICollector_DX1Collector.hpp index d9b43a5c..285db9ff 100644 --- a/include/xo/gc/detail/ICollector_DX1Collector.hpp +++ b/include/xo/gc/detail/ICollector_DX1Collector.hpp @@ -104,6 +104,7 @@ Return false if installation fails (e.g. memory exhausted) **/ **/ static void request_gc(DX1Collector & self, Generation upto); /** Assign pointer @p p_lhs to destination @p rhs, within parent allocation @p parent +DEPRECATED. Only used in MockCollector for gc unit test Require: gc not in progress **/ static void assign_member(DX1Collector & self, void * parent, obj * p_lhs, obj & rhs); diff --git a/src/gc/DX1Collector.cpp b/src/gc/DX1Collector.cpp index af7adff9..076f3480 100644 --- a/src/gc/DX1Collector.cpp +++ b/src/gc/DX1Collector.cpp @@ -620,24 +620,11 @@ namespace xo { void DX1Collector::assign_member(void * parent, obj * p_lhs, obj rhs) { - scope log(XO_DEBUG(config_.debug_flag_), - xtag("parent", parent), xtag("lhs", p_lhs), xtag("rhs", rhs.data())); - - // ++ stats.n_mutation_; - - if (runstate_.is_running()) { - *p_lhs = rhs; - - // for removal of all doubt: - // don't log mutations during GC cycle. - // That said: should not be happening! - assert(false); - - return; - } else { - mlog_store_.assign_member(&gco_store_, parent, p_lhs, rhs); - - } + this->barrier_assign_aux(parent, + p_lhs->iface(), + p_lhs->opaque_data_addr(), + rhs.iface(), + rhs.opaque_data()); } /*assign_member*/ DX1CollectorIterator @@ -702,7 +689,12 @@ namespace xo { xtag("lhs.iface", lhs_iface), xtag("&lhs.data", lhs_data), xtag("rhs.iface", rhs_iface), xtag("rhs.data", rhs_data)); - // see .assign_member() + mlog_store_.assign_member_aux(&gco_store_, + parent, + lhs_iface, + lhs_data, + rhs_iface, + rhs_data); } } /*namespace mm*/ } /*namespace xo*/ diff --git a/src/gc/MutationLogStore.cpp b/src/gc/MutationLogStore.cpp index e57f40d4..82a7d782 100644 --- a/src/gc/MutationLogStore.cpp +++ b/src/gc/MutationLogStore.cpp @@ -139,17 +139,31 @@ namespace xo { } /*verify_ok*/ void - MutationLogStore::assign_member(GCObjectStore * gco_store, - void * parent, - obj * p_lhs, - obj rhs) + MutationLogStore::assign_member_aux(GCObjectStore * gco_store, + void * parent, + AGCObject * lhs_iface, + void ** lhs_addr, + AGCObject * rhs_iface, + void * rhs_data) { scope log(XO_DEBUG(config_.debug_flag_), - xtag("parent", parent), xtag("lhs", p_lhs), xtag("rhs", rhs.data())); + xtag("parent", parent), + xtag("lhs.iface", lhs_iface), + xtag("&lhs.data", lhs_addr), + xtag("rhs.iface", rhs_iface), + xtag("rhs.data", rhs_data)); // ++ stats.n_mutation_; - *p_lhs = rhs; + assert(parent); + assert(lhs_addr); + assert(rhs_iface); + assert(rhs_data); + + if (lhs_iface) + *lhs_iface = *rhs_iface; + + *lhs_addr = rhs_data; if (!config_.enabled_flag_) { log && log(xtag("msg", "noop b/c incremental gc disabled")); @@ -162,7 +176,7 @@ namespace xo { // 1. generation of lhs // 2. generation of rhs - Generation src_g = gco_store->generation_of(Role::to_space(), p_lhs); + Generation src_g = gco_store->generation_of(Role::to_space(), lhs_addr); if (src_g.is_sentinel()) { log && log(xtag("msg", "noop because src not gc-owned")); @@ -172,7 +186,7 @@ namespace xo { return; } - Generation dest_g = gco_store->generation_of(Role::to_space(), rhs.data()); + Generation dest_g = gco_store->generation_of(Role::to_space(), rhs_data); if (dest_g.is_sentinel()) { log && log(xtag("msg", "noop because dest not gc-owned")); @@ -197,7 +211,7 @@ namespace xo { const DArena * arena = gco_store->get_space(Role::to_space(), src_g); const DArena::header_type * src_hdr = arena->obj2hdr(parent); - const DArena::header_type * dest_hdr = arena->obj2hdr(rhs.data()); + const DArena::header_type * dest_hdr = arena->obj2hdr(rhs_data); assert(src_hdr && dest_hdr); @@ -222,16 +236,16 @@ namespace xo { // control here: we have an older->younger pointer, need to log it - void ** lhs_addr = reinterpret_cast(&(p_lhs->data_)); + obj snap(rhs_iface, rhs_data); - this->_append_mutation(dest_g, parent, lhs_addr, rhs); + this->_append_mutation(dest_g, parent, lhs_addr, snap); } void MutationLogStore::_append_mutation(Generation dest_g, void * parent, void ** addr, - obj rhs) + obj snap) { // mlog keyed by generation in which pointer _destination_ resides: // collection that moves destination generation around needs to also @@ -239,7 +253,7 @@ namespace xo { // MutationLog * mlog = this->mlog_[Role::to_space()][dest_g]; - mlog->push_back(MutationLogEntry(parent, addr, rhs)); + mlog->push_back(MutationLogEntry(parent, addr, snap)); } void diff --git a/utest/DMockCollector.cpp b/utest/DMockCollector.cpp index eb180685..a4573f2d 100644 --- a/utest/DMockCollector.cpp +++ b/utest/DMockCollector.cpp @@ -91,7 +91,12 @@ namespace xo { void DMockCollector::assign_member(void * parent, obj * p_lhs, obj & rhs) { - mls_->assign_member(gcos_, parent, p_lhs, rhs); + mls_->assign_member_aux(gcos_, + parent, + p_lhs->iface(), + p_lhs->opaque_data_addr(), + rhs.iface(), + rhs.opaque_data()); } void *