rustc: Write raw type parameters instead of linearized type parameters in object body shapes
This commit is contained in:
parent
dfa5bd1114
commit
e372f943e2
4 changed files with 61 additions and 36 deletions
|
@ -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,6 +437,10 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
|
|||
|
||||
|
||||
ty::ty_param(n, _) {
|
||||
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;
|
||||
|
@ -448,6 +455,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
|
|||
assert (found);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret s;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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()));
|
||||
|
|
|
@ -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".
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue