rt: Get rid of the hack that looks for captured type descriptors adjacent to the root one for functions and objects

This commit is contained in:
Patrick Walton 2011-09-23 16:51:50 -07:00
parent 6164de90e2
commit 0c4e0fdfae
5 changed files with 52 additions and 28 deletions

View file

@ -169,7 +169,6 @@ irc::compute_ircs(rust_task *task, irc_map &ircs) {
begin(task->local_allocs.begin()), end(task->local_allocs.end());
while (begin != end) {
uint8_t *p = reinterpret_cast<uint8_t *>(begin->first);
p += sizeof(uintptr_t); // Skip over the reference count.
const type_desc *tydesc = begin->second;
@ -178,9 +177,9 @@ irc::compute_ircs(rust_task *task, irc_map &ircs) {
shape::arena arena;
shape::type_param *params =
shape::type_param::from_tydesc(&tydesc, arena);
irc irc(task, true, tydesc->shape, params, tydesc->shape_tables, p,
ircs);
shape::type_param::from_tydesc_and_data(tydesc, p, arena);
irc irc(task, true, tydesc->shape, params, tydesc->shape_tables,
p + sizeof(uintptr_t), ircs);
irc.walk();
#if 0
@ -374,26 +373,25 @@ mark::do_mark(rust_task *task, const std::vector<void *> &roots,
if (marked.find(alloc) == marked.end()) {
marked.insert(alloc);
uint8_t *p = reinterpret_cast<uint8_t *>(alloc);
p += sizeof(uintptr_t); // Skip over the reference count.
const type_desc *tydesc = task->local_allocs[*begin];
const type_desc *tydesc = task->local_allocs[alloc];
//DPRINT("marking: %p, tydesc=%p\n", p, tydesc);
uint8_t *p = reinterpret_cast<uint8_t *>(alloc);
shape::arena arena;
shape::type_param *params =
shape::type_param::from_tydesc(&tydesc, arena);
shape::type_param::from_tydesc_and_data(tydesc, p, arena);
#if 0
// We skip over the reference count here.
shape::log log(task, true, tydesc->shape, params,
tydesc->shape_tables, p, std::cerr);
tydesc->shape_tables, p + sizeof(uintptr_t),
std::cerr);
log.walk();
DPRINT("\n");
#endif
// We skip over the reference count here.
mark mark(task, true, tydesc->shape, params, tydesc->shape_tables,
p, marked);
p + sizeof(uintptr_t), marked);
mark.walk();
}

View file

@ -105,7 +105,8 @@ gc::mark(std::vector<root> &roots) {
shape::arena arena;
shape::type_param *params =
shape::type_param::from_tydesc(&ri->tydesc, arena);
shape::type_param::from_tydesc_and_data(ri->tydesc, ri->data,
arena);
shape::log log(task, true, ri->tydesc->shape, params,
ri->tydesc->shape_tables, ri->data, std::cerr);
log.walk();

View file

@ -160,12 +160,13 @@ rust_obstack::dump() const {
iterator b = begin(), e = end();
while (b != e) {
std::pair<const type_desc *,void *> data = *b;
uint8_t *dp = reinterpret_cast<uint8_t *>(data.second);
shape::arena arena;
shape::type_param *params =
shape::type_param::from_tydesc(&data.first, arena);
shape::type_param::from_tydesc_and_data(data.first, dp, arena);
shape::log log(task, true, data.first->shape, params,
data.first->shape_tables,
reinterpret_cast<uint8_t *>(data.second), std::cerr);
data.first->shape_tables, dp, std::cerr);
log.walk();
std::cerr << "\n";

View file

@ -37,7 +37,10 @@ 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);
// FIXME: Doesn't handle a type-parametric object closing over a
// type-parametric object type properly.
ptrs[i].params = from_tydesc(subtydesc, arena);
}
return ptrs;
}
@ -531,8 +534,12 @@ 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;
// FIXME: This may well be broken when comparing two closures or objects
// that close over different sets of type parameters.
shape::type_param *params =
shape::type_param::from_tydesc(&tydesc, arena);
shape::type_param::from_tydesc_and_data(tydesc, data_0, arena);
shape::cmp cmp(task, true, tydesc->shape, params, tydesc->shape_tables,
data_0, data_1);
cmp.walk();
@ -552,7 +559,7 @@ upcall_log_type(rust_task *task, const type_desc *tydesc, uint8_t *data,
shape::arena arena;
shape::type_param *params =
shape::type_param::from_tydesc(&tydesc, arena);
shape::type_param::from_tydesc_and_data(tydesc, data, arena);
std::stringstream ss;
shape::log log(task, true, tydesc->shape, params, tydesc->shape_tables,

View file

@ -310,27 +310,44 @@ 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) {
uintptr_t n_obj_params = (*tydesc)->n_obj_params;
// In order to find the type parameters of objects and functions, we
// have to actually have the data pointer, since we don't statically
// know from the type of an object or function which type parameters
// it closes over.
assert(!tydesc->n_obj_params && "Type-parametric objects and "
"functions must go through from_tydesc_and_data() instead!");
return make(tydesc->first_param, tydesc->n_params, arena);
}
static type_param *from_tydesc_and_data(const type_desc *tydesc,
uint8_t *dp, arena &arena) {
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",
(unsigned long)n_obj_params, tydesc, tydesc + 4);
(unsigned long)n_obj_params, tydesc,
dp + sizeof(uintptr_t) + tydesc->size);
n_obj_params &= 0x7fffffff;
// FIXME: Is this right?
first_param = (const type_desc **)
((uint8_t *)(tydesc + 4) + (*tydesc)->size);
(dp + sizeof(uintptr_t) + tydesc->size);
} else {
// Object closure.
DPRINT("n_obj_params OBJ %lu, tydesc %p, starting at %p\n",
(unsigned long)n_obj_params, tydesc, tydesc + 4);
first_param = tydesc + 4;
(unsigned long)n_obj_params, tydesc,
dp + sizeof(uintptr_t) * 2);
first_param = (const type_desc **)
(dp + sizeof(uintptr_t) * 2);
}
return make(first_param, n_obj_params, arena);
}
return make((*tydesc)->first_param, (*tydesc)->n_params, arena);
return make(tydesc->first_param, tydesc->n_params, arena);
}
};