free uniq data we encounter on the sweep, walk thru them otherwise
This commit is contained in:
parent
f4a3a3b878
commit
e55aa6e5ef
|
@ -46,13 +46,18 @@ const shape_vec: u8 = 11u8;
|
|||
const shape_tag: u8 = 12u8;
|
||||
const shape_box: u8 = 13u8;
|
||||
const shape_struct: u8 = 17u8;
|
||||
const shape_fn: u8 = 18u8;
|
||||
const shape_box_fn: u8 = 18u8;
|
||||
const shape_obj: u8 = 19u8;
|
||||
const shape_res: u8 = 20u8;
|
||||
const shape_var: u8 = 21u8;
|
||||
const shape_uniq: u8 = 22u8;
|
||||
const shape_opaque_closure_ptr: u8 = 23u8; // the closure itself.
|
||||
const shape_iface: u8 = 24u8;
|
||||
const shape_uniq_fn: u8 = 25u8;
|
||||
const shape_stack_fn: u8 = 26u8;
|
||||
const shape_bare_fn: u8 = 27u8;
|
||||
const shape_tydesc: u8 = 28u8;
|
||||
const shape_send_tydesc: u8 = 29u8;
|
||||
|
||||
// FIXME: This is a bad API in trans_common.
|
||||
fn C_u8(n: u8) -> ValueRef { ret trans_common::C_u8(n as uint); }
|
||||
|
@ -267,6 +272,14 @@ fn s_variant_tag_t(tcx: ty_ctxt) -> u8 {
|
|||
ret s_int(tcx);
|
||||
}
|
||||
|
||||
fn s_tydesc(_tcx: ty_ctxt) -> u8 {
|
||||
ret shape_tydesc;
|
||||
}
|
||||
|
||||
fn s_send_tydesc(_tcx: ty_ctxt) -> u8 {
|
||||
ret shape_send_tydesc;
|
||||
}
|
||||
|
||||
fn mk_ctxt(llmod: ModuleRef) -> ctxt {
|
||||
let llshapetablesty = trans_common::T_named_struct("shapes");
|
||||
let llshapetables =
|
||||
|
@ -305,8 +318,10 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint],
|
|||
ty::ty_bot. { s += [shape_u8]; }
|
||||
ty::ty_int(ast::ty_i.) { s += [s_int(ccx.tcx)]; }
|
||||
ty::ty_float(ast::ty_f.) { s += [s_float(ccx.tcx)]; }
|
||||
ty::ty_uint(ast::ty_u.) | ty::ty_ptr(_) | ty::ty_type. |
|
||||
ty::ty_send_type. | ty::ty_native(_) { s += [s_uint(ccx.tcx)]; }
|
||||
ty::ty_uint(ast::ty_u.) | ty::ty_ptr(_) |
|
||||
ty::ty_native(_) { s += [s_uint(ccx.tcx)]; }
|
||||
ty::ty_type. { s += [s_tydesc(ccx.tcx)]; }
|
||||
ty::ty_send_type. { s += [s_send_tydesc(ccx.tcx)]; }
|
||||
ty::ty_int(ast::ty_i8.) { s += [shape_i8]; }
|
||||
ty::ty_uint(ast::ty_u16.) { s += [shape_u16]; }
|
||||
ty::ty_int(ast::ty_i16.) { s += [shape_i16]; }
|
||||
|
@ -418,8 +433,17 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint],
|
|||
}
|
||||
}
|
||||
}
|
||||
ty::ty_fn(_) {
|
||||
s += [shape_fn];
|
||||
ty::ty_fn({proto: ast::proto_box., _}) {
|
||||
s += [shape_box_fn];
|
||||
}
|
||||
ty::ty_fn({proto: ast::proto_uniq., _}) {
|
||||
s += [shape_uniq_fn];
|
||||
}
|
||||
ty::ty_fn({proto: ast::proto_block., _}) {
|
||||
s += [shape_stack_fn];
|
||||
}
|
||||
ty::ty_fn({proto: ast::proto_bare., _}) {
|
||||
s += [shape_bare_fn];
|
||||
}
|
||||
ty::ty_opaque_closure_ptr(_) {
|
||||
s += [shape_opaque_closure_ptr];
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
// collection.
|
||||
#define RUST_CC_FREQUENCY 5000
|
||||
|
||||
// defined in rust_upcall.cpp:
|
||||
void upcall_s_free_shared_type_desc(type_desc *td);
|
||||
|
||||
namespace cc {
|
||||
|
||||
// Internal reference count computation
|
||||
|
@ -70,7 +73,7 @@ class irc : public shape::data<irc,shape::ptr> {
|
|||
in_tables, in_data),
|
||||
ircs(in_ircs) {}
|
||||
|
||||
void walk_vec(bool is_pod, uint16_t sp_size) {
|
||||
void walk_vec2(bool is_pod, uint16_t sp_size) {
|
||||
if (is_pod || shape::get_dp<void *>(dp) == NULL)
|
||||
return; // There can't be any outbound pointers from this.
|
||||
|
||||
|
@ -86,47 +89,63 @@ class irc : public shape::data<irc,shape::ptr> {
|
|||
}
|
||||
}
|
||||
|
||||
void walk_tag(shape::tag_info &tinfo, uint32_t tag_variant) {
|
||||
shape::data<irc,shape::ptr>::walk_variant(tinfo, tag_variant);
|
||||
void walk_tag2(shape::tag_info &tinfo, uint32_t tag_variant) {
|
||||
shape::data<irc,shape::ptr>::walk_variant1(tinfo, tag_variant);
|
||||
}
|
||||
|
||||
void walk_box() {
|
||||
shape::data<irc,shape::ptr>::walk_box_contents();
|
||||
void walk_box2() {
|
||||
shape::data<irc,shape::ptr>::walk_box_contents1();
|
||||
}
|
||||
|
||||
void walk_fn() {
|
||||
// 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_uniq2() {
|
||||
shape::data<irc,shape::ptr>::walk_uniq_contents1();
|
||||
}
|
||||
|
||||
void walk_obj() {
|
||||
void walk_fn2(char code) {
|
||||
switch (code) {
|
||||
case shape::SHAPE_BOX_FN: {
|
||||
// Record an irc for the environment box, but don't descend
|
||||
// into it since it will be walked via the box's allocation
|
||||
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: // Not reachable from heap.
|
||||
case shape::SHAPE_UNIQ_FN: break; /* Can only close over sendable
|
||||
* (and hence acyclic) data */
|
||||
default: abort();
|
||||
}
|
||||
}
|
||||
|
||||
void walk_obj2() {
|
||||
dp += sizeof(void *); // skip vtable
|
||||
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_iface() {
|
||||
//shape::data<irc,shape::ptr>::walk_iface_contents(dp);
|
||||
shape::data<irc,shape::ptr>::walk_box_contents();
|
||||
void walk_iface2() {
|
||||
walk_box2();
|
||||
}
|
||||
|
||||
void walk_res(const shape::rust_fn *dtor, unsigned n_params,
|
||||
const shape::type_param *params, const uint8_t *end_sp,
|
||||
bool live) {
|
||||
void walk_tydesc2(char) {
|
||||
}
|
||||
|
||||
void walk_res2(const shape::rust_fn *dtor, unsigned n_params,
|
||||
const shape::type_param *params, const uint8_t *end_sp,
|
||||
bool live) {
|
||||
while (this->sp != end_sp) {
|
||||
this->walk();
|
||||
align = true;
|
||||
}
|
||||
}
|
||||
|
||||
void walk_subcontext(irc &sub) { sub.walk(); }
|
||||
void walk_subcontext2(irc &sub) { sub.walk(); }
|
||||
|
||||
void walk_box_contents(irc &sub, shape::ptr &ref_count_dp) {
|
||||
void walk_uniq_contents2(irc &sub) { sub.walk(); }
|
||||
|
||||
void walk_box_contents2(irc &sub, shape::ptr &ref_count_dp) {
|
||||
maybe_record_irc(ref_count_dp);
|
||||
|
||||
// Do not traverse the contents of this box; it's in the allocation
|
||||
|
@ -153,28 +172,28 @@ class irc : public shape::data<irc,shape::ptr> {
|
|||
}
|
||||
}
|
||||
|
||||
void walk_struct(const uint8_t *end_sp) {
|
||||
void walk_struct2(const uint8_t *end_sp) {
|
||||
while (this->sp != end_sp) {
|
||||
this->walk();
|
||||
align = true;
|
||||
}
|
||||
}
|
||||
|
||||
void walk_variant(shape::tag_info &tinfo, uint32_t variant_id,
|
||||
void walk_variant2(shape::tag_info &tinfo, uint32_t variant_id,
|
||||
const std::pair<const uint8_t *,const uint8_t *>
|
||||
variant_ptr_and_end);
|
||||
|
||||
template<typename T>
|
||||
inline void walk_number() { /* no-op */ }
|
||||
inline void walk_number2() { /* no-op */ }
|
||||
|
||||
public:
|
||||
static void compute_ircs(rust_task *task, irc_map &ircs);
|
||||
};
|
||||
|
||||
void
|
||||
irc::walk_variant(shape::tag_info &tinfo, uint32_t variant_id,
|
||||
const std::pair<const uint8_t *,const uint8_t *>
|
||||
variant_ptr_and_end) {
|
||||
irc::walk_variant2(shape::tag_info &tinfo, uint32_t variant_id,
|
||||
const std::pair<const uint8_t *,const uint8_t *>
|
||||
variant_ptr_and_end) {
|
||||
irc sub(*this, variant_ptr_and_end.first, tinfo.params);
|
||||
|
||||
assert(variant_id < 256); // FIXME: Temporary sanity check.
|
||||
|
@ -305,7 +324,7 @@ class mark : public shape::data<mark,shape::ptr> {
|
|||
in_tables, in_data),
|
||||
marked(in_marked) {}
|
||||
|
||||
void walk_vec(bool is_pod, uint16_t sp_size) {
|
||||
void walk_vec2(bool is_pod, uint16_t sp_size) {
|
||||
if (is_pod || shape::get_dp<void *>(dp) == NULL)
|
||||
return; // There can't be any outbound pointers from this.
|
||||
|
||||
|
@ -321,23 +340,39 @@ class mark : public shape::data<mark,shape::ptr> {
|
|||
}
|
||||
}
|
||||
|
||||
void walk_tag(shape::tag_info &tinfo, uint32_t tag_variant) {
|
||||
shape::data<mark,shape::ptr>::walk_variant(tinfo, tag_variant);
|
||||
void walk_tag2(shape::tag_info &tinfo, uint32_t tag_variant) {
|
||||
shape::data<mark,shape::ptr>::walk_variant1(tinfo, tag_variant);
|
||||
}
|
||||
|
||||
void walk_box() {
|
||||
shape::data<mark,shape::ptr>::walk_box_contents();
|
||||
void walk_box2() {
|
||||
shape::data<mark,shape::ptr>::walk_box_contents1();
|
||||
}
|
||||
|
||||
void walk_fn() {
|
||||
shape::data<mark,shape::ptr>::walk_fn_contents(dp);
|
||||
void walk_uniq2() {
|
||||
shape::data<mark,shape::ptr>::walk_uniq_contents1();
|
||||
}
|
||||
|
||||
void walk_obj() {
|
||||
shape::data<mark,shape::ptr>::walk_obj_contents(dp);
|
||||
void walk_fn2(char code) {
|
||||
switch (code) {
|
||||
case shape::SHAPE_BOX_FN: {
|
||||
// Record an irc for the environment box, but don't descend
|
||||
// into it since it will be walked via the box's allocation
|
||||
shape::data<mark,shape::ptr>::walk_fn_contents1(dp);
|
||||
break;
|
||||
}
|
||||
case shape::SHAPE_BARE_FN: // Does not close over data.
|
||||
case shape::SHAPE_STACK_FN: // Not reachable from heap.
|
||||
case shape::SHAPE_UNIQ_FN: break; /* Can only close over sendable
|
||||
* (and hence acyclic) data */
|
||||
default: abort();
|
||||
}
|
||||
}
|
||||
|
||||
void walk_res(const shape::rust_fn *dtor, unsigned n_params,
|
||||
void walk_obj2() {
|
||||
shape::data<mark,shape::ptr>::walk_obj_contents1(dp);
|
||||
}
|
||||
|
||||
void walk_res2(const shape::rust_fn *dtor, unsigned n_params,
|
||||
const shape::type_param *params, const uint8_t *end_sp,
|
||||
bool live) {
|
||||
while (this->sp != end_sp) {
|
||||
|
@ -346,9 +381,18 @@ class mark : public shape::data<mark,shape::ptr> {
|
|||
}
|
||||
}
|
||||
|
||||
void walk_subcontext(mark &sub) { sub.walk(); }
|
||||
void walk_iface2() {
|
||||
walk_box2();
|
||||
}
|
||||
|
||||
void walk_box_contents(mark &sub, shape::ptr &ref_count_dp) {
|
||||
void walk_tydesc2(char) {
|
||||
}
|
||||
|
||||
void walk_subcontext2(mark &sub) { sub.walk(); }
|
||||
|
||||
void walk_uniq_contents2(mark &sub) { sub.walk(); }
|
||||
|
||||
void walk_box_contents2(mark &sub, shape::ptr &ref_count_dp) {
|
||||
if (!ref_count_dp)
|
||||
return;
|
||||
|
||||
|
@ -359,19 +403,19 @@ class mark : public shape::data<mark,shape::ptr> {
|
|||
sub.walk();
|
||||
}
|
||||
|
||||
void walk_struct(const uint8_t *end_sp) {
|
||||
void walk_struct2(const uint8_t *end_sp) {
|
||||
while (this->sp != end_sp) {
|
||||
this->walk();
|
||||
align = true;
|
||||
}
|
||||
}
|
||||
|
||||
void walk_variant(shape::tag_info &tinfo, uint32_t variant_id,
|
||||
void walk_variant2(shape::tag_info &tinfo, uint32_t variant_id,
|
||||
const std::pair<const uint8_t *,const uint8_t *>
|
||||
variant_ptr_and_end);
|
||||
|
||||
template<typename T>
|
||||
inline void walk_number() { /* no-op */ }
|
||||
inline void walk_number2() { /* no-op */ }
|
||||
|
||||
public:
|
||||
static void do_mark(rust_task *task, const std::vector<void *> &roots,
|
||||
|
@ -379,7 +423,7 @@ public:
|
|||
};
|
||||
|
||||
void
|
||||
mark::walk_variant(shape::tag_info &tinfo, uint32_t variant_id,
|
||||
mark::walk_variant2(shape::tag_info &tinfo, uint32_t variant_id,
|
||||
const std::pair<const uint8_t *,const uint8_t *>
|
||||
variant_ptr_and_end) {
|
||||
mark sub(*this, variant_ptr_and_end.first, tinfo.params);
|
||||
|
@ -470,13 +514,13 @@ class sweep : public shape::data<sweep,shape::ptr> {
|
|||
: shape::data<sweep,shape::ptr>(in_task, in_align, in_sp,
|
||||
in_params, in_tables, in_data) {}
|
||||
|
||||
void walk_vec(bool is_pod, uint16_t sp_size) {
|
||||
void walk_vec2(bool is_pod, uint16_t sp_size) {
|
||||
void *vec = shape::get_dp<void *>(dp);
|
||||
walk_vec(is_pod, get_vec_data_range(dp));
|
||||
walk_vec2(is_pod, get_vec_data_range(dp));
|
||||
task->kernel->free(vec);
|
||||
}
|
||||
|
||||
void walk_vec(bool is_pod,
|
||||
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;
|
||||
|
@ -486,50 +530,99 @@ class sweep : public shape::data<sweep,shape::ptr> {
|
|||
}
|
||||
}
|
||||
|
||||
void walk_tag(shape::tag_info &tinfo, uint32_t tag_variant) {
|
||||
shape::data<sweep,shape::ptr>::walk_variant(tinfo, tag_variant);
|
||||
void walk_tag2(shape::tag_info &tinfo, uint32_t tag_variant) {
|
||||
shape::data<sweep,shape::ptr>::walk_variant1(tinfo, tag_variant);
|
||||
}
|
||||
|
||||
void walk_box() {
|
||||
shape::data<sweep,shape::ptr>::walk_box_contents();
|
||||
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_fn() {
|
||||
void walk_box2() {
|
||||
shape::data<sweep,shape::ptr>::walk_box_contents1();
|
||||
}
|
||||
|
||||
void walk_fn2(char code) {
|
||||
switch (code) {
|
||||
case shape::SHAPE_UNIQ_FN: {
|
||||
fn_env_pair pair = *(fn_env_pair*)dp;
|
||||
|
||||
// free closed over data:
|
||||
//
|
||||
// FIXME--this is a bit sketchy, since there is an
|
||||
// embedded tydesc that we will be using to walk the
|
||||
// data, but it will be freed as we walk. In the
|
||||
// generated code we pull this desc out and free it
|
||||
// later. We may well want to do the same. However,
|
||||
// since all we use from the descr. is the "shape", I
|
||||
// think we're ok.
|
||||
shape::data<sweep,shape::ptr>::walk_fn_contents1(dp);
|
||||
|
||||
// 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_obj() {
|
||||
return;
|
||||
void walk_iface2() {
|
||||
walk_box2();
|
||||
}
|
||||
|
||||
void walk_iface() {
|
||||
//shape::data<sweep,shape::ptr>::walk_iface_contents(dp);
|
||||
shape::data<sweep,shape::ptr>::walk_box_contents();
|
||||
void walk_tydesc2(char kind) {
|
||||
type_desc *td = *(type_desc **)dp;
|
||||
switch(kind) {
|
||||
case shape::SHAPE_TYDESC:
|
||||
break;
|
||||
case shape::SHAPE_SEND_TYDESC:
|
||||
upcall_s_free_shared_type_desc(td);
|
||||
break;
|
||||
default: abort();
|
||||
}
|
||||
}
|
||||
|
||||
void walk_res(const shape::rust_fn *dtor, unsigned n_params,
|
||||
const shape::type_param *params, const uint8_t *end_sp,
|
||||
bool live) {
|
||||
void walk_res2(const shape::rust_fn *dtor, unsigned n_params,
|
||||
const shape::type_param *params, const uint8_t *end_sp,
|
||||
bool live) {
|
||||
while (this->sp != end_sp) {
|
||||
this->walk();
|
||||
align = true;
|
||||
}
|
||||
}
|
||||
|
||||
void walk_subcontext(sweep &sub) { sub.walk(); }
|
||||
void walk_subcontext2(sweep &sub) { sub.walk(); }
|
||||
|
||||
void walk_box_contents(sweep &sub, shape::ptr &ref_count_dp) {
|
||||
void walk_uniq_contents2(sweep &sub) { sub.walk(); }
|
||||
|
||||
void walk_box_contents2(sweep &sub, shape::ptr &ref_count_dp) {
|
||||
return;
|
||||
}
|
||||
|
||||
void walk_struct(const uint8_t *end_sp) {
|
||||
void walk_struct2(const uint8_t *end_sp) {
|
||||
while (this->sp != end_sp) {
|
||||
this->walk();
|
||||
align = true;
|
||||
}
|
||||
}
|
||||
|
||||
void walk_variant(shape::tag_info &tinfo, uint32_t variant_id,
|
||||
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);
|
||||
|
@ -542,7 +635,7 @@ class sweep : public shape::data<sweep,shape::ptr> {
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
inline void walk_number() { /* no-op */ }
|
||||
inline void walk_number2() { /* no-op */ }
|
||||
|
||||
public:
|
||||
static void do_sweep(rust_task *task, const std::set<void *> &marked);
|
||||
|
|
|
@ -73,7 +73,7 @@ type_param::from_obj_shape(const uint8_t *sp, ptr dp, arena &arena) {
|
|||
// A shape printer, useful for debugging
|
||||
|
||||
void
|
||||
print::walk_tag(tag_info &tinfo) {
|
||||
print::walk_tag1(tag_info &tinfo) {
|
||||
DPRINT("tag%u", tinfo.tag_id);
|
||||
if (!tinfo.n_params)
|
||||
return;
|
||||
|
@ -94,7 +94,7 @@ print::walk_tag(tag_info &tinfo) {
|
|||
}
|
||||
|
||||
void
|
||||
print::walk_struct(const uint8_t *end_sp) {
|
||||
print::walk_struct1(const uint8_t *end_sp) {
|
||||
DPRINT("(");
|
||||
|
||||
bool first = true;
|
||||
|
@ -110,8 +110,8 @@ print::walk_struct(const uint8_t *end_sp) {
|
|||
}
|
||||
|
||||
void
|
||||
print::walk_res(const rust_fn *dtor, unsigned n_params,
|
||||
const type_param *params, const uint8_t *end_sp) {
|
||||
print::walk_res1(const rust_fn *dtor, unsigned n_params,
|
||||
const type_param *params, const uint8_t *end_sp) {
|
||||
DPRINT("res@%p", dtor);
|
||||
|
||||
// Print type parameters.
|
||||
|
@ -151,7 +151,7 @@ print::walk_res(const rust_fn *dtor, unsigned n_params,
|
|||
}
|
||||
|
||||
void
|
||||
print::walk_var(uint8_t param_index) {
|
||||
print::walk_var1(uint8_t param_index) {
|
||||
DPRINT("%c=", 'T' + param_index);
|
||||
|
||||
const type_param *param = ¶ms[param_index];
|
||||
|
@ -160,25 +160,25 @@ print::walk_var(uint8_t param_index) {
|
|||
}
|
||||
|
||||
template<>
|
||||
void print::walk_number<uint8_t>() { DPRINT("u8"); }
|
||||
void print::walk_number1<uint8_t>() { DPRINT("u8"); }
|
||||
template<>
|
||||
void print::walk_number<uint16_t>() { DPRINT("u16"); }
|
||||
void print::walk_number1<uint16_t>() { DPRINT("u16"); }
|
||||
template<>
|
||||
void print::walk_number<uint32_t>() { DPRINT("u32"); }
|
||||
void print::walk_number1<uint32_t>() { DPRINT("u32"); }
|
||||
template<>
|
||||
void print::walk_number<uint64_t>() { DPRINT("u64"); }
|
||||
void print::walk_number1<uint64_t>() { DPRINT("u64"); }
|
||||
template<>
|
||||
void print::walk_number<int8_t>() { DPRINT("i8"); }
|
||||
void print::walk_number1<int8_t>() { DPRINT("i8"); }
|
||||
template<>
|
||||
void print::walk_number<int16_t>() { DPRINT("i16"); }
|
||||
void print::walk_number1<int16_t>() { DPRINT("i16"); }
|
||||
template<>
|
||||
void print::walk_number<int32_t>() { DPRINT("i32"); }
|
||||
void print::walk_number1<int32_t>() { DPRINT("i32"); }
|
||||
template<>
|
||||
void print::walk_number<int64_t>() { DPRINT("i64"); }
|
||||
void print::walk_number1<int64_t>() { DPRINT("i64"); }
|
||||
template<>
|
||||
void print::walk_number<float>() { DPRINT("f32"); }
|
||||
void print::walk_number1<float>() { DPRINT("f32"); }
|
||||
template<>
|
||||
void print::walk_number<double>() { DPRINT("f64"); }
|
||||
void print::walk_number1<double>() { DPRINT("f64"); }
|
||||
|
||||
|
||||
void
|
||||
|
@ -225,13 +225,13 @@ size_of::compute_tag_size(tag_info &tinfo) {
|
|||
}
|
||||
|
||||
void
|
||||
size_of::walk_tag(tag_info &tinfo) {
|
||||
size_of::walk_tag1(tag_info &tinfo) {
|
||||
compute_tag_size(*this, tinfo);
|
||||
sa = tinfo.tag_sa;
|
||||
}
|
||||
|
||||
void
|
||||
size_of::walk_struct(const uint8_t *end_sp) {
|
||||
size_of::walk_struct1(const uint8_t *end_sp) {
|
||||
size_align struct_sa(0, 1);
|
||||
|
||||
bool first = true;
|
||||
|
@ -264,21 +264,21 @@ class cmp : public data<cmp,ptr_pair> {
|
|||
friend class data<cmp,ptr_pair>;
|
||||
|
||||
private:
|
||||
void walk_vec(bool is_pod,
|
||||
const std::pair<ptr_pair,ptr_pair> &data_range);
|
||||
void walk_vec2(bool is_pod,
|
||||
const std::pair<ptr_pair,ptr_pair> &data_range);
|
||||
|
||||
inline void walk_subcontext(cmp &sub) {
|
||||
inline void walk_subcontext2(cmp &sub) {
|
||||
sub.walk();
|
||||
result = sub.result;
|
||||
}
|
||||
|
||||
inline void walk_box_contents(cmp &sub, ptr_pair &ref_count_dp) {
|
||||
inline void walk_box_contents2(cmp &sub, ptr_pair &ref_count_dp) {
|
||||
sub.align = true;
|
||||
sub.walk();
|
||||
result = sub.result;
|
||||
}
|
||||
|
||||
inline void walk_uniq_contents(cmp &sub) {
|
||||
inline void walk_uniq_contents2(cmp &sub) {
|
||||
sub.align = true;
|
||||
sub.walk();
|
||||
result = sub.result;
|
||||
|
@ -338,32 +338,36 @@ public:
|
|||
in_dp),
|
||||
result(0) {}
|
||||
|
||||
void walk_vec(bool is_pod, uint16_t sp_size) {
|
||||
walk_vec(is_pod, get_vec_data_range(dp));
|
||||
void walk_vec2(bool is_pod, uint16_t sp_size) {
|
||||
walk_vec2(is_pod, get_vec_data_range(dp));
|
||||
}
|
||||
|
||||
void walk_box() {
|
||||
data<cmp,ptr_pair>::walk_box_contents();
|
||||
void walk_box2() {
|
||||
data<cmp,ptr_pair>::walk_box_contents1();
|
||||
}
|
||||
|
||||
void walk_uniq() {
|
||||
data<cmp,ptr_pair>::walk_uniq_contents();
|
||||
void walk_uniq2() {
|
||||
data<cmp,ptr_pair>::walk_uniq_contents1();
|
||||
}
|
||||
|
||||
void walk_fn() { return cmp_two_pointers(); }
|
||||
void walk_obj() { return cmp_two_pointers(); }
|
||||
void walk_iface2() {
|
||||
data<cmp,ptr_pair>::walk_box_contents1();
|
||||
}
|
||||
|
||||
void walk_tag(tag_info &tinfo, const data_pair<tag_variant_t> &tag_variants);
|
||||
void walk_struct(const uint8_t *end_sp);
|
||||
void walk_res(const rust_fn *dtor, uint16_t n_ty_params,
|
||||
const type_param *ty_params_sp, const uint8_t *end_sp,
|
||||
const data_pair<uintptr_t> &live);
|
||||
void walk_variant(tag_info &tinfo, tag_variant_t variant_id,
|
||||
const std::pair<const uint8_t *,const uint8_t *>
|
||||
variant_ptr_and_end);
|
||||
void walk_fn2(char) { return cmp_two_pointers(); }
|
||||
void walk_obj2() { return cmp_two_pointers(); }
|
||||
|
||||
void walk_tag2(tag_info &tinfo, const data_pair<tag_variant_t> &tag_variants);
|
||||
void walk_struct2(const uint8_t *end_sp);
|
||||
void walk_res2(const rust_fn *dtor, uint16_t n_ty_params,
|
||||
const type_param *ty_params_sp, const uint8_t *end_sp,
|
||||
const data_pair<uintptr_t> &live);
|
||||
void walk_variant2(tag_info &tinfo, tag_variant_t variant_id,
|
||||
const std::pair<const uint8_t *,const uint8_t *>
|
||||
variant_ptr_and_end);
|
||||
|
||||
template<typename T>
|
||||
void walk_number() { cmp_number(get_dp<T>(dp)); }
|
||||
void walk_number2() { cmp_number(get_dp<T>(dp)); }
|
||||
};
|
||||
|
||||
template<>
|
||||
|
@ -372,7 +376,7 @@ void cmp::cmp_number<int32_t>(const data_pair<int32_t> &nums) {
|
|||
}
|
||||
|
||||
void
|
||||
cmp::walk_vec(bool is_pod, const std::pair<ptr_pair,ptr_pair> &data_range) {
|
||||
cmp::walk_vec2(bool is_pod, const std::pair<ptr_pair,ptr_pair> &data_range) {
|
||||
cmp sub(*this, data_range.first);
|
||||
ptr_pair data_end = sub.end_dp = data_range.second;
|
||||
while (!result && sub.dp < data_end) {
|
||||
|
@ -390,15 +394,15 @@ cmp::walk_vec(bool is_pod, const std::pair<ptr_pair,ptr_pair> &data_range) {
|
|||
}
|
||||
|
||||
void
|
||||
cmp::walk_tag(tag_info &tinfo, const data_pair<tag_variant_t> &tag_variants) {
|
||||
cmp::walk_tag2(tag_info &tinfo, const data_pair<tag_variant_t> &tag_variants) {
|
||||
cmp_number(tag_variants);
|
||||
if (result != 0)
|
||||
return;
|
||||
data<cmp,ptr_pair>::walk_variant(tinfo, tag_variants.fst);
|
||||
data<cmp,ptr_pair>::walk_variant1(tinfo, tag_variants.fst);
|
||||
}
|
||||
|
||||
void
|
||||
cmp::walk_struct(const uint8_t *end_sp) {
|
||||
cmp::walk_struct2(const uint8_t *end_sp) {
|
||||
while (!result && this->sp != end_sp) {
|
||||
this->walk();
|
||||
align = true;
|
||||
|
@ -406,16 +410,16 @@ cmp::walk_struct(const uint8_t *end_sp) {
|
|||
}
|
||||
|
||||
void
|
||||
cmp::walk_res(const rust_fn *dtor, uint16_t n_ty_params,
|
||||
cmp::walk_res2(const rust_fn *dtor, uint16_t n_ty_params,
|
||||
const type_param *ty_params_sp, const uint8_t *end_sp,
|
||||
const data_pair<uintptr_t> &live) {
|
||||
abort(); // TODO
|
||||
}
|
||||
|
||||
void
|
||||
cmp::walk_variant(tag_info &tinfo, tag_variant_t variant_id,
|
||||
const std::pair<const uint8_t *,const uint8_t *>
|
||||
variant_ptr_and_end) {
|
||||
cmp::walk_variant2(tag_info &tinfo, tag_variant_t variant_id,
|
||||
const std::pair<const uint8_t *,const uint8_t *>
|
||||
variant_ptr_and_end) {
|
||||
cmp sub(*this, variant_ptr_and_end.first, tinfo.params);
|
||||
|
||||
const uint8_t *variant_end = variant_ptr_and_end.second;
|
||||
|
@ -430,7 +434,7 @@ cmp::walk_variant(tag_info &tinfo, tag_variant_t variant_id,
|
|||
// Polymorphic logging, for convenience
|
||||
|
||||
void
|
||||
log::walk_string(const std::pair<ptr,ptr> &data) {
|
||||
log::walk_string2(const std::pair<ptr,ptr> &data) {
|
||||
out << prefix << "\"" << std::hex;
|
||||
|
||||
ptr subdp = data.first;
|
||||
|
@ -447,7 +451,7 @@ log::walk_string(const std::pair<ptr,ptr> &data) {
|
|||
}
|
||||
|
||||
void
|
||||
log::walk_struct(const uint8_t *end_sp) {
|
||||
log::walk_struct2(const uint8_t *end_sp) {
|
||||
out << prefix << "(";
|
||||
prefix = "";
|
||||
|
||||
|
@ -463,10 +467,10 @@ log::walk_struct(const uint8_t *end_sp) {
|
|||
}
|
||||
|
||||
void
|
||||
log::walk_vec(bool is_pod, const std::pair<ptr,ptr> &data) {
|
||||
log::walk_vec2(bool is_pod, const std::pair<ptr,ptr> &data) {
|
||||
if (peek() == SHAPE_U8) {
|
||||
sp++; // It's a string. We handle this ourselves.
|
||||
walk_string(data);
|
||||
walk_string2(data);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -485,9 +489,9 @@ log::walk_vec(bool is_pod, const std::pair<ptr,ptr> &data) {
|
|||
}
|
||||
|
||||
void
|
||||
log::walk_variant(tag_info &tinfo, tag_variant_t variant_id,
|
||||
const std::pair<const uint8_t *,const uint8_t *>
|
||||
variant_ptr_and_end) {
|
||||
log::walk_variant2(tag_info &tinfo, tag_variant_t variant_id,
|
||||
const std::pair<const uint8_t *,const uint8_t *>
|
||||
variant_ptr_and_end) {
|
||||
log sub(*this, variant_ptr_and_end.first, tinfo.params);
|
||||
const uint8_t *variant_end = variant_ptr_and_end.second;
|
||||
|
||||
|
@ -503,8 +507,8 @@ log::walk_variant(tag_info &tinfo, tag_variant_t variant_id,
|
|||
}
|
||||
|
||||
void
|
||||
log::walk_res(const rust_fn *dtor, unsigned n_params,
|
||||
const type_param *params, const uint8_t *end_sp, bool live) {
|
||||
log::walk_res2(const rust_fn *dtor, unsigned n_params,
|
||||
const type_param *params, const uint8_t *end_sp, bool live) {
|
||||
out << prefix << "res";
|
||||
|
||||
if (this->sp == end_sp)
|
||||
|
|
|
@ -46,12 +46,17 @@ const uint8_t SHAPE_VEC = 11u;
|
|||
const uint8_t SHAPE_TAG = 12u;
|
||||
const uint8_t SHAPE_BOX = 13u;
|
||||
const uint8_t SHAPE_STRUCT = 17u;
|
||||
const uint8_t SHAPE_FN = 18u;
|
||||
const uint8_t SHAPE_BOX_FN = 18u;
|
||||
const uint8_t SHAPE_OBJ = 19u;
|
||||
const uint8_t SHAPE_RES = 20u;
|
||||
const uint8_t SHAPE_VAR = 21u;
|
||||
const uint8_t SHAPE_UNIQ = 22u;
|
||||
const uint8_t SHAPE_IFACE = 24u;
|
||||
const uint8_t SHAPE_UNIQ_FN = 25u;
|
||||
const uint8_t SHAPE_STACK_FN = 26u;
|
||||
const uint8_t SHAPE_BARE_FN = 27u;
|
||||
const uint8_t SHAPE_TYDESC = 28u;
|
||||
const uint8_t SHAPE_SEND_TYDESC = 29u;
|
||||
|
||||
#ifdef _LP64
|
||||
const uint8_t SHAPE_PTR = SHAPE_U64;
|
||||
|
@ -247,13 +252,13 @@ protected:
|
|||
inline size_align get_size_align(const uint8_t *&addr);
|
||||
|
||||
private:
|
||||
void walk_vec();
|
||||
void walk_tag();
|
||||
void walk_box();
|
||||
void walk_uniq();
|
||||
void walk_struct();
|
||||
void walk_res();
|
||||
void walk_var();
|
||||
void walk_vec0();
|
||||
void walk_tag0();
|
||||
void walk_box0();
|
||||
void walk_uniq0();
|
||||
void walk_struct0();
|
||||
void walk_res0();
|
||||
void walk_var0();
|
||||
};
|
||||
|
||||
|
||||
|
@ -357,34 +362,40 @@ public:
|
|||
// Traversals
|
||||
|
||||
#define WALK_NUMBER(c_type) \
|
||||
static_cast<T *>(this)->template walk_number<c_type>()
|
||||
static_cast<T *>(this)->template walk_number1<c_type>()
|
||||
#define WALK_SIMPLE(method) static_cast<T *>(this)->method()
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
ctxt<T>::walk() {
|
||||
switch (*sp++) {
|
||||
case SHAPE_U8: WALK_NUMBER(uint8_t); break;
|
||||
case SHAPE_U16: WALK_NUMBER(uint16_t); break;
|
||||
case SHAPE_U32: WALK_NUMBER(uint32_t); break;
|
||||
case SHAPE_U64: WALK_NUMBER(uint64_t); break;
|
||||
case SHAPE_I8: WALK_NUMBER(int8_t); break;
|
||||
case SHAPE_I16: WALK_NUMBER(int16_t); break;
|
||||
case SHAPE_I32: WALK_NUMBER(int32_t); break;
|
||||
case SHAPE_I64: WALK_NUMBER(int64_t); break;
|
||||
case SHAPE_F32: WALK_NUMBER(float); break;
|
||||
case SHAPE_F64: WALK_NUMBER(double); break;
|
||||
case SHAPE_VEC: walk_vec(); break;
|
||||
case SHAPE_TAG: walk_tag(); break;
|
||||
case SHAPE_BOX: walk_box(); break;
|
||||
case SHAPE_STRUCT: walk_struct(); break;
|
||||
case SHAPE_FN: WALK_SIMPLE(walk_fn); break;
|
||||
case SHAPE_OBJ: WALK_SIMPLE(walk_obj); break;
|
||||
case SHAPE_RES: walk_res(); break;
|
||||
case SHAPE_VAR: walk_var(); break;
|
||||
case SHAPE_UNIQ: walk_uniq(); break;
|
||||
case SHAPE_IFACE: WALK_SIMPLE(walk_iface); break;
|
||||
default: abort();
|
||||
char s = *sp++;
|
||||
switch (s) {
|
||||
case SHAPE_U8: WALK_NUMBER(uint8_t); break;
|
||||
case SHAPE_U16: WALK_NUMBER(uint16_t); break;
|
||||
case SHAPE_U32: WALK_NUMBER(uint32_t); break;
|
||||
case SHAPE_U64: WALK_NUMBER(uint64_t); break;
|
||||
case SHAPE_I8: WALK_NUMBER(int8_t); break;
|
||||
case SHAPE_I16: WALK_NUMBER(int16_t); break;
|
||||
case SHAPE_I32: WALK_NUMBER(int32_t); break;
|
||||
case SHAPE_I64: WALK_NUMBER(int64_t); break;
|
||||
case SHAPE_F32: WALK_NUMBER(float); break;
|
||||
case SHAPE_F64: WALK_NUMBER(double); break;
|
||||
case SHAPE_VEC: walk_vec0(); break;
|
||||
case SHAPE_TAG: walk_tag0(); break;
|
||||
case SHAPE_BOX: walk_box0(); break;
|
||||
case SHAPE_STRUCT: walk_struct0(); break;
|
||||
case SHAPE_OBJ: WALK_SIMPLE(walk_obj1); break;
|
||||
case SHAPE_RES: walk_res0(); break;
|
||||
case SHAPE_VAR: walk_var0(); break;
|
||||
case SHAPE_UNIQ: walk_uniq0(); break;
|
||||
case SHAPE_IFACE: WALK_SIMPLE(walk_iface1); break;
|
||||
case SHAPE_BOX_FN:
|
||||
case SHAPE_UNIQ_FN:
|
||||
case SHAPE_STACK_FN:
|
||||
case SHAPE_BARE_FN: static_cast<T*>(this)->walk_fn1(s); break;
|
||||
case SHAPE_SEND_TYDESC:
|
||||
case SHAPE_TYDESC: static_cast<T*>(this)->walk_tydesc1(s); break;
|
||||
default: abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -420,20 +431,20 @@ ctxt<T>::get_variant_sp(tag_info &tinfo, tag_variant_t variant_id) {
|
|||
|
||||
template<typename T>
|
||||
void
|
||||
ctxt<T>::walk_vec() {
|
||||
ctxt<T>::walk_vec0() {
|
||||
bool is_pod = *sp++;
|
||||
|
||||
uint16_t sp_size = get_u16_bump(sp);
|
||||
const uint8_t *end_sp = sp + sp_size;
|
||||
|
||||
static_cast<T *>(this)->walk_vec(is_pod, sp_size);
|
||||
static_cast<T *>(this)->walk_vec1(is_pod, sp_size);
|
||||
|
||||
sp = end_sp;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
ctxt<T>::walk_tag() {
|
||||
ctxt<T>::walk_tag0() {
|
||||
tag_info tinfo;
|
||||
tinfo.tag_id = get_u16_bump(sp);
|
||||
|
||||
|
@ -465,45 +476,45 @@ ctxt<T>::walk_tag() {
|
|||
tinfo.params = params;
|
||||
|
||||
// Call to the implementation.
|
||||
static_cast<T *>(this)->walk_tag(tinfo);
|
||||
static_cast<T *>(this)->walk_tag1(tinfo);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
ctxt<T>::walk_box() {
|
||||
ctxt<T>::walk_box0() {
|
||||
uint16_t sp_size = get_u16_bump(sp);
|
||||
const uint8_t *end_sp = sp + sp_size;
|
||||
|
||||
static_cast<T *>(this)->walk_box();
|
||||
static_cast<T *>(this)->walk_box1();
|
||||
|
||||
sp = end_sp;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
ctxt<T>::walk_uniq() {
|
||||
ctxt<T>::walk_uniq0() {
|
||||
uint16_t sp_size = get_u16_bump(sp);
|
||||
const uint8_t *end_sp = sp + sp_size;
|
||||
|
||||
static_cast<T *>(this)->walk_uniq();
|
||||
static_cast<T *>(this)->walk_uniq1();
|
||||
|
||||
sp = end_sp;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
ctxt<T>::walk_struct() {
|
||||
ctxt<T>::walk_struct0() {
|
||||
uint16_t sp_size = get_u16_bump(sp);
|
||||
const uint8_t *end_sp = sp + sp_size;
|
||||
|
||||
static_cast<T *>(this)->walk_struct(end_sp);
|
||||
static_cast<T *>(this)->walk_struct1(end_sp);
|
||||
|
||||
sp = end_sp;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
ctxt<T>::walk_res() {
|
||||
ctxt<T>::walk_res0() {
|
||||
uint16_t dtor_offset = get_u16_bump(sp);
|
||||
const rust_fn **resources =
|
||||
reinterpret_cast<const rust_fn **>(tables->resources);
|
||||
|
@ -523,16 +534,16 @@ ctxt<T>::walk_res() {
|
|||
uint16_t sp_size = get_u16_bump(sp);
|
||||
const uint8_t *end_sp = sp + sp_size;
|
||||
|
||||
static_cast<T *>(this)->walk_res(dtor, n_ty_params, params, end_sp);
|
||||
static_cast<T *>(this)->walk_res1(dtor, n_ty_params, params, end_sp);
|
||||
|
||||
sp = end_sp;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
ctxt<T>::walk_var() {
|
||||
ctxt<T>::walk_var0() {
|
||||
uint8_t param = *sp++;
|
||||
static_cast<T *>(this)->walk_var(param);
|
||||
static_cast<T *>(this)->walk_var1(param);
|
||||
}
|
||||
|
||||
// A shape printer, useful for debugging
|
||||
|
@ -553,26 +564,44 @@ public:
|
|||
const rust_shape_tables *in_tables)
|
||||
: ctxt<print>(in_task, in_align, in_sp, in_params, in_tables) {}
|
||||
|
||||
void walk_tag(tag_info &tinfo);
|
||||
void walk_struct(const uint8_t *end_sp);
|
||||
void walk_res(const rust_fn *dtor, unsigned n_params,
|
||||
const type_param *params, const uint8_t *end_sp);
|
||||
void walk_var(uint8_t param);
|
||||
void walk_tag1(tag_info &tinfo);
|
||||
void walk_struct1(const uint8_t *end_sp);
|
||||
void walk_res1(const rust_fn *dtor, unsigned n_params,
|
||||
const type_param *params, const uint8_t *end_sp);
|
||||
void walk_var1(uint8_t param);
|
||||
|
||||
void walk_vec(bool is_pod, uint16_t sp_size) {
|
||||
void walk_vec1(bool is_pod, uint16_t sp_size) {
|
||||
DPRINT("vec<"); walk(); DPRINT(">");
|
||||
}
|
||||
void walk_box() {
|
||||
DPRINT("box<"); walk(); DPRINT(">");
|
||||
void walk_uniq1() {
|
||||
DPRINT("~<"); walk(); DPRINT(">");
|
||||
}
|
||||
void walk_box1() {
|
||||
DPRINT("@<"); walk(); DPRINT(">");
|
||||
}
|
||||
|
||||
void walk_fn() { DPRINT("fn"); }
|
||||
void walk_obj() { DPRINT("obj"); }
|
||||
void walk_iface() { DPRINT("iface"); }
|
||||
void walk_closure();
|
||||
void walk_fn1(char kind) {
|
||||
switch(kind) {
|
||||
case SHAPE_BARE_FN: DPRINT("fn"); break;
|
||||
case SHAPE_BOX_FN: DPRINT("fn@"); break;
|
||||
case SHAPE_UNIQ_FN: DPRINT("fn~"); break;
|
||||
case SHAPE_STACK_FN: DPRINT("fn&"); break;
|
||||
default: abort();
|
||||
}
|
||||
}
|
||||
void walk_obj1() { DPRINT("obj"); }
|
||||
void walk_iface1() { DPRINT("iface"); }
|
||||
|
||||
void walk_tydesc1(char kind) {
|
||||
switch(kind) {
|
||||
case SHAPE_TYDESC: DPRINT("tydesc"); break;
|
||||
case SHAPE_SEND_TYDESC: DPRINT("send-tydesc"); break;
|
||||
default: abort();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void walk_number() {}
|
||||
void walk_number1() {}
|
||||
|
||||
template<typename T>
|
||||
static void print_cx(const T *cx) {
|
||||
|
@ -608,33 +637,35 @@ public:
|
|||
const rust_shape_tables *in_tables = NULL)
|
||||
: ctxt<size_of>(other, in_sp, in_params, in_tables) {}
|
||||
|
||||
void walk_tag(tag_info &tinfo);
|
||||
void walk_struct(const uint8_t *end_sp);
|
||||
void walk_tag1(tag_info &tinfo);
|
||||
void walk_struct1(const uint8_t *end_sp);
|
||||
|
||||
void walk_box() { sa.set(sizeof(void *), sizeof(void *)); }
|
||||
void walk_fn() { sa.set(sizeof(void *)*2, sizeof(void *)); }
|
||||
void walk_obj() { sa.set(sizeof(void *)*2, sizeof(void *)); }
|
||||
void walk_iface() { sa.set(sizeof(void *), sizeof(void *)); }
|
||||
void walk_closure();
|
||||
void walk_uniq1() { sa.set(sizeof(void *), sizeof(void *)); }
|
||||
void walk_box1() { sa.set(sizeof(void *), sizeof(void *)); }
|
||||
void walk_fn1(char) { sa.set(sizeof(void *)*2, sizeof(void *)); }
|
||||
void walk_obj1() { sa.set(sizeof(void *)*2, sizeof(void *)); }
|
||||
void walk_iface1() { sa.set(sizeof(void *), sizeof(void *)); }
|
||||
void walk_tydesc1(char) { sa.set(sizeof(void *), sizeof(void *)); }
|
||||
void walk_closure1();
|
||||
|
||||
void walk_vec(bool is_pod, uint16_t sp_size) {
|
||||
void walk_vec1(bool is_pod, uint16_t sp_size) {
|
||||
sa.set(sizeof(void *), sizeof(void *));
|
||||
}
|
||||
|
||||
void walk_var(uint8_t param_index) {
|
||||
void walk_var1(uint8_t param_index) {
|
||||
const type_param *param = ¶ms[param_index];
|
||||
size_of sub(*this, param->shape, param->params, param->tables);
|
||||
sub.walk();
|
||||
sa = sub.sa;
|
||||
}
|
||||
|
||||
void walk_res(const rust_fn *dtor, unsigned n_params,
|
||||
const type_param *params, const uint8_t *end_sp) {
|
||||
void walk_res1(const rust_fn *dtor, unsigned n_params,
|
||||
const type_param *params, const uint8_t *end_sp) {
|
||||
abort(); // TODO
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void walk_number() { sa.set(sizeof(T), alignof<T>()); }
|
||||
void walk_number1() { sa.set(sizeof(T), alignof<T>()); }
|
||||
|
||||
void compute_tag_size(tag_info &tinfo);
|
||||
|
||||
|
@ -819,12 +850,12 @@ public:
|
|||
protected:
|
||||
U end_dp;
|
||||
|
||||
void walk_box_contents();
|
||||
void walk_uniq_contents();
|
||||
void walk_fn_contents(ptr &dp);
|
||||
void walk_obj_contents(ptr &dp);
|
||||
void walk_iface_contents(ptr &dp);
|
||||
void walk_variant(tag_info &tinfo, tag_variant_t variant);
|
||||
void walk_box_contents1();
|
||||
void walk_uniq_contents1();
|
||||
void walk_fn_contents1(ptr &dp);
|
||||
void walk_obj_contents1(ptr &dp);
|
||||
void walk_iface_contents1(ptr &dp);
|
||||
void walk_variant1(tag_info &tinfo, tag_variant_t variant);
|
||||
|
||||
static std::pair<uint8_t *,uint8_t *> get_vec_data_range(ptr dp);
|
||||
static std::pair<ptr_pair,ptr_pair> get_vec_data_range(ptr_pair &dp);
|
||||
|
@ -840,87 +871,100 @@ public:
|
|||
dp(in_dp),
|
||||
end_dp() {}
|
||||
|
||||
void walk_tag(tag_info &tinfo);
|
||||
void walk_tag1(tag_info &tinfo);
|
||||
|
||||
void walk_struct(const uint8_t *end_sp) {
|
||||
static_cast<T *>(this)->walk_struct(end_sp);
|
||||
void walk_struct1(const uint8_t *end_sp) {
|
||||
static_cast<T *>(this)->walk_struct2(end_sp);
|
||||
}
|
||||
|
||||
void walk_vec(bool is_pod, uint16_t sp_size) {
|
||||
DATA_SIMPLE(void *, walk_vec(is_pod, sp_size));
|
||||
void walk_vec1(bool is_pod, uint16_t sp_size) {
|
||||
DATA_SIMPLE(void *, walk_vec2(is_pod, sp_size));
|
||||
}
|
||||
|
||||
void walk_box() { DATA_SIMPLE(void *, walk_box()); }
|
||||
void walk_box1() { DATA_SIMPLE(void *, walk_box2()); }
|
||||
|
||||
void walk_uniq() { DATA_SIMPLE(void *, walk_uniq()); }
|
||||
void walk_uniq1() { DATA_SIMPLE(void *, walk_uniq2()); }
|
||||
|
||||
void walk_fn() {
|
||||
void walk_fn1(char code) {
|
||||
ALIGN_TO(alignof<void *>());
|
||||
U next_dp = dp + sizeof(void *) * 2;
|
||||
static_cast<T *>(this)->walk_fn();
|
||||
static_cast<T *>(this)->walk_fn2(code);
|
||||
dp = next_dp;
|
||||
}
|
||||
|
||||
void walk_obj() {
|
||||
void walk_obj1() {
|
||||
ALIGN_TO(alignof<void *>());
|
||||
U next_dp = dp + sizeof(void *) * 2;
|
||||
static_cast<T *>(this)->walk_obj();
|
||||
static_cast<T *>(this)->walk_obj2();
|
||||
dp = next_dp;
|
||||
}
|
||||
|
||||
void walk_iface() {
|
||||
void walk_iface1() {
|
||||
ALIGN_TO(alignof<void *>());
|
||||
U next_dp = dp + sizeof(void *);
|
||||
static_cast<T *>(this)->walk_iface();
|
||||
static_cast<T *>(this)->walk_iface2();
|
||||
dp = next_dp;
|
||||
}
|
||||
|
||||
void walk_res(const rust_fn *dtor, unsigned n_params,
|
||||
const type_param *params, const uint8_t *end_sp) {
|
||||
void walk_tydesc1(char kind) {
|
||||
ALIGN_TO(alignof<void *>());
|
||||
U next_dp = dp + sizeof(void *);
|
||||
static_cast<T *>(this)->walk_tydesc2(kind);
|
||||
dp = next_dp;
|
||||
}
|
||||
|
||||
void walk_res1(const rust_fn *dtor, unsigned n_params,
|
||||
const type_param *params, const uint8_t *end_sp) {
|
||||
typename U::template data<uintptr_t>::t live = bump_dp<uintptr_t>(dp);
|
||||
// Delegate to the implementation.
|
||||
static_cast<T *>(this)->walk_res(dtor, n_params, params, end_sp,
|
||||
static_cast<T *>(this)->walk_res2(dtor, n_params, params, end_sp,
|
||||
live);
|
||||
}
|
||||
|
||||
void walk_var(uint8_t param_index) {
|
||||
void walk_var1(uint8_t param_index) {
|
||||
const type_param *param = &this->params[param_index];
|
||||
T sub(*static_cast<T *>(this), param->shape, param->params,
|
||||
param->tables);
|
||||
static_cast<T *>(this)->walk_subcontext(sub);
|
||||
static_cast<T *>(this)->walk_subcontext2(sub);
|
||||
dp = sub.dp;
|
||||
}
|
||||
|
||||
template<typename W>
|
||||
void walk_number() { DATA_SIMPLE(W, walk_number<W>()); }
|
||||
template<typename WN>
|
||||
void walk_number1() {
|
||||
//DATA_SIMPLE(W, walk_number2<W>());
|
||||
ALIGN_TO(alignof<WN>());
|
||||
U end_dp = dp + sizeof(WN);
|
||||
T* t = static_cast<T *>(this);
|
||||
t->template walk_number2<WN>();
|
||||
dp = end_dp;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T,typename U>
|
||||
void
|
||||
data<T,U>::walk_box_contents() {
|
||||
data<T,U>::walk_box_contents1() {
|
||||
typename U::template data<uint8_t *>::t box_ptr = bump_dp<uint8_t *>(dp);
|
||||
|
||||
U ref_count_dp(box_ptr);
|
||||
T sub(*static_cast<T *>(this), ref_count_dp + sizeof(ref_cnt_t));
|
||||
static_cast<T *>(this)->walk_box_contents(sub, ref_count_dp);
|
||||
static_cast<T *>(this)->walk_box_contents2(sub, ref_count_dp);
|
||||
}
|
||||
|
||||
template<typename T,typename U>
|
||||
void
|
||||
data<T,U>::walk_uniq_contents() {
|
||||
data<T,U>::walk_uniq_contents1() {
|
||||
typename U::template data<uint8_t *>::t box_ptr = bump_dp<uint8_t *>(dp);
|
||||
U data_ptr(box_ptr);
|
||||
T sub(*static_cast<T *>(this), data_ptr);
|
||||
static_cast<T *>(this)->walk_uniq_contents(sub);
|
||||
static_cast<T *>(this)->walk_uniq_contents2(sub);
|
||||
}
|
||||
|
||||
template<typename T,typename U>
|
||||
void
|
||||
data<T,U>::walk_variant(tag_info &tinfo, tag_variant_t variant_id) {
|
||||
data<T,U>::walk_variant1(tag_info &tinfo, tag_variant_t variant_id) {
|
||||
std::pair<const uint8_t *,const uint8_t *> variant_ptr_and_end =
|
||||
this->get_variant_sp(tinfo, variant_id);
|
||||
static_cast<T *>(this)->walk_variant(tinfo, variant_id,
|
||||
variant_ptr_and_end);
|
||||
static_cast<T *>(this)->walk_variant2(tinfo, variant_id,
|
||||
variant_ptr_and_end);
|
||||
}
|
||||
|
||||
template<typename T,typename U>
|
||||
|
@ -943,7 +987,7 @@ data<T,U>::get_vec_data_range(ptr_pair &dp) {
|
|||
|
||||
template<typename T,typename U>
|
||||
void
|
||||
data<T,U>::walk_tag(tag_info &tinfo) {
|
||||
data<T,U>::walk_tag1(tag_info &tinfo) {
|
||||
size_of::compute_tag_size(*this, tinfo);
|
||||
|
||||
if (tinfo.variant_count > 1)
|
||||
|
@ -957,14 +1001,14 @@ data<T,U>::walk_tag(tag_info &tinfo) {
|
|||
else
|
||||
tag_variant = 0;
|
||||
|
||||
static_cast<T *>(this)->walk_tag(tinfo, tag_variant);
|
||||
static_cast<T *>(this)->walk_tag2(tinfo, tag_variant);
|
||||
|
||||
dp = end_dp;
|
||||
}
|
||||
|
||||
template<typename T,typename U>
|
||||
void
|
||||
data<T,U>::walk_fn_contents(ptr &dp) {
|
||||
data<T,U>::walk_fn_contents1(ptr &dp) {
|
||||
fn_env_pair pair = bump_dp<fn_env_pair>(dp);
|
||||
if (!pair.env)
|
||||
return;
|
||||
|
@ -982,7 +1026,7 @@ data<T,U>::walk_fn_contents(ptr &dp) {
|
|||
|
||||
template<typename T,typename U>
|
||||
void
|
||||
data<T,U>::walk_obj_contents(ptr &dp) {
|
||||
data<T,U>::walk_obj_contents1(ptr &dp) {
|
||||
dp += sizeof(void *); // Skip over the vtable.
|
||||
|
||||
uint8_t *box_ptr = bump_dp<uint8_t *>(dp);
|
||||
|
@ -1003,7 +1047,7 @@ data<T,U>::walk_obj_contents(ptr &dp) {
|
|||
|
||||
template<typename T,typename U>
|
||||
void
|
||||
data<T,U>::walk_iface_contents(ptr &dp) {
|
||||
data<T,U>::walk_iface_contents1(ptr &dp) {
|
||||
uint8_t *box_ptr = bump_dp<uint8_t *>(dp);
|
||||
if (!box_ptr) return;
|
||||
U ref_count_dp(box_ptr);
|
||||
|
@ -1017,7 +1061,7 @@ data<T,U>::walk_iface_contents(ptr &dp) {
|
|||
T sub(*static_cast<T *>(this), valtydesc->shape + 5, NULL, NULL,
|
||||
value_dp);
|
||||
sub.align = true;
|
||||
static_cast<T *>(this)->walk_box_contents(sub, ref_count_dp);
|
||||
static_cast<T *>(this)->walk_box_contents2(sub, ref_count_dp);
|
||||
}
|
||||
|
||||
// Polymorphic logging, for convenience
|
||||
|
@ -1067,52 +1111,56 @@ private:
|
|||
out(other.out),
|
||||
prefix("") {}
|
||||
|
||||
void walk_vec(bool is_pod, uint16_t sp_size) {
|
||||
void walk_vec2(bool is_pod, uint16_t sp_size) {
|
||||
if (!get_dp<void *>(dp))
|
||||
out << prefix << "(null)";
|
||||
else
|
||||
walk_vec(is_pod, get_vec_data_range(dp));
|
||||
walk_vec2(is_pod, get_vec_data_range(dp));
|
||||
}
|
||||
|
||||
void walk_tag(tag_info &tinfo, tag_variant_t tag_variant) {
|
||||
void walk_tag2(tag_info &tinfo, tag_variant_t tag_variant) {
|
||||
out << prefix << "tag" << tag_variant;
|
||||
data<log,ptr>::walk_variant(tinfo, tag_variant);
|
||||
data<log,ptr>::walk_variant1(tinfo, tag_variant);
|
||||
}
|
||||
|
||||
void walk_box() {
|
||||
void walk_box2() {
|
||||
out << prefix << "@";
|
||||
prefix = "";
|
||||
data<log,ptr>::walk_box_contents();
|
||||
data<log,ptr>::walk_box_contents1();
|
||||
}
|
||||
|
||||
void walk_uniq() {
|
||||
void walk_uniq2() {
|
||||
out << prefix << "~";
|
||||
prefix = "";
|
||||
data<log,ptr>::walk_uniq_contents();
|
||||
data<log,ptr>::walk_uniq_contents1();
|
||||
}
|
||||
|
||||
void walk_fn() {
|
||||
void walk_fn2(char kind) {
|
||||
out << prefix << "fn";
|
||||
prefix = "";
|
||||
data<log,ptr>::walk_fn_contents(dp);
|
||||
data<log,ptr>::walk_fn_contents1(dp);
|
||||
}
|
||||
|
||||
void walk_obj() {
|
||||
void walk_obj2() {
|
||||
out << prefix << "obj";
|
||||
prefix = "";
|
||||
data<log,ptr>::walk_obj_contents(dp);
|
||||
data<log,ptr>::walk_obj_contents1(dp);
|
||||
}
|
||||
|
||||
void walk_iface() {
|
||||
void walk_iface2() {
|
||||
out << prefix << "iface(";
|
||||
prefix = "";
|
||||
data<log,ptr>::walk_iface_contents(dp);
|
||||
data<log,ptr>::walk_iface_contents1(dp);
|
||||
out << prefix << ")";
|
||||
}
|
||||
|
||||
void walk_subcontext(log &sub) { sub.walk(); }
|
||||
void walk_tydesc2(char kind) {
|
||||
out << prefix << "tydesc";
|
||||
}
|
||||
|
||||
void walk_box_contents(log &sub, ptr &ref_count_dp) {
|
||||
void walk_subcontext2(log &sub) { sub.walk(); }
|
||||
|
||||
void walk_box_contents2(log &sub, ptr &ref_count_dp) {
|
||||
out << prefix;
|
||||
if (!ref_count_dp) {
|
||||
out << "(null)";
|
||||
|
@ -1122,23 +1170,23 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
void walk_uniq_contents(log &sub) {
|
||||
void walk_uniq_contents2(log &sub) {
|
||||
out << prefix;
|
||||
sub.align = true;
|
||||
sub.walk();
|
||||
}
|
||||
|
||||
void walk_struct(const uint8_t *end_sp);
|
||||
void walk_vec(bool is_pod, const std::pair<ptr,ptr> &data);
|
||||
void walk_variant(tag_info &tinfo, tag_variant_t variant_id,
|
||||
void walk_struct2(const uint8_t *end_sp);
|
||||
void walk_vec2(bool is_pod, const std::pair<ptr,ptr> &data);
|
||||
void walk_variant2(tag_info &tinfo, tag_variant_t variant_id,
|
||||
const std::pair<const uint8_t *,const uint8_t *>
|
||||
variant_ptr_and_end);
|
||||
void walk_string(const std::pair<ptr,ptr> &data);
|
||||
void walk_res(const rust_fn *dtor, unsigned n_params,
|
||||
const type_param *params, const uint8_t *end_sp, bool live);
|
||||
void walk_string2(const std::pair<ptr,ptr> &data);
|
||||
void walk_res2(const rust_fn *dtor, unsigned n_params,
|
||||
const type_param *params, const uint8_t *end_sp, bool live);
|
||||
|
||||
template<typename T>
|
||||
inline void walk_number() {
|
||||
inline void walk_number2() {
|
||||
out << prefix;
|
||||
fmt_number(out, get_dp<T>(dp));
|
||||
}
|
||||
|
|
|
@ -279,7 +279,7 @@ upcall_create_shared_type_desc(type_desc *td) {
|
|||
*/
|
||||
|
||||
void upcall_s_free_shared_type_desc(type_desc *td)
|
||||
{
|
||||
{ // n.b.: invoked from rust_cc.cpp as well as generated code
|
||||
rust_task *task = rust_scheduler::get_task();
|
||||
LOG_UPCALL_ENTRY(task);
|
||||
|
||||
|
|
|
@ -6,12 +6,14 @@
|
|||
|
||||
type pointy = {
|
||||
mutable a : maybe_pointy,
|
||||
c : ~int,
|
||||
d : sendfn()->(),
|
||||
};
|
||||
|
||||
fn empty_pointy() -> @pointy {
|
||||
ret @{
|
||||
mutable a : none,
|
||||
c : ~22,
|
||||
d : sendfn()->(){},
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue