Skip to content

Commit 5593add

Browse files
author
Elliott Slaughter
committed
rustc: Break cyclical dependence between emit_tydescs and gen_shape_tables.
Force all tydescs to be emitted before emit_tydescs to avoid linker failures.
1 parent 785c524 commit 5593add

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

src/rustc/middle/trans/base.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,10 @@ fn declare_tydesc_addrspace(ccx: @crate_ctxt, t: ty::t) -> addrspace {
531531
// Generates the declaration for (but doesn't emit) a type descriptor.
532532
fn declare_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
533533
let _icx = ccx.insn_ctxt("declare_tydesc");
534+
// If emit_tydescs already ran, then we shouldn't be creating any new
535+
// tydescs.
536+
assert !ccx.finished_tydescs;
537+
534538
let llty = type_of(ccx, t);
535539

536540
if ccx.sess.count_type_sizes() {
@@ -624,6 +628,8 @@ fn make_generic_glue(ccx: @crate_ctxt, t: ty::t, llfn: ValueRef,
624628
625629
fn emit_tydescs(ccx: @crate_ctxt) {
626630
let _icx = ccx.insn_ctxt("emit_tydescs");
631+
// As of this point, allow no more tydescs to be created.
632+
ccx.finished_tydescs = true;
627633
for ccx.tydescs.each |key, val| {
628634
let glue_fn_ty = T_ptr(T_generic_glue_fn(ccx));
629635
let ti = val;
@@ -5927,6 +5933,7 @@ fn trans_crate(sess: session::session,
59275933
discrims: ast_util::new_def_hash::<ValueRef>(),
59285934
discrim_symbols: int_hash::<~str>(),
59295935
tydescs: ty::new_ty_hash(),
5936+
mut finished_tydescs: false,
59305937
external: ast_util::new_def_hash(),
59315938
monomorphized: map::hashmap(hash_mono_id, sys::shape_eq),
59325939
monomorphizing: ast_util::new_def_hash(),
@@ -5982,6 +5989,9 @@ fn trans_crate(sess: session::session,
59825989
}
59835990

59845991
fill_crate_map(ccx, crate_map);
5992+
// NB: Must call force_declare_tydescs before emit_tydescs to break
5993+
// cyclical dependency with shape code! See shape.rs for details.
5994+
force_declare_tydescs(ccx);
59855995
emit_tydescs(ccx);
59865996
gen_shape_tables(ccx);
59875997
write_abi_version(ccx);

src/rustc/middle/trans/common.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ type crate_ctxt = {
117117
discrims: hashmap<ast::def_id, ValueRef>,
118118
discrim_symbols: hashmap<ast::node_id, ~str>,
119119
tydescs: hashmap<ty::t, @tydesc_info>,
120+
// Set when running emit_tydescs to enforce that no more tydescs are
121+
// created.
122+
mut finished_tydescs: bool,
120123
// Track mapping of external ids to local items imported for inlining
121124
external: hashmap<ast::def_id, Option<ast::node_id>>,
122125
// Cache instances of monomorphized functions

src/rustc/middle/trans/shape.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,34 @@ fn gen_resource_shapes(ccx: @crate_ctxt) -> ValueRef {
584584
return mk_global(ccx, ~"resource_shapes", C_struct(dtors), true);
585585
}
586586

587+
// This function serves to break a cyclical dependence between
588+
// emit_tydescs and gen_shape_tables.
589+
//
590+
// * emit_tydescs calls shape_of, which causes changes to the shape
591+
// tables
592+
// * gen_shape_tables transitively calls get_tydesc, which causes new
593+
// tydescs to be created
594+
//
595+
// We force those tydescs to be emitted now, thus breaking the
596+
// dependency.
597+
fn force_declare_tydescs(ccx: @crate_ctxt) {
598+
// Walk all known tydescs first to force shape code to declare
599+
// dependencies.
600+
for ccx.tydescs.each |key, _val| {
601+
shape_of(ccx, key);
602+
}
603+
604+
// Then walk all resource shapes to force emit all dtors.
605+
let len = ccx.shape_cx.resources.len();
606+
for uint::range(0u, len) |i| {
607+
let ri = ccx.shape_cx.resources.get(i);
608+
for ri.tps.each() |s| { assert !ty::type_has_params(s); }
609+
do option::iter(ri.parent_id) |id| {
610+
trans::base::get_res_dtor(ccx, ri.did, id, ri.tps);
611+
}
612+
}
613+
}
614+
587615
fn gen_shape_tables(ccx: @crate_ctxt) {
588616
let lltagstable = gen_enum_shapes(ccx);
589617
let llresourcestable = gen_resource_shapes(ccx);

0 commit comments

Comments
 (0)