diff options
| author | Brian Anderson <banderson@mozilla.com> | 2012-03-26 16:27:35 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2012-03-29 16:43:18 -0700 |
| commit | 3ff01361d578d611d3b09c3abca059f7cecd204c (patch) | |
| tree | 411b2b7314b256678d931e93ff75fe4eed026fa7 /src/rt/rust_cc.cpp | |
| parent | ad26b00696afb1b74a636fa02e2600485a914d47 (diff) | |
| download | rust-3ff01361d578d611d3b09c3abca059f7cecd204c.tar.gz rust-3ff01361d578d611d3b09c3abca059f7cecd204c.zip | |
rt: Make the CC sweep use the box annihilator
Diffstat (limited to 'src/rt/rust_cc.cpp')
| -rw-r--r-- | src/rt/rust_cc.cpp | 197 |
1 files changed, 7 insertions, 190 deletions
diff --git a/src/rt/rust_cc.cpp b/src/rt/rust_cc.cpp index c727aec694e..7403c077d5d 100644 --- a/src/rt/rust_cc.cpp +++ b/src/rt/rust_cc.cpp @@ -20,6 +20,9 @@ using namespace std; +void +annihilate_box(rust_task *task, rust_opaque_box *box); + namespace cc { // Internal reference count computation @@ -448,183 +451,9 @@ mark::do_mark(rust_task *task, } } -class sweep : public shape::data<sweep,shape::ptr> { - friend class shape::data<sweep,shape::ptr>; - - sweep(const sweep &other, const shape::ptr &in_dp) - : shape::data<sweep,shape::ptr>(other.task, other.align, - other.sp, other.params, - other.tables, in_dp) {} - - sweep(const sweep &other, - const uint8_t *in_sp, - const shape::type_param *in_params, - const rust_shape_tables *in_tables = NULL) - : shape::data<sweep,shape::ptr>(other.task, - other.align, - in_sp, - in_params, - in_tables ? in_tables : other.tables, - other.dp) {} - - sweep(const sweep &other, - const uint8_t *in_sp, - const shape::type_param *in_params, - const rust_shape_tables *in_tables, - shape::ptr in_dp) - : shape::data<sweep,shape::ptr>(other.task, - other.align, - in_sp, - in_params, - in_tables, - in_dp) {} - - sweep(rust_task *in_task, - bool in_align, - const uint8_t *in_sp, - const shape::type_param *in_params, - const rust_shape_tables *in_tables, - uint8_t *in_data) - : shape::data<sweep,shape::ptr>(in_task, in_align, in_sp, - in_params, in_tables, in_data) {} - - void walk_vec2(bool is_pod, uint16_t sp_size) { - void *vec = shape::get_dp<void *>(dp); - walk_vec2(is_pod, get_vec_data_range(dp)); - task->kernel->free(vec); - } - - void walk_vec2(bool is_pod, - const std::pair<shape::ptr,shape::ptr> &data_range) { - sweep sub(*this, data_range.first); - shape::ptr data_end = sub.end_dp = data_range.second; - while (sub.dp < data_end) { - sub.walk_reset(); - sub.align = true; - } - } - - void walk_tag2(shape::tag_info &tinfo, uint32_t tag_variant) { - shape::data<sweep,shape::ptr>::walk_variant1(tinfo, tag_variant); - } - - void walk_uniq2() { - void *x = *((void **)dp); - // free contents first: - shape::data<sweep,shape::ptr>::walk_uniq_contents1(); - // now free the ptr: - task->kernel->free(x); - } - - void walk_box2() { - // In sweep phase, do not walk the box contents. There is an - // outer loop walking all remaining boxes, and this box may well - // have been freed already! - } - - void walk_fn2(char code) { - switch (code) { - case shape::SHAPE_UNIQ_FN: { - fn_env_pair pair = *(fn_env_pair*)dp; - - if (pair.env) { - // free closed over data: - shape::data<sweep,shape::ptr>::walk_fn_contents1(); - - // now free the ptr: - task->kernel->free(pair.env); - } - break; - } - case shape::SHAPE_BOX_FN: { - // the box will be visited separately: - shape::bump_dp<void*>(dp); // skip over the code ptr - walk_box2(); // walk over the environment ptr - break; - } - case shape::SHAPE_BARE_FN: // Does not close over data. - case shape::SHAPE_STACK_FN: break; // Not reachable from heap. - default: abort(); - } - } - - void walk_obj2() { - return; - } - - void walk_iface2() { - walk_box2(); - } - - void walk_tydesc2(char kind) { - switch(kind) { - case shape::SHAPE_TYDESC: - case shape::SHAPE_SEND_TYDESC: - break; - default: abort(); - } - } - - struct run_dtor_args { - const shape::rust_fn *dtor; - void *data; - }; - - typedef void (*dtor)(void **retptr, void *env, void *dptr); - - static void run_dtor(run_dtor_args *args) { - dtor f = (dtor)args->dtor; - f(NULL, args->dtor->env, args->data); - } - - void walk_res2(const shape::rust_fn *dtor, unsigned n_params, - const shape::type_param *params, const uint8_t *end_sp, - bool live) { - void *data = (void*)(uintptr_t)dp; - // Switch back to the Rust stack to run the destructor - run_dtor_args args = {dtor, data}; - task->call_on_rust_stack((void*)&args, (void*)run_dtor); - - while (this->sp != end_sp) { - this->walk(); - align = true; - } - } - - void walk_subcontext2(sweep &sub) { sub.walk(); } - - void walk_uniq_contents2(sweep &sub) { sub.walk(); } - - void walk_struct2(const uint8_t *end_sp) { - while (this->sp != end_sp) { - this->walk(); - align = true; - } - } - - void walk_variant2(shape::tag_info &tinfo, uint32_t variant_id, - const std::pair<const uint8_t *,const uint8_t *> - variant_ptr_and_end) { - sweep sub(*this, variant_ptr_and_end.first, tinfo.params); - - const uint8_t *variant_end = variant_ptr_and_end.second; - while (sub.sp < variant_end) { - sub.walk(); - align = true; - } - } - - template<typename T> - inline void walk_number2() { /* no-op */ } - -public: - static void do_sweep(rust_task *task, - const std::set<rust_opaque_box*> &marked); -}; - void -sweep::do_sweep(rust_task *task, - const std::set<rust_opaque_box*> &marked) { +do_sweep(rust_task *task, + const std::set<rust_opaque_box*> &marked) { boxed_region *boxed = &task->boxed; rust_opaque_box *box = boxed->first_live_alloc(); while (box != NULL) { @@ -632,19 +461,7 @@ sweep::do_sweep(rust_task *task, rust_opaque_box *box_next = box->next; if (marked.find(box) == marked.end()) { LOG(task, gc, "object is part of a cycle: %p", box); - - const type_desc *tydesc = box->td; - uint8_t *p = (uint8_t*) box_body(box); - shape::arena arena; - shape::type_param *params = - shape::type_param::from_tydesc_and_data(tydesc, p, arena); - - sweep sweep(task, true, tydesc->shape, - params, tydesc->shape_tables, - p); - sweep.walk(); - - boxed->free(box); + annihilate_box(task, box); } box = box_next; } @@ -664,7 +481,7 @@ do_cc(rust_task *task) { std::set<rust_opaque_box*> marked; mark::do_mark(task, roots, marked); - sweep::do_sweep(task, marked); + do_sweep(task, marked); } void |
