mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 11:07:42 +00:00
Record the internal reference count of environment boxes. Closes #981
This commit is contained in:
parent
6c4c33e009
commit
2d713215a8
@ -95,7 +95,12 @@ class irc : public shape::data<irc,shape::ptr> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void walk_fn() {
|
void walk_fn() {
|
||||||
shape::data<irc,shape::ptr>::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<uint8_t *>(dp);
|
||||||
|
shape::ptr ref_count_dp(box_ptr);
|
||||||
|
maybe_record_irc(ref_count_dp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void walk_obj() {
|
void walk_obj() {
|
||||||
@ -114,28 +119,32 @@ class irc : public shape::data<irc,shape::ptr> {
|
|||||||
void walk_subcontext(irc &sub) { sub.walk(); }
|
void walk_subcontext(irc &sub) { sub.walk(); }
|
||||||
|
|
||||||
void walk_box_contents(irc &sub, shape::ptr &ref_count_dp) {
|
void walk_box_contents(irc &sub, shape::ptr &ref_count_dp) {
|
||||||
if (!ref_count_dp)
|
maybe_record_irc(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not traverse the contents of this box; it's in the allocation
|
// 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
|
// somewhere, so we're guaranteed to come back to it (if we haven't
|
||||||
// traversed it already).
|
// 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) {
|
void walk_struct(const uint8_t *end_sp) {
|
||||||
while (this->sp != end_sp) {
|
while (this->sp != end_sp) {
|
||||||
this->walk();
|
this->walk();
|
||||||
@ -231,8 +240,8 @@ find_roots(rust_task *task, irc_map &ircs, std::vector<void *> &roots) {
|
|||||||
} else {
|
} else {
|
||||||
LOG(task, gc, "nonroot found: %p, irc %lu, ref count %lu",
|
LOG(task, gc, "nonroot found: %p, irc %lu, ref count %lu",
|
||||||
alloc, irc, ref_count);
|
alloc, irc, ref_count);
|
||||||
/*assert(irc == ref_count && "Internal reference count must be "
|
assert(irc == ref_count && "Internal reference count must be "
|
||||||
"less than or equal to the total reference count!");*/
|
"less than or equal to the total reference count!");
|
||||||
}
|
}
|
||||||
|
|
||||||
++begin;
|
++begin;
|
||||||
|
10
src/test/run-pass/cycle-collection2.rs
Normal file
10
src/test/run-pass/cycle-collection2.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
type foo = { mutable z : fn@() };
|
||||||
|
|
||||||
|
fn nop() { }
|
||||||
|
fn nop_foo(_x : @foo) { }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let w = @{ mutable z: bind nop() };
|
||||||
|
let x = bind nop_foo(w);
|
||||||
|
w.z = x;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user