From 2d713215a8fba320b2e5472d1ae6924e5a9d263c Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 21 Oct 2011 13:27:44 -0700 Subject: Record the internal reference count of environment boxes. Closes #981 --- src/rt/rust_cc.cpp | 47 ++++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 19 deletions(-) (limited to 'src/rt') diff --git a/src/rt/rust_cc.cpp b/src/rt/rust_cc.cpp index e9d220d9032..2e3ff89291c 100644 --- a/src/rt/rust_cc.cpp +++ b/src/rt/rust_cc.cpp @@ -95,7 +95,12 @@ class irc : public shape::data { } void walk_fn() { - shape::data::walk_fn_contents(dp); + // Record an irc for the environment box, but don't descend + // into it since it will be walked via the box's allocation + dp += sizeof(void *); // skip code pointer + uint8_t * box_ptr = shape::bump_dp(dp); + shape::ptr ref_count_dp(box_ptr); + maybe_record_irc(ref_count_dp); } void walk_obj() { @@ -114,28 +119,32 @@ class irc : public shape::data { void walk_subcontext(irc &sub) { sub.walk(); } void walk_box_contents(irc &sub, shape::ptr &ref_count_dp) { - if (!ref_count_dp) - return; - - // Bump the internal reference count of the box. - if (ircs.find((void *)ref_count_dp) == ircs.end()) { - LOG(task, gc, - "setting internal reference count for %p to 1", - (void *)ref_count_dp); - ircs[(void *)ref_count_dp] = 1; - } else { - uintptr_t newcount = ircs[(void *)ref_count_dp] + 1; - LOG(task, gc, - "bumping internal reference count for %p to %lu", - (void *)ref_count_dp, newcount); - ircs[(void *)ref_count_dp] = newcount; - } + maybe_record_irc(ref_count_dp); // Do not traverse the contents of this box; it's in the allocation // somewhere, so we're guaranteed to come back to it (if we haven't // traversed it already). } + void maybe_record_irc(shape::ptr &ref_count_dp) { + if (!ref_count_dp) + return; + + // Bump the internal reference count of the box. + if (ircs.find((void *)ref_count_dp) == ircs.end()) { + LOG(task, gc, + "setting internal reference count for %p to 1", + (void *)ref_count_dp); + ircs[(void *)ref_count_dp] = 1; + } else { + uintptr_t newcount = ircs[(void *)ref_count_dp] + 1; + LOG(task, gc, + "bumping internal reference count for %p to %lu", + (void *)ref_count_dp, newcount); + ircs[(void *)ref_count_dp] = newcount; + } + } + void walk_struct(const uint8_t *end_sp) { while (this->sp != end_sp) { this->walk(); @@ -231,8 +240,8 @@ find_roots(rust_task *task, irc_map &ircs, std::vector &roots) { } else { LOG(task, gc, "nonroot found: %p, irc %lu, ref count %lu", alloc, irc, ref_count); - /*assert(irc == ref_count && "Internal reference count must be " - "less than or equal to the total reference count!");*/ + assert(irc == ref_count && "Internal reference count must be " + "less than or equal to the total reference count!"); } ++begin; -- cgit 1.4.1-3-g733a5