Skip to content

Commit 861736b

Browse files
author
Elliott Slaughter
committed
---
yaml --- r: 31737 b: refs/heads/dist-snap c: 166cb1b h: refs/heads/master i: 31735: 7bbbef4 v: v3
1 parent c0857d0 commit 861736b

File tree

7 files changed

+119
-61
lines changed

7 files changed

+119
-61
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: d0c6ce338884ee21843f4b40bf6bf18d222ce5df
99
refs/heads/incoming: d9317a174e434d4c99fc1a37fd7dc0d2f5328d37
10-
refs/heads/dist-snap: 76d04af71a64e9c79ea21c8d4b956ef0591e3c61
10+
refs/heads/dist-snap: 166cb1b28bc23303d15e8c1c4a71d0cdff0556a2
1111
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1212
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/dist-snap/src/rustc/middle/trans/base.rs

Lines changed: 101 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -546,18 +546,18 @@ fn make_generic_glue_inner(ccx: @crate_ctxt, t: ty::t,
546546
let fcx = new_fn_ctxt(ccx, ~[], llfn, none);
547547
lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
548548
ccx.stats.n_glues_created += 1u;
549-
// Any nontrivial glue is with values passed *by alias*; this is a
549+
// All glue functions take values passed *by alias*; this is a
550550
// requirement since in many contexts glue is invoked indirectly and
551551
// the caller has no idea if it's dealing with something that can be
552552
// passed by value.
553-
554-
let llty = T_ptr(type_of(ccx, t));
553+
//
554+
// llfn is expected be declared to take a parameter of the appropriate
555+
// type, so we don't need to explicitly cast the function parameter.
555556

556557
let bcx = top_scope_block(fcx, none);
557558
let lltop = bcx.llbb;
558559
let llrawptr0 = llvm::LLVMGetParam(llfn, 3u as c_uint);
559-
let llval0 = BitCast(bcx, llrawptr0, llty);
560-
helper(bcx, llval0, t);
560+
helper(bcx, llrawptr0, t);
561561
finish_fn(fcx, lltop);
562562
return llfn;
563563
}
@@ -581,28 +581,44 @@ fn make_generic_glue(ccx: @crate_ctxt, t: ty::t, llfn: ValueRef,
581581
fn emit_tydescs(ccx: @crate_ctxt) {
582582
let _icx = ccx.insn_ctxt(~"emit_tydescs");
583583
for ccx.tydescs.each |key, val| {
584-
let glue_fn_ty = T_ptr(T_glue_fn(ccx));
584+
let glue_fn_ty = T_ptr(T_generic_glue_fn(ccx));
585585
let ti = val;
586586

587+
// Each of the glue functions needs to be cast to a generic type
588+
// before being put into the tydesc because we only have a singleton
589+
// tydesc type. Then we'll recast each function to its real type when
590+
// calling it.
587591
let take_glue =
588592
match copy ti.take_glue {
589593
none => { ccx.stats.n_null_glues += 1u; C_null(glue_fn_ty) }
590-
some(v) => { ccx.stats.n_real_glues += 1u; v }
594+
some(v) => {
595+
ccx.stats.n_real_glues += 1u;
596+
llvm::LLVMConstPointerCast(v, glue_fn_ty)
597+
}
591598
};
592599
let drop_glue =
593600
match copy ti.drop_glue {
594601
none => { ccx.stats.n_null_glues += 1u; C_null(glue_fn_ty) }
595-
some(v) => { ccx.stats.n_real_glues += 1u; v }
602+
some(v) => {
603+
ccx.stats.n_real_glues += 1u;
604+
llvm::LLVMConstPointerCast(v, glue_fn_ty)
605+
}
596606
};
597607
let free_glue =
598608
match copy ti.free_glue {
599609
none => { ccx.stats.n_null_glues += 1u; C_null(glue_fn_ty) }
600-
some(v) => { ccx.stats.n_real_glues += 1u; v }
610+
some(v) => {
611+
ccx.stats.n_real_glues += 1u;
612+
llvm::LLVMConstPointerCast(v, glue_fn_ty)
613+
}
601614
};
602615
let visit_glue =
603616
match copy ti.visit_glue {
604617
none => { ccx.stats.n_null_glues += 1u; C_null(glue_fn_ty) }
605-
some(v) => { ccx.stats.n_real_glues += 1u; v }
618+
some(v) => {
619+
ccx.stats.n_real_glues += 1u;
620+
llvm::LLVMConstPointerCast(v, glue_fn_ty)
621+
}
606622
};
607623

608624
let shape = shape_of(ccx, key);
@@ -692,20 +708,20 @@ fn make_visit_glue(bcx: block, v: ValueRef, t: ty::t) {
692708

693709

694710
fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) {
695-
// v is a pointer to the actual box component of the type here. The
696-
// ValueRef will have the wrong type here (make_generic_glue is casting
697-
// everything to a pointer to the type that the glue acts on).
711+
// NB: v0 is an *alias* of type t here, not a direct value.
698712
let _icx = bcx.insn_ctxt(~"make_free_glue");
699713
let ccx = bcx.ccx();
700714
let bcx = match ty::get(t).struct {
701715
ty::ty_box(body_mt) => {
702-
let v = PointerCast(bcx, v, type_of(ccx, t));
716+
let v = Load(bcx, v);
703717
let body = GEPi(bcx, v, ~[0u, abi::box_field_body]);
718+
// Cast away the addrspace of the box pointer.
719+
let body = PointerCast(bcx, body, T_ptr(type_of(ccx, body_mt.ty)));
704720
let bcx = drop_ty(bcx, body, body_mt.ty);
705721
trans_free(bcx, v)
706722
}
707723
ty::ty_opaque_box => {
708-
let v = PointerCast(bcx, v, type_of(ccx, t));
724+
let v = Load(bcx, v);
709725
let td = Load(bcx, GEPi(bcx, v, ~[0u, abi::box_field_tydesc]));
710726
let valptr = GEPi(bcx, v, ~[0u, abi::box_field_body]);
711727
// Generate code that, dynamically, indexes into the
@@ -715,7 +731,6 @@ fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) {
715731
trans_free(bcx, v)
716732
}
717733
ty::ty_uniq(content_mt) => {
718-
let v = PointerCast(bcx, v, type_of(ccx, t));
719734
uniq::make_free_glue(bcx, v, t)
720735
}
721736
ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) |
@@ -785,7 +800,7 @@ fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
785800
}
786801
ty::ty_uniq(_) |
787802
ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) => {
788-
free_ty(bcx, Load(bcx, v0), t)
803+
free_ty(bcx, v0, t)
789804
}
790805
ty::ty_unboxed_vec(_) => {
791806
tvec::make_drop_glue_unboxed(bcx, v0, t)
@@ -861,14 +876,12 @@ fn decr_refcnt_maybe_free(bcx: block, box_ptr: ValueRef, t: ty::t) -> block {
861876
let ccx = bcx.ccx();
862877
maybe_validate_box(bcx, box_ptr);
863878

864-
let llbox_ty = T_opaque_box_ptr(ccx);
865-
let box_ptr = PointerCast(bcx, box_ptr, llbox_ty);
866879
do with_cond(bcx, IsNotNull(bcx, box_ptr)) |bcx| {
867880
let rc_ptr = GEPi(bcx, box_ptr, ~[0u, abi::box_field_refcnt]);
868881
let rc = Sub(bcx, Load(bcx, rc_ptr), C_int(ccx, 1));
869882
Store(bcx, rc, rc_ptr);
870883
let zero_test = ICmp(bcx, lib::llvm::IntEQ, C_int(ccx, 0), rc);
871-
with_cond(bcx, zero_test, |bcx| free_ty(bcx, box_ptr, t))
884+
with_cond(bcx, zero_test, |bcx| free_ty_immediate(bcx, box_ptr, t))
872885
}
873886
}
874887

@@ -1097,17 +1110,16 @@ fn lazily_emit_all_tydesc_glue(ccx: @crate_ctxt,
10971110
fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: uint,
10981111
ti: @tydesc_info) {
10991112
let _icx = ccx.insn_ctxt(~"lazily_emit_tydesc_glue");
1113+
let llfnty = type_of_glue_fn(ccx, ti.ty);
11001114
if field == abi::tydesc_field_take_glue {
11011115
match ti.take_glue {
11021116
some(_) => (),
11031117
none => {
11041118
debug!{"+++ lazily_emit_tydesc_glue TAKE %s",
11051119
ppaux::ty_to_str(ccx.tcx, ti.ty)};
1106-
let glue_fn = declare_generic_glue
1107-
(ccx, ti.ty, T_glue_fn(ccx), ~"take");
1120+
let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, ~"take");
11081121
ti.take_glue = some(glue_fn);
1109-
make_generic_glue(ccx, ti.ty, glue_fn,
1110-
make_take_glue, ~"take");
1122+
make_generic_glue(ccx, ti.ty, glue_fn, make_take_glue, ~"take");
11111123
debug!{"--- lazily_emit_tydesc_glue TAKE %s",
11121124
ppaux::ty_to_str(ccx.tcx, ti.ty)};
11131125
}
@@ -1118,11 +1130,9 @@ fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: uint,
11181130
none => {
11191131
debug!{"+++ lazily_emit_tydesc_glue DROP %s",
11201132
ppaux::ty_to_str(ccx.tcx, ti.ty)};
1121-
let glue_fn =
1122-
declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), ~"drop");
1133+
let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, ~"drop");
11231134
ti.drop_glue = some(glue_fn);
1124-
make_generic_glue(ccx, ti.ty, glue_fn,
1125-
make_drop_glue, ~"drop");
1135+
make_generic_glue(ccx, ti.ty, glue_fn, make_drop_glue, ~"drop");
11261136
debug!{"--- lazily_emit_tydesc_glue DROP %s",
11271137
ppaux::ty_to_str(ccx.tcx, ti.ty)};
11281138
}
@@ -1133,11 +1143,9 @@ fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: uint,
11331143
none => {
11341144
debug!{"+++ lazily_emit_tydesc_glue FREE %s",
11351145
ppaux::ty_to_str(ccx.tcx, ti.ty)};
1136-
let glue_fn =
1137-
declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), ~"free");
1146+
let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, ~"free");
11381147
ti.free_glue = some(glue_fn);
1139-
make_generic_glue(ccx, ti.ty, glue_fn,
1140-
make_free_glue, ~"free");
1148+
make_generic_glue(ccx, ti.ty, glue_fn, make_free_glue, ~"free");
11411149
debug!{"--- lazily_emit_tydesc_glue FREE %s",
11421150
ppaux::ty_to_str(ccx.tcx, ti.ty)};
11431151
}
@@ -1148,11 +1156,9 @@ fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: uint,
11481156
none => {
11491157
debug!{"+++ lazily_emit_tydesc_glue VISIT %s",
11501158
ppaux::ty_to_str(ccx.tcx, ti.ty)};
1151-
let glue_fn =
1152-
declare_generic_glue(ccx, ti.ty, T_glue_fn(ccx), ~"visit");
1159+
let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, ~"visit");
11531160
ti.visit_glue = some(glue_fn);
1154-
make_generic_glue(ccx, ti.ty, glue_fn,
1155-
make_visit_glue, ~"visit");
1161+
make_generic_glue(ccx, ti.ty, glue_fn, make_visit_glue, ~"visit");
11561162
debug!{"--- lazily_emit_tydesc_glue VISIT %s",
11571163
ppaux::ty_to_str(ccx.tcx, ti.ty)};
11581164
}
@@ -1161,43 +1167,63 @@ fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: uint,
11611167
}
11621168

11631169
// See [Note-arg-mode]
1164-
fn call_tydesc_glue_full(++cx: block, v: ValueRef, tydesc: ValueRef,
1170+
fn call_tydesc_glue_full(++bcx: block, v: ValueRef, tydesc: ValueRef,
11651171
field: uint, static_ti: option<@tydesc_info>) {
1166-
let _icx = cx.insn_ctxt(~"call_tydesc_glue_full");
1167-
if cx.unreachable { return; }
1172+
let _icx = bcx.insn_ctxt(~"call_tydesc_glue_full");
1173+
if bcx.unreachable { return; }
1174+
let ccx = bcx.ccx();
11681175

1169-
let mut static_glue_fn = none;
1170-
match static_ti {
1171-
none => {/* no-op */ }
1176+
let static_glue_fn = match static_ti {
1177+
none => none,
11721178
some(sti) => {
1173-
lazily_emit_tydesc_glue(cx.ccx(), field, sti);
1179+
lazily_emit_tydesc_glue(ccx, field, sti);
11741180
if field == abi::tydesc_field_take_glue {
1175-
static_glue_fn = sti.take_glue;
1181+
sti.take_glue
11761182
} else if field == abi::tydesc_field_drop_glue {
1177-
static_glue_fn = sti.drop_glue;
1183+
sti.drop_glue
11781184
} else if field == abi::tydesc_field_free_glue {
1179-
static_glue_fn = sti.free_glue;
1185+
sti.free_glue
11801186
} else if field == abi::tydesc_field_visit_glue {
1181-
static_glue_fn = sti.visit_glue;
1187+
sti.visit_glue
1188+
} else {
1189+
none
11821190
}
11831191
}
1184-
}
1192+
};
1193+
1194+
// When available, use static type info to give glue the right type.
1195+
let static_glue_fn = match static_ti {
1196+
none => none,
1197+
some(sti) => {
1198+
match static_glue_fn {
1199+
none => none,
1200+
some(sgf) => some(
1201+
PointerCast(bcx, sgf, T_ptr(type_of_glue_fn(ccx, sti.ty))))
1202+
}
1203+
}
1204+
};
11851205

1186-
let llrawptr = PointerCast(cx, v, T_ptr(T_i8()));
1206+
// When static type info is available, avoid casting parameter because the
1207+
// function already has the right type. Otherwise cast to generic pointer.
1208+
let llrawptr = if is_none(static_ti) || is_none(static_glue_fn) {
1209+
PointerCast(bcx, v, T_ptr(T_i8()))
1210+
} else {
1211+
v
1212+
};
11871213

11881214
let llfn = {
11891215
match static_glue_fn {
11901216
none => {
11911217
// Select out the glue function to call from the tydesc
1192-
let llfnptr = GEPi(cx, tydesc, ~[0u, field]);
1193-
Load(cx, llfnptr)
1218+
let llfnptr = GEPi(bcx, tydesc, ~[0u, field]);
1219+
Load(bcx, llfnptr)
11941220
}
11951221
some(sgf) => sgf
11961222
}
11971223
};
11981224

1199-
Call(cx, llfn, ~[C_null(T_ptr(T_nil())), C_null(T_ptr(T_nil())),
1200-
C_null(T_ptr(T_ptr(cx.ccx().tydesc_type))), llrawptr]);
1225+
Call(bcx, llfn, ~[C_null(T_ptr(T_nil())), C_null(T_ptr(T_nil())),
1226+
C_null(T_ptr(T_ptr(bcx.ccx().tydesc_type))), llrawptr]);
12011227
}
12021228

12031229
// See [Note-arg-mode]
@@ -1231,6 +1257,7 @@ fn call_cmp_glue(bcx: block, lhs: ValueRef, rhs: ValueRef, t: ty::t,
12311257
}
12321258

12331259
fn take_ty(cx: block, v: ValueRef, t: ty::t) -> block {
1260+
// NB: v is an *alias* of type t here, not a direct value.
12341261
let _icx = cx.insn_ctxt(~"take_ty");
12351262
if ty::type_needs_drop(cx.tcx(), t) {
12361263
return call_tydesc_glue(cx, v, t, abi::tydesc_field_take_glue);
@@ -1239,6 +1266,7 @@ fn take_ty(cx: block, v: ValueRef, t: ty::t) -> block {
12391266
}
12401267

12411268
fn drop_ty(cx: block, v: ValueRef, t: ty::t) -> block {
1269+
// NB: v is an *alias* of type t here, not a direct value.
12421270
let _icx = cx.insn_ctxt(~"drop_ty");
12431271
if ty::type_needs_drop(cx.tcx(), t) {
12441272
return call_tydesc_glue(cx, v, t, abi::tydesc_field_drop_glue);
@@ -1252,7 +1280,7 @@ fn drop_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block {
12521280
ty::ty_uniq(_) |
12531281
ty::ty_evec(_, ty::vstore_uniq) |
12541282
ty::ty_estr(ty::vstore_uniq) => {
1255-
free_ty(bcx, v, t)
1283+
free_ty_immediate(bcx, v, t)
12561284
}
12571285
ty::ty_box(_) | ty::ty_opaque_box |
12581286
ty::ty_evec(_, ty::vstore_box) |
@@ -1284,13 +1312,32 @@ fn take_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> result {
12841312
}
12851313

12861314
fn free_ty(cx: block, v: ValueRef, t: ty::t) -> block {
1315+
// NB: v is an *alias* of type t here, not a direct value.
12871316
let _icx = cx.insn_ctxt(~"free_ty");
12881317
if ty::type_needs_drop(cx.tcx(), t) {
12891318
return call_tydesc_glue(cx, v, t, abi::tydesc_field_free_glue);
12901319
}
12911320
return cx;
12921321
}
12931322

1323+
fn free_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block {
1324+
let _icx = bcx.insn_ctxt(~"free_ty_immediate");
1325+
match ty::get(t).struct {
1326+
ty::ty_uniq(_) |
1327+
ty::ty_evec(_, ty::vstore_uniq) |
1328+
ty::ty_estr(ty::vstore_uniq) |
1329+
ty::ty_box(_) | ty::ty_opaque_box |
1330+
ty::ty_evec(_, ty::vstore_box) |
1331+
ty::ty_estr(ty::vstore_box) |
1332+
ty::ty_opaque_closure_ptr(_) => {
1333+
let vp = alloca_zeroed(bcx, type_of(bcx.ccx(), t));
1334+
Store(bcx, v, vp);
1335+
free_ty(bcx, vp, t)
1336+
}
1337+
_ => bcx.tcx().sess.bug(~"free_ty_immediate: non-box ty")
1338+
}
1339+
}
1340+
12941341
fn call_memmove(cx: block, dst: ValueRef, src: ValueRef,
12951342
n_bytes: ValueRef) {
12961343
// FIXME (Related to #1645, I think?): Provide LLVM with better

branches/dist-snap/src/rustc/middle/trans/closure.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ fn make_opaque_cbox_drop_glue(
492492
ty::mk_opaque_closure_ptr(bcx.tcx(), ck))
493493
}
494494
ty::ck_uniq => {
495-
free_ty(bcx, Load(bcx, cboxptr),
495+
free_ty(bcx, cboxptr,
496496
ty::mk_opaque_closure_ptr(bcx.tcx(), ck))
497497
}
498498
}
@@ -501,7 +501,7 @@ fn make_opaque_cbox_drop_glue(
501501
fn make_opaque_cbox_free_glue(
502502
bcx: block,
503503
ck: ty::closure_kind,
504-
cbox: ValueRef) // ptr to the opaque closure
504+
cbox: ValueRef) // ptr to ptr to the opaque closure
505505
-> block {
506506
let _icx = bcx.insn_ctxt(~"closure::make_opaque_cbox_free_glue");
507507
match ck {
@@ -513,7 +513,7 @@ fn make_opaque_cbox_free_glue(
513513
do with_cond(bcx, IsNotNull(bcx, cbox)) |bcx| {
514514
// Load the type descr found in the cbox
515515
let lltydescty = T_ptr(ccx.tydesc_type);
516-
let cbox = PointerCast(bcx, cbox, T_opaque_cbox_ptr(ccx));
516+
let cbox = Load(bcx, cbox);
517517
let tydescptr = GEPi(bcx, cbox, ~[0u, abi::box_field_tydesc]);
518518
let tydesc = Load(bcx, tydescptr);
519519
let tydesc = PointerCast(bcx, tydesc, lltydescty);

branches/dist-snap/src/rustc/middle/trans/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,7 @@ fn T_tydesc_field(cx: @crate_ctxt, field: uint) -> TypeRef unsafe {
655655
return t;
656656
}
657657

658-
fn T_glue_fn(cx: @crate_ctxt) -> TypeRef {
658+
fn T_generic_glue_fn(cx: @crate_ctxt) -> TypeRef {
659659
let s = ~"glue_fn";
660660
match name_has_type(cx.tn, s) {
661661
some(t) => return t,

branches/dist-snap/src/rustc/middle/trans/tvec.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,10 +175,13 @@ fn trans_evec(bcx: block, elements: evec_elements,
175175
let ty = ty::mk_evec(bcx.tcx(),
176176
{ty: unit_ty, mutbl: ast::m_mutbl},
177177
ty::vstore_fixed(count));
178+
let llty = T_ptr(type_of::type_of(bcx.ccx(), ty));
178179

179180
let n = C_uint(ccx, count);
180181
let vp = base::arrayalloca(bcx, llunitty, n);
181-
add_clean(bcx, vp, ty);
182+
// Cast to the fake type we told cleanup to expect.
183+
let vp0 = BitCast(bcx, vp, llty);
184+
add_clean(bcx, vp0, ty);
182185

183186
let len = Mul(bcx, n, unit_sz);
184187

0 commit comments

Comments
 (0)