diff --git a/src/rt/rust_cc.cpp b/src/rt/rust_cc.cpp index 11f8332bcd7f..84fb6e8456fa 100644 --- a/src/rt/rust_cc.cpp +++ b/src/rt/rust_cc.cpp @@ -164,20 +164,20 @@ irc::walk_variant(shape::tag_info &tinfo, uint32_t variant_id, void irc::compute_ircs(rust_task *task, irc_map &ircs) { - std::map::iterator begin(task->local_allocs.begin()), - end(task->local_allocs.end()); + std::map::iterator + begin(task->local_allocs.begin()), end(task->local_allocs.end()); while (begin != end) { uint8_t *p = reinterpret_cast(begin->first); p += sizeof(uintptr_t); // Skip over the reference count. - type_desc *tydesc = begin->second; + const type_desc *tydesc = begin->second; //DPRINT("determining internal ref counts: %p, tydesc=%p\n", p, //tydesc); shape::arena arena; shape::type_param *params = - shape::type_param::from_tydesc(tydesc, arena); + shape::type_param::from_tydesc(&tydesc, arena); irc irc(task, true, tydesc->shape, params, tydesc->shape_tables, p, ircs); irc.walk(); @@ -197,8 +197,8 @@ irc::compute_ircs(rust_task *task, irc_map &ircs) { void find_roots(rust_task *task, irc_map &ircs, std::vector &roots) { - std::map::iterator begin(task->local_allocs.begin()), - end(task->local_allocs.end()); + std::map::iterator + begin(task->local_allocs.begin()), end(task->local_allocs.end()); while (begin != end) { void *alloc = begin->first; uintptr_t *ref_count_ptr = reinterpret_cast(alloc); @@ -376,13 +376,13 @@ mark::do_mark(rust_task *task, const std::vector &roots, uint8_t *p = reinterpret_cast(alloc); p += sizeof(uintptr_t); // Skip over the reference count. - type_desc *tydesc = task->local_allocs[*begin]; + const type_desc *tydesc = task->local_allocs[*begin]; //DPRINT("marking: %p, tydesc=%p\n", p, tydesc); shape::arena arena; shape::type_param *params = - shape::type_param::from_tydesc(tydesc, arena); + shape::type_param::from_tydesc(&tydesc, arena); #if 0 shape::log log(task, true, tydesc->shape, params, @@ -403,8 +403,8 @@ mark::do_mark(rust_task *task, const std::vector &roots, void sweep(rust_task *task, const std::set &marked) { - std::map::iterator begin(task->local_allocs.begin()), - end(task->local_allocs.end()); + std::map::iterator + begin(task->local_allocs.begin()), end(task->local_allocs.end()); while (begin != end) { void *alloc = begin->first; if (marked.find(alloc) == marked.end()) { diff --git a/src/rt/rust_gc.cpp b/src/rt/rust_gc.cpp index 8a13b20fc217..6e6a5dd766f0 100644 --- a/src/rt/rust_gc.cpp +++ b/src/rt/rust_gc.cpp @@ -38,11 +38,11 @@ struct frame { struct root_info { intptr_t frame_offset; uintptr_t dynamic; // 0 = static, 1 = dynamic - type_desc *tydesc; + const type_desc *tydesc; }; struct root { - type_desc *tydesc; + const type_desc *tydesc; uint8_t *data; root(const root_info &info, const frame &frame) @@ -117,8 +117,8 @@ gc::mark(std::vector &roots) { DPRINT("root: %p\n", ri->data); shape::arena arena; - shape::type_param *params = shape::type_param::from_tydesc(ri->tydesc, - arena); + shape::type_param *params = + shape::type_param::from_tydesc(&ri->tydesc, arena); shape::log log(task, true, ri->tydesc->shape, params, ri->tydesc->shape_tables, ri->data, std::cerr); log.walk(); diff --git a/src/rt/rust_obstack.cpp b/src/rt/rust_obstack.cpp index fc11eed86f4b..99e72489f5fc 100644 --- a/src/rt/rust_obstack.cpp +++ b/src/rt/rust_obstack.cpp @@ -161,8 +161,8 @@ rust_obstack::dump() const { while (b != e) { std::pair data = *b; shape::arena arena; - shape::type_param *params = shape::type_param::from_tydesc(data.first, - arena); + shape::type_param *params = + shape::type_param::from_tydesc(&data.first, arena); shape::log log(task, true, data.first->shape, params, data.first->shape_tables, reinterpret_cast(data.second), std::cerr); diff --git a/src/rt/rust_shape.cpp b/src/rt/rust_shape.cpp index c6ee35717dc9..d25c340264e6 100644 --- a/src/rt/rust_shape.cpp +++ b/src/rt/rust_shape.cpp @@ -37,7 +37,7 @@ type_param::make(const type_desc **tydescs, unsigned n_tydescs, const type_desc *subtydesc = tydescs[i]; ptrs[i].shape = subtydesc->shape; ptrs[i].tables = subtydesc->shape_tables; - ptrs[i].params = from_tydesc(subtydesc, arena); + ptrs[i].params = from_tydesc(&subtydesc, arena); } return ptrs; } @@ -527,11 +527,12 @@ log::walk_res(const rust_fn *dtor, unsigned n_params, } // end namespace shape extern "C" void -upcall_cmp_type(int8_t *result, rust_task *task, type_desc *tydesc, +upcall_cmp_type(int8_t *result, rust_task *task, const type_desc *tydesc, const type_desc **subtydescs, uint8_t *data_0, uint8_t *data_1, uint8_t cmp_type) { shape::arena arena; - shape::type_param *params = shape::type_param::from_tydesc(tydesc, arena); + shape::type_param *params = + shape::type_param::from_tydesc(&tydesc, arena); shape::cmp cmp(task, true, tydesc->shape, params, tydesc->shape_tables, data_0, data_1); cmp.walk(); @@ -544,13 +545,14 @@ upcall_cmp_type(int8_t *result, rust_task *task, type_desc *tydesc, } extern "C" void -upcall_log_type(rust_task *task, type_desc *tydesc, uint8_t *data, +upcall_log_type(rust_task *task, const type_desc *tydesc, uint8_t *data, uint32_t level) { if (task->sched->log_lvl < level) return; // TODO: Don't evaluate at all? shape::arena arena; - shape::type_param *params = shape::type_param::from_tydesc(tydesc, arena); + shape::type_param *params = + shape::type_param::from_tydesc(&tydesc, arena); std::stringstream ss; shape::log log(task, true, tydesc->shape, params, tydesc->shape_tables, diff --git a/src/rt/rust_shape.h b/src/rt/rust_shape.h index 1f1490a36c8a..357786ae2ce6 100644 --- a/src/rt/rust_shape.h +++ b/src/rt/rust_shape.h @@ -310,12 +310,27 @@ public: } // Creates type parameters from a type descriptor. - static inline type_param *from_tydesc(const type_desc *tydesc, + static inline type_param *from_tydesc(const type_desc **tydesc, arena &arena) { - if (tydesc->n_obj_params) { - // TODO + if ((*tydesc)->n_obj_params) { + uintptr_t n_obj_params = (*tydesc)->n_obj_params; + const type_desc **first_param; + if (n_obj_params & 0x80000000) { + // Function closure. + DPRINT("n_obj_params FN %lu, tydesc %p, starting at %p\n", + n_obj_params, tydesc, tydesc + 4); + n_obj_params &= 0x7fffffff; + first_param = (const type_desc **) + ((uint8_t *)(tydesc + 4) + (*tydesc)->size); + } else { + // Object closure. + DPRINT("n_obj_params OBJ %lu, tydesc %p, starting at %p\n", + n_obj_params, tydesc, tydesc + 4); + first_param = tydesc + 4; + } } - return make(tydesc->first_param, tydesc->n_params, arena); + + return make((*tydesc)->first_param, (*tydesc)->n_params, arena); } }; diff --git a/src/rt/rust_task.h b/src/rt/rust_task.h index 05c34cec587a..047fbd2b58ff 100644 --- a/src/rt/rust_task.h +++ b/src/rt/rust_task.h @@ -115,7 +115,7 @@ rust_task : public kernel_owned, rust_cond rust_obstack dynastack; - std::map local_allocs; + std::map local_allocs; // Only a pointer to 'name' is kept, so it must live as long as this task. rust_task(rust_scheduler *sched,