From 0ab27b1d5b68d3bc3c727895e5219ce254c685ad Mon Sep 17 00:00:00 2001 From: Stuart Pernsteiner Date: Wed, 16 Jul 2014 11:27:57 -0700 Subject: [PATCH] split CrateContext into shared and local pieces Break up `CrateContext` into `SharedCrateContext` and `LocalCrateContext`. The local piece corresponds to a single compilation unit, and contains all LLVM-related components. (LLVM data structures are tied to a specific `LLVMContext`, and we will need separate `LLVMContext`s to safely run multithreaded optimization.) The shared piece contains data structures that need to be shared across all compilation units, such as the `ty::ctxt` and some tables related to crate metadata. --- src/librustc/back/link.rs | 1 + src/librustc/driver/driver.rs | 1 + src/librustc/middle/trans/base.rs | 108 ++++---- src/librustc/middle/trans/builder.rs | 2 +- src/librustc/middle/trans/common.rs | 4 +- src/librustc/middle/trans/context.rs | 393 ++++++++++++++++++--------- 6 files changed, 327 insertions(+), 182 deletions(-) diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index d9c05f9a76da9..cb71e5983235d 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -405,6 +405,7 @@ pub mod write { llvm::LLVMRustDisposeTargetMachine(tm); llvm::LLVMDisposeModule(trans.metadata_module); + llvm::LLVMContextDispose(trans.metadata_context); llvm::LLVMDisposeModule(llmod); llvm::LLVMContextDispose(llcx); if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); } diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 3d0678aa0e7ac..5e9d8da5b4edb 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -444,6 +444,7 @@ pub fn phase_save_analysis(sess: &Session, pub struct CrateTranslation { pub context: ContextRef, pub module: ModuleRef, + pub metadata_context: ContextRef, pub metadata_module: ModuleRef, pub link: LinkMeta, pub metadata: Vec, diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 78488654c510c..dc8dabda83438 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -56,6 +56,7 @@ use middle::trans::common::{tydesc_info, type_is_immediate}; use middle::trans::common::{type_is_zero_size, val_ty}; use middle::trans::common; use middle::trans::consts; +use middle::trans::context::SharedCrateContext; use middle::trans::controlflow; use middle::trans::datum; use middle::trans::debuginfo; @@ -136,7 +137,7 @@ pub fn push_ctxt(s: &'static str) -> _InsnCtxt { } pub struct StatRecorder<'a> { - ccx: &'a CrateContext, + ccx: &'a CrateContext<'a>, name: Option, start: u64, istart: uint, @@ -2114,7 +2115,7 @@ fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &ast::EnumDef, sp: Span, } pub struct TransItemVisitor<'a> { - pub ccx: &'a CrateContext, + pub ccx: &'a CrateContext<'a>, } impl<'a> Visitor<()> for TransItemVisitor<'a> { @@ -2895,52 +2896,54 @@ pub fn trans_crate(krate: ast::Crate, let link_meta = link::build_link_meta(&tcx.sess, &krate, name); - // Append ".rs" to crate name as LLVM module identifier. - // - // LLVM code generator emits a ".file filename" directive - // for ELF backends. Value of the "filename" is set as the - // LLVM module identifier. Due to a LLVM MC bug[1], LLVM - // crashes if the module identifier is same as other symbols - // such as a function name in the module. - // 1. http://llvm.org/bugs/show_bug.cgi?id=11479 - let mut llmod_id = link_meta.crate_name.clone(); - llmod_id.push_str(".rs"); + // Multiple compilation units won't be supported until a later commit. + let codegen_units = 1; + let shared_ccx = SharedCrateContext::new(link_meta.crate_name.as_slice(), + codegen_units, + tcx, + exp_map2, + Sha256::new(), + link_meta.clone(), + reachable); - let ccx = CrateContext::new(llmod_id.as_slice(), tcx, exp_map2, - Sha256::new(), link_meta, reachable); + let metadata = { + let ccx = shared_ccx.get_ccx(0); - // First, verify intrinsics. - intrinsic::check_intrinsics(&ccx); + // First, verify intrinsics. + intrinsic::check_intrinsics(&ccx); - // Next, translate the module. - { - let _icx = push_ctxt("text"); - trans_mod(&ccx, &krate.module); - } + // Next, translate the module. + { + let _icx = push_ctxt("text"); + trans_mod(&ccx, &krate.module); + } - glue::emit_tydescs(&ccx); - if ccx.sess().opts.debuginfo != NoDebugInfo { - debuginfo::finalize(&ccx); - } + glue::emit_tydescs(&ccx); + if ccx.sess().opts.debuginfo != NoDebugInfo { + debuginfo::finalize(&ccx); + } + + // Translate the metadata. + write_metadata(&ccx, &krate) + }; - // Translate the metadata. - let metadata = write_metadata(&ccx, &krate); - if ccx.sess().trans_stats() { + if shared_ccx.sess().trans_stats() { + let stats = shared_ccx.stats(); println!("--- trans stats ---"); - println!("n_static_tydescs: {}", ccx.stats().n_static_tydescs.get()); - println!("n_glues_created: {}", ccx.stats().n_glues_created.get()); - println!("n_null_glues: {}", ccx.stats().n_null_glues.get()); - println!("n_real_glues: {}", ccx.stats().n_real_glues.get()); - - println!("n_fns: {}", ccx.stats().n_fns.get()); - println!("n_monos: {}", ccx.stats().n_monos.get()); - println!("n_inlines: {}", ccx.stats().n_inlines.get()); - println!("n_closures: {}", ccx.stats().n_closures.get()); + println!("n_static_tydescs: {}", stats.n_static_tydescs.get()); + println!("n_glues_created: {}", stats.n_glues_created.get()); + println!("n_null_glues: {}", stats.n_null_glues.get()); + println!("n_real_glues: {}", stats.n_real_glues.get()); + + println!("n_fns: {}", stats.n_fns.get()); + println!("n_monos: {}", stats.n_monos.get()); + println!("n_inlines: {}", stats.n_inlines.get()); + println!("n_closures: {}", stats.n_closures.get()); println!("fn stats:"); - ccx.stats().fn_stats.borrow_mut().sort_by(|&(_, _, insns_a), &(_, _, insns_b)| { + stats.fn_stats.borrow_mut().sort_by(|&(_, _, insns_a), &(_, _, insns_b)| { insns_b.cmp(&insns_a) }); - for tuple in ccx.stats().fn_stats.borrow().iter() { + for tuple in stats.fn_stats.borrow().iter() { match *tuple { (ref name, ms, insns) => { println!("{} insns, {} ms, {}", insns, ms, *name); @@ -2948,27 +2951,26 @@ pub fn trans_crate(krate: ast::Crate, } } } - if ccx.sess().count_llvm_insns() { - for (k, v) in ccx.stats().llvm_insns.borrow().iter() { + if shared_ccx.sess().count_llvm_insns() { + for (k, v) in shared_ccx.stats().llvm_insns.borrow().iter() { println!("{:7u} {}", *v, *k); } } - let llcx = ccx.llcx(); - let link_meta = ccx.link_meta().clone(); - let llmod = ccx.llmod(); + let llcx = shared_ccx.get_ccx(0).llcx(); + let llmod = shared_ccx.get_ccx(0).llmod(); - let mut reachable: Vec = ccx.reachable().iter().filter_map(|id| { - ccx.item_symbols().borrow().find(id).map(|s| s.to_string()) + let mut reachable: Vec = shared_ccx.reachable().iter().filter_map(|id| { + shared_ccx.item_symbols().borrow().find(id).map(|s| s.to_string()) }).collect(); // For the purposes of LTO, we add to the reachable set all of the upstream // reachable extern fns. These functions are all part of the public ABI of // the final product, so LTO needs to preserve them. - ccx.sess().cstore.iter_crate_data(|cnum, _| { - let syms = csearch::get_reachable_extern_fns(&ccx.sess().cstore, cnum); + shared_ccx.sess().cstore.iter_crate_data(|cnum, _| { + let syms = csearch::get_reachable_extern_fns(&shared_ccx.sess().cstore, cnum); reachable.extend(syms.move_iter().map(|did| { - csearch::get_symbol(&ccx.sess().cstore, did) + csearch::get_symbol(&shared_ccx.sess().cstore, did) })); }); @@ -2986,15 +2988,17 @@ pub fn trans_crate(krate: ast::Crate, // referenced from rt/rust_try.ll reachable.push("rust_eh_personality_catch".to_string()); - let metadata_module = ccx.metadata_llmod(); - let formats = ccx.tcx().dependency_formats.borrow().clone(); + let metadata_module = shared_ccx.metadata_llmod(); + let metadata_context = shared_ccx.metadata_llcx(); + let formats = shared_ccx.tcx().dependency_formats.borrow().clone(); let no_builtins = attr::contains_name(krate.attrs.as_slice(), "no_builtins"); - (ccx.take_tcx(), CrateTranslation { + (shared_ccx.take_tcx(), CrateTranslation { context: llcx, module: llmod, link: link_meta, metadata_module: metadata_module, + metadata_context: metadata_context, metadata: metadata, reachable: reachable, crate_formats: formats, diff --git a/src/librustc/middle/trans/builder.rs b/src/librustc/middle/trans/builder.rs index 29c7b93a3691f..61a79f4a8eeba 100644 --- a/src/librustc/middle/trans/builder.rs +++ b/src/librustc/middle/trans/builder.rs @@ -25,7 +25,7 @@ use syntax::codemap::Span; pub struct Builder<'a> { pub llbuilder: BuilderRef, - pub ccx: &'a CrateContext, + pub ccx: &'a CrateContext<'a>, } // This is a really awful way to get a zero-length c-string, but better (and a diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index f0014827cc780..dbd3de2a9986a 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -297,7 +297,7 @@ pub struct FunctionContext<'a> { pub block_arena: &'a TypedArena>, // This function's enclosing crate context. - pub ccx: &'a CrateContext, + pub ccx: &'a CrateContext<'a>, // Used and maintained by the debuginfo module. pub debug_context: debuginfo::FunctionDebugContext, @@ -449,7 +449,7 @@ impl<'a> Block<'a> { }) } - pub fn ccx(&self) -> &'a CrateContext { self.fcx.ccx } + pub fn ccx(&self) -> &'a CrateContext<'a> { self.fcx.ccx } pub fn tcx(&self) -> &'a ty::ctxt { self.fcx.ccx.tcx() } diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index d3538afa972f3..130e382e4e897 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -51,18 +51,40 @@ pub struct Stats { pub fn_stats: RefCell >, } -pub struct CrateContext { +/// The shared portion of a `CrateContext`. There is one `SharedCrateContext` +/// per crate. The data here is shared between all compilation units of the +/// crate, so it must not contain references to any LLVM data structures +/// (aside from metadata-related ones). +pub struct SharedCrateContext { + local_ccxs: Vec, + + metadata_llmod: ModuleRef, + metadata_llcx: ContextRef, + + exp_map2: resolve::ExportMap2, + reachable: NodeSet, + item_symbols: RefCell>, + link_meta: LinkMeta, + /// A set of static items which cannot be inlined into other crates. This + /// will prevent in IIItem() structures from being encoded into the metadata + /// that is generated + non_inlineable_statics: RefCell, + symbol_hasher: RefCell, + tcx: ty::ctxt, + stats: Stats, +} + +/// The local portion of a `CrateContext`. There is one `LocalCrateContext` +/// per compilation unit. Each one has its own LLVM `ContextRef` so that +/// several compilation units may be optimized in parallel. All other LLVM +/// data structures in the `LocalCrateContext` are tied to that `ContextRef`. +pub struct LocalCrateContext { llmod: ModuleRef, llcx: ContextRef, - metadata_llmod: ModuleRef, td: TargetData, tn: TypeNames, externs: RefCell, item_vals: RefCell>, - exp_map2: resolve::ExportMap2, - reachable: NodeSet, - item_symbols: RefCell>, - link_meta: LinkMeta, drop_glues: RefCell>, tydescs: RefCell>>, /// Set when running emit_tydescs to enforce that no more tydescs are @@ -73,10 +95,6 @@ pub struct CrateContext { /// Backwards version of the `external` map (inlined items to where they /// came from) external_srcs: RefCell>, - /// A set of static items which cannot be inlined into other crates. This - /// will prevent in IIItem() structures from being encoded into the metadata - /// that is generated - non_inlineable_statics: RefCell, /// Cache instances of monomorphized functions monomorphized: RefCell>, monomorphizing: RefCell>, @@ -109,11 +127,8 @@ pub struct CrateContext { lltypes: RefCell>, llsizingtypes: RefCell>, adt_reprs: RefCell>>, - symbol_hasher: RefCell, type_hashcodes: RefCell>, all_llvm_symbols: RefCell>, - tcx: ty::ctxt, - stats: Stats, int_type: Type, opaque_vec_type: Type, builder: BuilderRef_res, @@ -128,71 +143,178 @@ pub struct CrateContext { intrinsics: RefCell>, } -impl CrateContext { - pub fn new(name: &str, +pub struct CrateContext<'a> { + shared: &'a SharedCrateContext, + local: &'a LocalCrateContext, +} + +unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextRef, ModuleRef) { + let llcx = llvm::LLVMContextCreate(); + let llmod = mod_name.with_c_str(|buf| { + llvm::LLVMModuleCreateWithNameInContext(buf, llcx) + }); + sess.targ_cfg + .target_strs + .data_layout + .as_slice() + .with_c_str(|buf| { + llvm::LLVMSetDataLayout(llmod, buf); + }); + sess.targ_cfg + .target_strs + .target_triple + .as_slice() + .with_c_str(|buf| { + llvm::LLVMRustSetNormalizedTarget(llmod, buf); + }); + (llcx, llmod) +} + +impl SharedCrateContext { + pub fn new(crate_name: &str, + local_count: uint, tcx: ty::ctxt, emap2: resolve::ExportMap2, symbol_hasher: Sha256, link_meta: LinkMeta, reachable: NodeSet) - -> CrateContext { + -> SharedCrateContext { + let (metadata_llcx, metadata_llmod) = unsafe { + create_context_and_module(&tcx.sess, "metadata") + }; + + let mut shared_ccx = SharedCrateContext { + local_ccxs: Vec::with_capacity(local_count), + metadata_llmod: metadata_llmod, + metadata_llcx: metadata_llcx, + exp_map2: emap2, + reachable: reachable, + item_symbols: RefCell::new(NodeMap::new()), + link_meta: link_meta, + non_inlineable_statics: RefCell::new(NodeSet::new()), + symbol_hasher: RefCell::new(symbol_hasher), + tcx: tcx, + stats: Stats { + n_static_tydescs: Cell::new(0u), + n_glues_created: Cell::new(0u), + n_null_glues: Cell::new(0u), + n_real_glues: Cell::new(0u), + n_fns: Cell::new(0u), + n_monos: Cell::new(0u), + n_inlines: Cell::new(0u), + n_closures: Cell::new(0u), + n_llvm_insns: Cell::new(0u), + llvm_insns: RefCell::new(HashMap::new()), + fn_stats: RefCell::new(Vec::new()), + }, + }; + + for i in range(0, local_count) { + // Append ".rs" to crate name as LLVM module identifier. + // + // LLVM code generator emits a ".file filename" directive + // for ELF backends. Value of the "filename" is set as the + // LLVM module identifier. Due to a LLVM MC bug[1], LLVM + // crashes if the module identifier is same as other symbols + // such as a function name in the module. + // 1. http://llvm.org/bugs/show_bug.cgi?id=11479 + let llmod_id = format!("{}.{}.rs", crate_name, i); + let local_ccx = LocalCrateContext::new(&shared_ccx, llmod_id.as_slice()); + shared_ccx.local_ccxs.push(local_ccx); + } + + shared_ccx + } + + pub fn get_ccx<'a>(&'a self, index: uint) -> CrateContext<'a> { + CrateContext { + shared: self, + local: &self.local_ccxs[index], + } + } + + + pub fn metadata_llmod(&self) -> ModuleRef { + self.metadata_llmod + } + + pub fn metadata_llcx(&self) -> ContextRef { + self.metadata_llcx + } + + pub fn exp_map2<'a>(&'a self) -> &'a resolve::ExportMap2 { + &self.exp_map2 + } + + pub fn reachable<'a>(&'a self) -> &'a NodeSet { + &self.reachable + } + + pub fn item_symbols<'a>(&'a self) -> &'a RefCell> { + &self.item_symbols + } + + pub fn link_meta<'a>(&'a self) -> &'a LinkMeta { + &self.link_meta + } + + pub fn non_inlineable_statics<'a>(&'a self) -> &'a RefCell { + &self.non_inlineable_statics + } + + pub fn symbol_hasher<'a>(&'a self) -> &'a RefCell { + &self.symbol_hasher + } + + pub fn tcx<'a>(&'a self) -> &'a ty::ctxt { + &self.tcx + } + + pub fn take_tcx(self) -> ty::ctxt { + self.tcx + } + + pub fn sess<'a>(&'a self) -> &'a Session { + &self.tcx.sess + } + + pub fn stats<'a>(&'a self) -> &'a Stats { + &self.stats + } +} + +impl LocalCrateContext { + fn new(shared: &SharedCrateContext, + name: &str) + -> LocalCrateContext { unsafe { - let llcx = llvm::LLVMContextCreate(); - let llmod = name.with_c_str(|buf| { - llvm::LLVMModuleCreateWithNameInContext(buf, llcx) - }); - let metadata_llmod = format!("{}_metadata", name).with_c_str(|buf| { - llvm::LLVMModuleCreateWithNameInContext(buf, llcx) - }); - tcx.sess - .targ_cfg - .target_strs - .data_layout - .as_slice() - .with_c_str(|buf| { - llvm::LLVMSetDataLayout(llmod, buf); - llvm::LLVMSetDataLayout(metadata_llmod, buf); - }); - tcx.sess - .targ_cfg - .target_strs - .target_triple - .as_slice() - .with_c_str(|buf| { - llvm::LLVMRustSetNormalizedTarget(llmod, buf); - llvm::LLVMRustSetNormalizedTarget(metadata_llmod, buf); - }); - - let td = mk_target_data(tcx.sess - .targ_cfg - .target_strs - .data_layout - .as_slice()); - - let dbg_cx = if tcx.sess.opts.debuginfo != NoDebugInfo { + let (llcx, llmod) = create_context_and_module(&shared.tcx.sess, name); + + let td = mk_target_data(shared.tcx + .sess + .targ_cfg + .target_strs + .data_layout + .as_slice()); + + let dbg_cx = if shared.tcx.sess.opts.debuginfo != NoDebugInfo { Some(debuginfo::CrateDebugContext::new(llmod)) } else { None }; - let mut ccx = CrateContext { + let mut local_ccx = LocalCrateContext { llmod: llmod, llcx: llcx, - metadata_llmod: metadata_llmod, td: td, tn: TypeNames::new(), externs: RefCell::new(HashMap::new()), item_vals: RefCell::new(NodeMap::new()), - exp_map2: emap2, - reachable: reachable, - item_symbols: RefCell::new(NodeMap::new()), - link_meta: link_meta, drop_glues: RefCell::new(HashMap::new()), tydescs: RefCell::new(HashMap::new()), finished_tydescs: Cell::new(false), external: RefCell::new(DefIdMap::new()), external_srcs: RefCell::new(NodeMap::new()), - non_inlineable_statics: RefCell::new(NodeSet::new()), monomorphized: RefCell::new(HashMap::new()), monomorphizing: RefCell::new(DefIdMap::new()), vtables: RefCell::new(HashMap::new()), @@ -205,23 +327,8 @@ impl CrateContext { lltypes: RefCell::new(HashMap::new()), llsizingtypes: RefCell::new(HashMap::new()), adt_reprs: RefCell::new(HashMap::new()), - symbol_hasher: RefCell::new(symbol_hasher), type_hashcodes: RefCell::new(HashMap::new()), all_llvm_symbols: RefCell::new(HashSet::new()), - tcx: tcx, - stats: Stats { - n_static_tydescs: Cell::new(0u), - n_glues_created: Cell::new(0u), - n_null_glues: Cell::new(0u), - n_real_glues: Cell::new(0u), - n_fns: Cell::new(0u), - n_monos: Cell::new(0u), - n_inlines: Cell::new(0u), - n_closures: Cell::new(0u), - n_llvm_insns: Cell::new(0u), - llvm_insns: RefCell::new(HashMap::new()), - fn_stats: RefCell::new(Vec::new()), - }, int_type: Type::from_ref(ptr::mut_null()), opaque_vec_type: Type::from_ref(ptr::mut_null()), builder: BuilderRef_res(llvm::LLVMCreateBuilderInContext(llcx)), @@ -231,33 +338,61 @@ impl CrateContext { intrinsics: RefCell::new(HashMap::new()), }; - ccx.int_type = Type::int(&ccx); - ccx.opaque_vec_type = Type::opaque_vec(&ccx); + local_ccx.int_type = Type::int(&local_ccx.dummy_ccx(shared)); + local_ccx.opaque_vec_type = Type::opaque_vec(&local_ccx.dummy_ccx(shared)); + + // Done mutating local_ccx directly. (The rest of the + // initialization goes through RefCell.) + { + let ccx = local_ccx.dummy_ccx(shared); - let mut str_slice_ty = Type::named_struct(&ccx, "str_slice"); - str_slice_ty.set_struct_body([Type::i8p(&ccx), ccx.int_type()], false); - ccx.tn().associate_type("str_slice", &str_slice_ty); + let mut str_slice_ty = Type::named_struct(&ccx, "str_slice"); + str_slice_ty.set_struct_body([Type::i8p(&ccx), ccx.int_type()], false); + ccx.tn().associate_type("str_slice", &str_slice_ty); - ccx.tn().associate_type("tydesc", &Type::tydesc(&ccx, str_slice_ty)); + ccx.tn().associate_type("tydesc", &Type::tydesc(&ccx, str_slice_ty)); - if ccx.sess().count_llvm_insns() { - base::init_insn_ctxt() + if ccx.sess().count_llvm_insns() { + base::init_insn_ctxt() + } } - ccx + local_ccx } } - pub fn tcx<'a>(&'a self) -> &'a ty::ctxt { - &self.tcx + /// Create a dummy `CrateContext` from `self` and the provided + /// `SharedCrateContext`. This is somewhat dangerous because `self` may + /// not actually be an element of `shared.local_ccxs`, which can cause some + /// operations to `fail` unexpectedly. + /// + /// This is used in the `LocalCrateContext` constructor to allow calling + /// functions that expect a complete `CrateContext`, even before the local + /// portion is fully initialized and attached to the `SharedCrateContext`. + fn dummy_ccx<'a>(&'a self, shared: &'a SharedCrateContext) -> CrateContext<'a> { + CrateContext { + shared: shared, + local: self, + } } +} - pub fn take_tcx(self) -> ty::ctxt { - self.tcx +impl<'b> CrateContext<'b> { + pub fn shared(&self) -> &'b SharedCrateContext { + self.shared + } + + pub fn local(&self) -> &'b LocalCrateContext { + self.local + } + + + pub fn tcx<'a>(&'a self) -> &'a ty::ctxt { + &self.shared.tcx } pub fn sess<'a>(&'a self) -> &'a Session { - &self.tcx.sess + &self.shared.tcx.sess } pub fn builder<'a>(&'a self) -> Builder<'a> { @@ -265,15 +400,15 @@ impl CrateContext { } pub fn raw_builder<'a>(&'a self) -> BuilderRef { - self.builder.b + self.local.builder.b } pub fn tydesc_type(&self) -> Type { - self.tn.find_type("tydesc").unwrap() + self.local.tn.find_type("tydesc").unwrap() } pub fn get_intrinsic(&self, key: & &'static str) -> ValueRef { - match self.intrinsics.borrow().find_copy(key) { + match self.intrinsics().borrow().find_copy(key) { Some(v) => return v, _ => {} } @@ -297,160 +432,164 @@ impl CrateContext { pub fn llmod(&self) -> ModuleRef { - self.llmod + self.local.llmod } pub fn llcx(&self) -> ContextRef { - self.llcx + self.local.llcx } pub fn metadata_llmod(&self) -> ModuleRef { - self.metadata_llmod + self.shared.metadata_llmod + } + + pub fn metadata_llcx(&self) -> ContextRef { + self.shared.metadata_llcx } pub fn td<'a>(&'a self) -> &'a TargetData { - &self.td + &self.local.td } pub fn tn<'a>(&'a self) -> &'a TypeNames { - &self.tn + &self.local.tn } pub fn externs<'a>(&'a self) -> &'a RefCell { - &self.externs + &self.local.externs } pub fn item_vals<'a>(&'a self) -> &'a RefCell> { - &self.item_vals + &self.local.item_vals } pub fn exp_map2<'a>(&'a self) -> &'a resolve::ExportMap2 { - &self.exp_map2 + &self.shared.exp_map2 } pub fn reachable<'a>(&'a self) -> &'a NodeSet { - &self.reachable + &self.shared.reachable } pub fn item_symbols<'a>(&'a self) -> &'a RefCell> { - &self.item_symbols + &self.shared.item_symbols } pub fn link_meta<'a>(&'a self) -> &'a LinkMeta { - &self.link_meta + &self.shared.link_meta } pub fn drop_glues<'a>(&'a self) -> &'a RefCell> { - &self.drop_glues + &self.local.drop_glues } pub fn tydescs<'a>(&'a self) -> &'a RefCell>> { - &self.tydescs + &self.local.tydescs } pub fn finished_tydescs<'a>(&'a self) -> &'a Cell { - &self.finished_tydescs + &self.local.finished_tydescs } pub fn external<'a>(&'a self) -> &'a RefCell>> { - &self.external + &self.local.external } pub fn external_srcs<'a>(&'a self) -> &'a RefCell> { - &self.external_srcs + &self.local.external_srcs } pub fn non_inlineable_statics<'a>(&'a self) -> &'a RefCell { - &self.non_inlineable_statics + &self.shared.non_inlineable_statics } pub fn monomorphized<'a>(&'a self) -> &'a RefCell> { - &self.monomorphized + &self.local.monomorphized } pub fn monomorphizing<'a>(&'a self) -> &'a RefCell> { - &self.monomorphizing + &self.local.monomorphizing } pub fn vtables<'a>(&'a self) -> &'a RefCell> { - &self.vtables + &self.local.vtables } pub fn const_cstr_cache<'a>(&'a self) -> &'a RefCell> { - &self.const_cstr_cache + &self.local.const_cstr_cache } pub fn const_globals<'a>(&'a self) -> &'a RefCell> { - &self.const_globals + &self.local.const_globals } pub fn const_values<'a>(&'a self) -> &'a RefCell> { - &self.const_values + &self.local.const_values } pub fn extern_const_values<'a>(&'a self) -> &'a RefCell> { - &self.extern_const_values + &self.local.extern_const_values } pub fn impl_method_cache<'a>(&'a self) -> &'a RefCell> { - &self.impl_method_cache + &self.local.impl_method_cache } pub fn closure_bare_wrapper_cache<'a>(&'a self) -> &'a RefCell> { - &self.closure_bare_wrapper_cache + &self.local.closure_bare_wrapper_cache } pub fn lltypes<'a>(&'a self) -> &'a RefCell> { - &self.lltypes + &self.local.lltypes } pub fn llsizingtypes<'a>(&'a self) -> &'a RefCell> { - &self.llsizingtypes + &self.local.llsizingtypes } pub fn adt_reprs<'a>(&'a self) -> &'a RefCell>> { - &self.adt_reprs + &self.local.adt_reprs } pub fn symbol_hasher<'a>(&'a self) -> &'a RefCell { - &self.symbol_hasher + &self.shared.symbol_hasher } pub fn type_hashcodes<'a>(&'a self) -> &'a RefCell> { - &self.type_hashcodes + &self.local.type_hashcodes } pub fn all_llvm_symbols<'a>(&'a self) -> &'a RefCell> { - &self.all_llvm_symbols + &self.local.all_llvm_symbols } pub fn stats<'a>(&'a self) -> &'a Stats { - &self.stats + &self.shared.stats } pub fn int_type(&self) -> Type { - self.int_type + self.local.int_type } pub fn opaque_vec_type(&self) -> Type { - self.opaque_vec_type + self.local.opaque_vec_type } pub fn unboxed_closure_vals<'a>(&'a self) -> &'a RefCell> { - &self.unboxed_closure_vals + &self.local.unboxed_closure_vals } pub fn dbg_cx<'a>(&'a self) -> &'a Option { - &self.dbg_cx + &self.local.dbg_cx } pub fn eh_personality<'a>(&'a self) -> &'a RefCell> { - &self.eh_personality + &self.local.eh_personality } fn intrinsics<'a>(&'a self) -> &'a RefCell> { - &self.intrinsics + &self.local.intrinsics } }