rustc: Write raw type parameters instead of linearized type parameters in object body shapes

This commit is contained in:
Patrick Walton 2011-09-22 16:10:48 -07:00
parent dfa5bd1114
commit e372f943e2
4 changed files with 61 additions and 36 deletions

View file

@ -274,7 +274,8 @@ fn add_substr(&dest: [u8], src: [u8]) {
dest += src;
}
fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint],
is_obj_body: bool) -> [u8] {
let s = [];
alt ty::struct(ccx.tcx, t) {
@ -320,7 +321,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
s += [shape_vec];
add_bool(s, true); // type is POD
let unit_ty = ty::mk_mach(ccx.tcx, ast::ty_u8);
add_substr(s, shape_of(ccx, unit_ty, ty_param_map));
add_substr(s, shape_of(ccx, unit_ty, ty_param_map, is_obj_body));
}
@ -352,7 +353,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
add_u16(sub, vec::len(tps) as u16);
for tp: ty::t in tps {
let subshape = shape_of(ccx, tp, ty_param_map);
let subshape = shape_of(ccx, tp, ty_param_map, is_obj_body);
add_u16(sub, vec::len(subshape) as u16);
sub += subshape;
}
@ -368,29 +369,31 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
ty::ty_box(mt) {
s += [shape_box];
add_substr(s, shape_of(ccx, mt.ty, ty_param_map));
add_substr(s, shape_of(ccx, mt.ty, ty_param_map, is_obj_body));
}
ty::ty_uniq(mt) {
s += [shape_uniq];
add_substr(s, shape_of(ccx, mt.ty, ty_param_map));
add_substr(s, shape_of(ccx, mt.ty, ty_param_map, is_obj_body));
}
ty::ty_vec(mt) {
s += [shape_vec];
add_bool(s, ty::type_is_pod(ccx.tcx, mt.ty));
add_substr(s, shape_of(ccx, mt.ty, ty_param_map));
add_substr(s, shape_of(ccx, mt.ty, ty_param_map, is_obj_body));
}
ty::ty_rec(fields) {
s += [shape_struct];
let sub = [];
for f: field in fields {
sub += shape_of(ccx, f.mt.ty, ty_param_map);
sub += shape_of(ccx, f.mt.ty, ty_param_map, is_obj_body);
}
add_substr(s, sub);
}
ty::ty_tup(elts) {
s += [shape_struct];
let sub = [];
for elt in elts { sub += shape_of(ccx, elt, ty_param_map); }
for elt in elts {
sub += shape_of(ccx, elt, ty_param_map, is_obj_body);
}
add_substr(s, sub);
}
@ -417,9 +420,9 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
add_u16(s, id as u16);
add_u16(s, vec::len(tps) as u16);
for tp: ty::t in tps {
add_substr(s, shape_of(ccx, tp, ty_param_map));
add_substr(s, shape_of(ccx, tp, ty_param_map, is_obj_body));
}
add_substr(s, shape_of(ccx, subt, ty_param_map));
add_substr(s, shape_of(ccx, subt, ty_param_map, is_obj_body));
}
@ -434,18 +437,23 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
ty::ty_param(n, _) {
// Find the type parameter in the parameter list.
let found = false;
let i = 0u;
while i < vec::len(ty_param_map) {
if n == ty_param_map[i] {
s += [shape_var, i as u8];
found = true;
break;
if is_obj_body {
// Just write in the parameter number.
s += [shape_var, n as u8];
} else {
// Find the type parameter in the parameter list.
let found = false;
let i = 0u;
while i < vec::len(ty_param_map) {
if n == ty_param_map[i] {
s += [shape_var, i as u8];
found = true;
break;
}
i += 1u;
}
i += 1u;
assert (found);
}
assert (found);
}
}
@ -460,7 +468,7 @@ fn shape_of_variant(ccx: @crate_ctxt, v: ty::variant_info,
while i < ty_param_count { ty_param_map += [i]; i += 1u; }
let s = [];
for t: ty::t in v.args { s += shape_of(ccx, t, ty_param_map); }
for t: ty::t in v.args { s += shape_of(ccx, t, ty_param_map, false); }
ret s;
}

View file

@ -951,10 +951,16 @@ fn get_derived_tydesc(cx: @block_ctxt, t: ty::t, escapes: bool,
none. {/* fall through */ }
}
let is_obj_body;
alt storage {
tps_normal. { is_obj_body = false; }
tps_obj(_) | tps_fn(_) { is_obj_body = true; }
}
bcx_ccx(cx).stats.n_derived_tydescs += 1u;
let bcx = new_raw_block_ctxt(cx.fcx, cx.fcx.llderivedtydescs);
let tys = linearize_ty_params(bcx, t);
let root_ti = get_static_tydesc(bcx, t, tys.params);
let root_ti = get_static_tydesc(bcx, t, tys.params, is_obj_body);
static_ti = some::<@tydesc_info>(root_ti);
lazily_emit_all_tydesc_glue(cx, static_ti);
let root = root_ti.tydesc;
@ -1048,13 +1054,13 @@ fn get_tydesc(cx: @block_ctxt, orig_t: ty::t, escapes: bool,
result: get_derived_tydesc(cx, t, escapes, storage, static_ti)};
}
// Otherwise, generate a tydesc if necessary, and return it.
let info = get_static_tydesc(cx, t, []);
let info = get_static_tydesc(cx, t, [], false);
static_ti = some::<@tydesc_info>(info);
ret {kind: tk_static, result: rslt(cx, info.tydesc)};
}
fn get_static_tydesc(cx: @block_ctxt, orig_t: ty::t, ty_params: [uint]) ->
@tydesc_info {
fn get_static_tydesc(cx: @block_ctxt, orig_t: ty::t, ty_params: [uint],
is_obj_body: bool) -> @tydesc_info {
let t = ty::strip_cname(bcx_tcx(cx), orig_t);
@ -1062,7 +1068,8 @@ fn get_static_tydesc(cx: @block_ctxt, orig_t: ty::t, ty_params: [uint]) ->
some(info) { ret info; }
none. {
bcx_ccx(cx).stats.n_static_tydescs += 1u;
let info = declare_tydesc(cx.fcx.lcx, cx.sp, t, ty_params);
let info = declare_tydesc(cx.fcx.lcx, cx.sp, t, ty_params,
is_obj_body);
bcx_ccx(cx).tydescs.insert(t, info);
ret info;
}
@ -1097,7 +1104,8 @@ fn set_glue_inlining(cx: @local_ctxt, f: ValueRef, t: ty::t) {
// Generates the declaration for (but doesn't emit) a type descriptor.
fn declare_tydesc(cx: @local_ctxt, sp: span, t: ty::t, ty_params: [uint]) ->
fn declare_tydesc(cx: @local_ctxt, sp: span, t: ty::t, ty_params: [uint],
is_obj_body: bool) ->
@tydesc_info {
log "+++ declare_tydesc " + ty_to_str(cx.ccx.tcx, t);
let ccx = cx.ccx;
@ -1133,7 +1141,8 @@ fn declare_tydesc(cx: @local_ctxt, sp: span, t: ty::t, ty_params: [uint]) ->
mutable drop_glue: none::<ValueRef>,
mutable free_glue: none::<ValueRef>,
mutable cmp_glue: none::<ValueRef>,
ty_params: ty_params};
ty_params: ty_params,
is_obj_body: is_obj_body};
log "--- declare_tydesc " + ty_to_str(cx.ccx.tcx, t);
ret info;
}
@ -1249,7 +1258,8 @@ fn emit_tydescs(ccx: @crate_ctxt) {
some(v) { ccx.stats.n_real_glues += 1u; v }
};
let shape = shape::shape_of(ccx, pair.key, ti.ty_params);
let shape = shape::shape_of(ccx, pair.key, ti.ty_params,
ti.is_obj_body);
let shape_tables =
llvm::LLVMConstPointerCast(ccx.shape_cx.llshapetables,
T_ptr(T_i8()));

View file

@ -58,7 +58,8 @@ type tydesc_info =
mutable drop_glue: option::t<ValueRef>,
mutable free_glue: option::t<ValueRef>,
mutable cmp_glue: option::t<ValueRef>,
ty_params: [uint]};
ty_params: [uint],
is_obj_body: bool};
/*
* A note on nomenclature of linking: "upcall", "extern" and "native".

View file

@ -108,6 +108,18 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
// refcount.
let body_ty: ty::t =
create_object_body_type(ccx.tcx, obj_fields, tps, none);
// We have to get this type descriptor now so that
// trans_malloc_boxed() doesn't generate a type descriptor with the
// wrong storage type and override the type descriptor we're about to
// generate.
let ti = none;
let storage = tps_obj(vec::len(ty_params));
let body_td = get_tydesc(bcx, body_ty, true, storage, ti).result;
bcx = body_td.bcx;
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, ti);
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, ti);
let box = trans_malloc_boxed(bcx, body_ty);
bcx = box.bcx;
let body = box.body;
@ -126,7 +138,6 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
let body_tydesc =
GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_tydesc]);
bcx = body_tydesc.bcx;
let ti = none;
check type_is_tup_like(bcx, body_ty);
let r =
@ -134,11 +145,6 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
bcx = r.bcx;
let body_typarams = r.val;
let storage = tps_obj(vec::len(ty_params));
let body_td = get_tydesc(bcx, body_ty, true, storage, ti).result;
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, ti);
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, ti);
bcx = body_td.bcx;
Store(bcx, body_td.val, body_tydesc.val);
// Copy the object's type parameters and fields into the space we