Clean up the tydesc handling code in trans.

This commit is contained in:
Michael Sullivan 2012-07-09 18:03:37 -07:00
parent ccee8cb4f9
commit 25b152397d
2 changed files with 80 additions and 119 deletions

View File

@ -367,12 +367,11 @@ fn malloc_raw_dyn(bcx: block, t: ty::t, heap: heap,
let llty = type_of(ccx, box_ptr_ty); let llty = type_of(ccx, box_ptr_ty);
// Get the tydesc for the body: // Get the tydesc for the body:
let mut static_ti = none; let static_ti = get_tydesc(ccx, t);
let lltydesc = get_tydesc(ccx, t, static_ti); lazily_emit_all_tydesc_glue(ccx, static_ti);
lazily_emit_all_tydesc_glue(ccx, copy static_ti);
// Allocate space: // Allocate space:
let rval = Call(bcx, upcall, ~[lltydesc, size]); let rval = Call(bcx, upcall, ~[static_ti.tydesc, size]);
ret PointerCast(bcx, rval, llty); ret PointerCast(bcx, rval, llty);
} }
@ -409,20 +408,10 @@ fn malloc_unique(bcx: block, t: ty::t) -> {box: ValueRef, body: ValueRef} {
// Type descriptor and type glue stuff // Type descriptor and type glue stuff
fn get_tydesc_simple(ccx: @crate_ctxt, t: ty::t) -> ValueRef { fn get_tydesc_simple(ccx: @crate_ctxt, t: ty::t) -> ValueRef {
let mut ti = none; get_tydesc(ccx, t).tydesc
get_tydesc(ccx, t, ti)
} }
fn get_tydesc(ccx: @crate_ctxt, t: ty::t, fn get_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
&static_ti: option<@tydesc_info>) -> ValueRef {
assert !ty::type_has_params(t);
// Otherwise, generate a tydesc if necessary, and return it.
let inf = get_static_tydesc(ccx, t);
static_ti = some(inf);
inf.tydesc
}
fn get_static_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
alt ccx.tydescs.find(t) { alt ccx.tydescs.find(t) {
some(inf) { inf } some(inf) { inf }
_ { _ {
@ -1090,7 +1079,7 @@ fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
} }
fn lazily_emit_all_tydesc_glue(ccx: @crate_ctxt, fn lazily_emit_all_tydesc_glue(ccx: @crate_ctxt,
static_ti: option<@tydesc_info>) { static_ti: @tydesc_info) {
lazily_emit_tydesc_glue(ccx, abi::tydesc_field_take_glue, static_ti); lazily_emit_tydesc_glue(ccx, abi::tydesc_field_take_glue, static_ti);
lazily_emit_tydesc_glue(ccx, abi::tydesc_field_drop_glue, static_ti); lazily_emit_tydesc_glue(ccx, abi::tydesc_field_drop_glue, static_ti);
lazily_emit_tydesc_glue(ccx, abi::tydesc_field_free_glue, static_ti); lazily_emit_tydesc_glue(ccx, abi::tydesc_field_free_glue, static_ti);
@ -1098,74 +1087,68 @@ fn lazily_emit_all_tydesc_glue(ccx: @crate_ctxt,
} }
fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: uint, fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: uint,
static_ti: option<@tydesc_info>) { ti: @tydesc_info) {
let _icx = ccx.insn_ctxt("lazily_emit_tydesc_glue"); let _icx = ccx.insn_ctxt("lazily_emit_tydesc_glue");
alt static_ti { if field == abi::tydesc_field_take_glue {
none { } alt ti.take_glue {
some(ti) { some(_) { }
if field == abi::tydesc_field_take_glue { none {
alt ti.take_glue { #debug("+++ lazily_emit_tydesc_glue TAKE %s",
some(_) { } ppaux::ty_to_str(ccx.tcx, ti.ty));
none { let glue_fn = declare_generic_glue
#debug("+++ lazily_emit_tydesc_glue TAKE %s", (ccx, ti.ty, T_glue_fn(ccx), "take");
ppaux::ty_to_str(ccx.tcx, ti.ty)); ti.take_glue = some(glue_fn);
let glue_fn = declare_generic_glue make_generic_glue(ccx, ti.ty, glue_fn,
(ccx, ti.ty, T_glue_fn(ccx), "take"); make_take_glue, "take");
ti.take_glue = some(glue_fn); #debug("--- lazily_emit_tydesc_glue TAKE %s",
make_generic_glue(ccx, ti.ty, glue_fn, ppaux::ty_to_str(ccx.tcx, ti.ty));
make_take_glue, "take"); }
#debug("--- lazily_emit_tydesc_glue TAKE %s", }
ppaux::ty_to_str(ccx.tcx, ti.ty)); } else if field == abi::tydesc_field_drop_glue {
} alt ti.drop_glue {
} some(_) { }
} else if field == abi::tydesc_field_drop_glue { none {
alt ti.drop_glue { #debug("+++ lazily_emit_tydesc_glue DROP %s",
some(_) { } ppaux::ty_to_str(ccx.tcx, ti.ty));
none { let glue_fn =
#debug("+++ lazily_emit_tydesc_glue DROP %s", declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), "drop");
ppaux::ty_to_str(ccx.tcx, ti.ty)); ti.drop_glue = some(glue_fn);
let glue_fn = make_generic_glue(ccx, ti.ty, glue_fn,
declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), "drop"); make_drop_glue, "drop");
ti.drop_glue = some(glue_fn); #debug("--- lazily_emit_tydesc_glue DROP %s",
make_generic_glue(ccx, ti.ty, glue_fn, ppaux::ty_to_str(ccx.tcx, ti.ty));
make_drop_glue, "drop"); }
#debug("--- lazily_emit_tydesc_glue DROP %s", }
ppaux::ty_to_str(ccx.tcx, ti.ty)); } else if field == abi::tydesc_field_free_glue {
} alt ti.free_glue {
} some(_) { }
} else if field == abi::tydesc_field_free_glue { none {
alt ti.free_glue { #debug("+++ lazily_emit_tydesc_glue FREE %s",
some(_) { } ppaux::ty_to_str(ccx.tcx, ti.ty));
none { let glue_fn =
#debug("+++ lazily_emit_tydesc_glue FREE %s", declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), "free");
ppaux::ty_to_str(ccx.tcx, ti.ty)); ti.free_glue = some(glue_fn);
let glue_fn = make_generic_glue(ccx, ti.ty, glue_fn,
declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), "free"); make_free_glue, "free");
ti.free_glue = some(glue_fn); #debug("--- lazily_emit_tydesc_glue FREE %s",
make_generic_glue(ccx, ti.ty, glue_fn, ppaux::ty_to_str(ccx.tcx, ti.ty));
make_free_glue, "free"); }
#debug("--- lazily_emit_tydesc_glue FREE %s", }
ppaux::ty_to_str(ccx.tcx, ti.ty)); } else if field == abi::tydesc_field_visit_glue {
} alt ti.visit_glue {
} some(_) { }
} else if field == abi::tydesc_field_visit_glue { none {
alt ti.visit_glue { #debug("+++ lazily_emit_tydesc_glue VISIT %s",
some(_) { } ppaux::ty_to_str(ccx.tcx, ti.ty));
none { let glue_fn =
#debug("+++ lazily_emit_tydesc_glue VISIT %s", declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), "visit");
ppaux::ty_to_str(ccx.tcx, ti.ty)); ti.visit_glue = some(glue_fn);
let glue_fn = make_generic_glue(ccx, ti.ty, glue_fn,
declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), "visit"); make_visit_glue, "visit");
ti.visit_glue = some(glue_fn); #debug("--- lazily_emit_tydesc_glue VISIT %s",
make_generic_glue(ccx, ti.ty, glue_fn, ppaux::ty_to_str(ccx.tcx, ti.ty));
make_visit_glue, "visit"); }
#debug("--- lazily_emit_tydesc_glue VISIT %s",
ppaux::ty_to_str(ccx.tcx, ti.ty));
}
}
} }
}
} }
} }
@ -1173,13 +1156,13 @@ fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: uint,
fn call_tydesc_glue_full(++cx: block, v: ValueRef, tydesc: ValueRef, fn call_tydesc_glue_full(++cx: block, v: ValueRef, tydesc: ValueRef,
field: uint, static_ti: option<@tydesc_info>) { field: uint, static_ti: option<@tydesc_info>) {
let _icx = cx.insn_ctxt("call_tydesc_glue_full"); let _icx = cx.insn_ctxt("call_tydesc_glue_full");
lazily_emit_tydesc_glue(cx.ccx(), field, static_ti); if cx.unreachable { ret; }
if cx.unreachable { ret; }
let mut static_glue_fn = none; let mut static_glue_fn = none;
alt static_ti { alt static_ti {
none {/* no-op */ } none {/* no-op */ }
some(sti) { some(sti) {
lazily_emit_tydesc_glue(cx.ccx(), field, sti);
if field == abi::tydesc_field_take_glue { if field == abi::tydesc_field_take_glue {
static_glue_fn = sti.take_glue; static_glue_fn = sti.take_glue;
} else if field == abi::tydesc_field_drop_glue { } else if field == abi::tydesc_field_drop_glue {
@ -1213,9 +1196,8 @@ fn call_tydesc_glue_full(++cx: block, v: ValueRef, tydesc: ValueRef,
fn call_tydesc_glue(++cx: block, v: ValueRef, t: ty::t, field: uint) fn call_tydesc_glue(++cx: block, v: ValueRef, t: ty::t, field: uint)
-> block { -> block {
let _icx = cx.insn_ctxt("call_tydesc_glue"); let _icx = cx.insn_ctxt("call_tydesc_glue");
let mut ti = none; let ti = get_tydesc(cx.ccx(), t);
let td = get_tydesc(cx.ccx(), t, ti); call_tydesc_glue_full(cx, v, ti.tydesc, field, some(ti));
call_tydesc_glue_full(cx, v, td, field, ti);
ret cx; ret cx;
} }

View File

@ -146,7 +146,7 @@ fn mk_closure_tys(tcx: ty::ctxt,
fn allocate_cbox(bcx: block, fn allocate_cbox(bcx: block,
ck: ty::closure_kind, ck: ty::closure_kind,
cdata_ty: ty::t) cdata_ty: ty::t)
-> (block, ValueRef, ~[ValueRef]) { -> ValueRef {
let _icx = bcx.insn_ctxt("closure::allocate_cbox"); let _icx = bcx.insn_ctxt("closure::allocate_cbox");
let ccx = bcx.ccx(), tcx = ccx.tcx; let ccx = bcx.ccx(), tcx = ccx.tcx;
@ -160,42 +160,23 @@ fn allocate_cbox(bcx: block,
Store(bcx, rc, ref_cnt); Store(bcx, rc, ref_cnt);
} }
fn store_tydesc(bcx: block,
cdata_ty: ty::t,
llbox: ValueRef,
&ti: option<@tydesc_info>) -> block {
let bound_tydesc = GEPi(bcx, llbox, ~[0u, abi::box_field_tydesc]);
let td = base::get_tydesc(bcx.ccx(), cdata_ty, ti);
Store(bcx, td, bound_tydesc);
bcx
}
// Allocate and initialize the box: // Allocate and initialize the box:
let mut ti = none; let llbox = alt ck {
let mut temp_cleanups = ~[];
let (bcx, llbox) = alt ck {
ty::ck_box { ty::ck_box {
get_tydesc(ccx, cdata_ty, ti); malloc_raw(bcx, cdata_ty, heap_shared)
let llbox = malloc_raw(bcx, cdata_ty, heap_shared);
(bcx, llbox)
} }
ty::ck_uniq { ty::ck_uniq {
let llbox = malloc_raw(bcx, cdata_ty, heap_exchange); malloc_raw(bcx, cdata_ty, heap_exchange)
(bcx, llbox)
} }
ty::ck_block { ty::ck_block {
let cbox_ty = tuplify_box_ty(tcx, cdata_ty); let cbox_ty = tuplify_box_ty(tcx, cdata_ty);
let llbox = base::alloc_ty(bcx, cbox_ty); let llbox = base::alloc_ty(bcx, cbox_ty);
nuke_ref_count(bcx, llbox); nuke_ref_count(bcx, llbox);
(bcx, llbox) llbox
} }
}; };
base::lazily_emit_tydesc_glue(ccx, abi::tydesc_field_take_glue, ti); ret llbox;
base::lazily_emit_tydesc_glue(ccx, abi::tydesc_field_drop_glue, ti);
base::lazily_emit_tydesc_glue(ccx, abi::tydesc_field_free_glue, ti);
ret (bcx, llbox, temp_cleanups);
} }
type closure_result = { type closure_result = {
@ -219,8 +200,8 @@ fn store_environment(bcx: block,
mk_closure_tys(tcx, bound_values); mk_closure_tys(tcx, bound_values);
// allocate closure in the heap // allocate closure in the heap
let mut (bcx, llbox, temp_cleanups) = let llbox = allocate_cbox(bcx, ck, cdata_ty);
allocate_cbox(bcx, ck, cdata_ty); let mut temp_cleanups = ~[];
// cbox_ty has the form of a tuple: (a, b, c) we want a ptr to a // cbox_ty has the form of a tuple: (a, b, c) we want a ptr to a
// tuple. This could be a ptr in uniq or a box or on stack, // tuple. This could be a ptr in uniq or a box or on stack,
@ -567,10 +548,9 @@ fn make_opaque_cbox_take_glue(
let bcx = take_ty(bcx, tydesc_out, ty::mk_type(tcx)); let bcx = take_ty(bcx, tydesc_out, ty::mk_type(tcx));
// Take the data in the tuple // Take the data in the tuple
let ti = none;
let cdata_out = GEPi(bcx, cbox_out, ~[0u, abi::box_field_body]); let cdata_out = GEPi(bcx, cbox_out, ~[0u, abi::box_field_body]);
call_tydesc_glue_full(bcx, cdata_out, tydesc, call_tydesc_glue_full(bcx, cdata_out, tydesc,
abi::tydesc_field_take_glue, ti); abi::tydesc_field_take_glue, none);
bcx bcx
} }
} }
@ -615,10 +595,9 @@ fn make_opaque_cbox_free_glue(
let tydesc = PointerCast(bcx, tydesc, lltydescty); let tydesc = PointerCast(bcx, tydesc, lltydescty);
// Drop the tuple data then free the descriptor // Drop the tuple data then free the descriptor
let ti = none;
let cdata = GEPi(bcx, cbox, ~[0u, abi::box_field_body]); let cdata = GEPi(bcx, cbox, ~[0u, abi::box_field_body]);
call_tydesc_glue_full(bcx, cdata, tydesc, call_tydesc_glue_full(bcx, cdata, tydesc,
abi::tydesc_field_drop_glue, ti); abi::tydesc_field_drop_glue, none);
// Free the ty descr (if necc) and the box itself // Free the ty descr (if necc) and the box itself
alt ck { alt ck {