diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 6044bec2c5a..174a93ed23e 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -196,9 +196,9 @@ impl TypedArena { self.end.set(last_chunk.end()); return; } else { - let prev_capacity = last_chunk.storage.cap(); + new_capacity = last_chunk.storage.cap(); loop { - new_capacity = prev_capacity.checked_mul(2).unwrap(); + new_capacity = new_capacity.checked_mul(2).unwrap(); if new_capacity >= currently_used_cap + n { break; } @@ -280,6 +280,133 @@ impl Drop for TypedArena { unsafe impl Send for TypedArena {} +pub struct DroplessArena { + /// A pointer to the next object to be allocated. + ptr: Cell<*mut u8>, + + /// A pointer to the end of the allocated area. When this pointer is + /// reached, a new chunk is allocated. + end: Cell<*mut u8>, + + /// A vector of arena chunks. + chunks: RefCell>>, +} + +impl DroplessArena { + pub fn new() -> DroplessArena { + DroplessArena { + ptr: Cell::new(0 as *mut u8), + end: Cell::new(0 as *mut u8), + chunks: RefCell::new(vec![]), + } + } + + pub fn in_arena(&self, ptr: *const T) -> bool { + let ptr = ptr as *const u8 as *mut u8; + for chunk in &*self.chunks.borrow() { + if chunk.start() <= ptr && ptr < chunk.end() { + return true; + } + } + + false + } + + fn align_for(&self) { + let align = mem::align_of::(); + let final_address = ((self.ptr.get() as usize) + align - 1) & !(align - 1); + self.ptr.set(final_address as *mut u8); + assert!(self.ptr <= self.end); + } + + #[inline(never)] + #[cold] + fn grow(&self, n: usize) { + let needed_bytes = n * mem::size_of::(); + unsafe { + let mut chunks = self.chunks.borrow_mut(); + let (chunk, mut new_capacity); + if let Some(last_chunk) = chunks.last_mut() { + let used_bytes = self.ptr.get() as usize - last_chunk.start() as usize; + if last_chunk.storage.reserve_in_place(used_bytes, needed_bytes) { + self.end.set(last_chunk.end()); + return; + } else { + new_capacity = last_chunk.storage.cap(); + loop { + new_capacity = new_capacity.checked_mul(2).unwrap(); + if new_capacity >= used_bytes + needed_bytes { + break; + } + } + } + } else { + new_capacity = cmp::max(needed_bytes, PAGE); + } + chunk = TypedArenaChunk::::new(new_capacity); + self.ptr.set(chunk.start()); + self.end.set(chunk.end()); + chunks.push(chunk); + } + } + + #[inline] + pub fn alloc(&self, object: T) -> &mut T { + unsafe { + assert!(!intrinsics::needs_drop::()); + assert!(mem::size_of::() != 0); + + self.align_for::(); + let future_end = intrinsics::arith_offset(self.ptr.get(), mem::size_of::() as isize); + if (future_end as *mut u8) >= self.end.get() { + self.grow::(1) + } + + let ptr = self.ptr.get(); + // Set the pointer past ourselves + self.ptr.set(intrinsics::arith_offset( + self.ptr.get(), mem::size_of::() as isize + ) as *mut u8); + // Write into uninitialized memory. + ptr::write(ptr as *mut T, object); + &mut *(ptr as *mut T) + } + } + + /// Allocates a slice of objects that are copied into the `DroplessArena`, returning a mutable + /// reference to it. Will panic if passed a zero-sized type. + /// + /// Panics: + /// - Zero-sized types + /// - Zero-length slices + #[inline] + pub fn alloc_slice(&self, slice: &[T]) -> &mut [T] + where T: Copy { + unsafe { + assert!(!intrinsics::needs_drop::()); + } + assert!(mem::size_of::() != 0); + assert!(slice.len() != 0); + self.align_for::(); + + let future_end = unsafe { + intrinsics::arith_offset(self.ptr.get(), (slice.len() * mem::size_of::()) as isize) + }; + if (future_end as *mut u8) >= self.end.get() { + self.grow::(slice.len()); + } + + unsafe { + let arena_slice = slice::from_raw_parts_mut(self.ptr.get() as *mut T, slice.len()); + self.ptr.set(intrinsics::arith_offset( + self.ptr.get(), (slice.len() * mem::size_of::()) as isize + ) as *mut u8); + arena_slice.copy_from_slice(slice); + arena_slice + } + } +} + #[cfg(test)] mod tests { extern crate test; diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 3e7cc0b1e3e..7b6ed56b779 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -41,6 +41,7 @@ use syntax::ast; use errors::DiagnosticBuilder; use syntax_pos::{self, Span, DUMMY_SP}; use util::nodemap::{FxHashMap, FxHashSet, NodeMap}; +use arena::DroplessArena; use self::combine::CombineFields; use self::higher_ranked::HrMatchResult; @@ -374,7 +375,7 @@ impl fmt::Display for FixupError { /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(InferCtxt<'b, 'gcx, 'tcx>). pub struct InferCtxtBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { global_tcx: TyCtxt<'a, 'gcx, 'gcx>, - arenas: ty::CtxtArenas<'tcx>, + arena: DroplessArena, tables: Option>>, param_env: Option>, projection_mode: Reveal, @@ -388,7 +389,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> { -> InferCtxtBuilder<'a, 'gcx, 'tcx> { InferCtxtBuilder { global_tcx: self, - arenas: ty::CtxtArenas::new(), + arena: DroplessArena::new(), tables: tables.map(RefCell::new), param_env: param_env, projection_mode: projection_mode, @@ -426,7 +427,7 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> { { let InferCtxtBuilder { global_tcx, - ref arenas, + ref arena, ref tables, ref mut param_env, projection_mode, @@ -439,7 +440,7 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> { let param_env = param_env.take().unwrap_or_else(|| { global_tcx.empty_parameter_environment() }); - global_tcx.enter_local(arenas, |tcx| f(InferCtxt { + global_tcx.enter_local(arena, |tcx| f(InferCtxt { tcx: tcx, tables: tables, projection_cache: RefCell::new(traits::ProjectionCache::new()), diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 380c5b0eb6f..f58d7dcb45f 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -39,7 +39,7 @@ use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet}; use util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::accumulate_vec::AccumulateVec; -use arena::TypedArena; +use arena::{TypedArena, DroplessArena}; use std::borrow::Borrow; use std::cell::{Cell, RefCell}; use std::hash::{Hash, Hasher}; @@ -55,16 +55,9 @@ use syntax::symbol::{Symbol, keywords}; use hir; /// Internal storage -pub struct CtxtArenas<'tcx> { +pub struct GlobalArenas<'tcx> { // internings - type_: TypedArena>, - type_list: TypedArena>, - substs: TypedArena>, - bare_fn: TypedArena>, - region: TypedArena, - stability: TypedArena, layout: TypedArena, - existential_predicates: TypedArena>, // references generics: TypedArena>, @@ -73,29 +66,21 @@ pub struct CtxtArenas<'tcx> { mir: TypedArena>>, } -impl<'tcx> CtxtArenas<'tcx> { - pub fn new() -> CtxtArenas<'tcx> { - CtxtArenas { - type_: TypedArena::new(), - type_list: TypedArena::new(), - substs: TypedArena::new(), - bare_fn: TypedArena::new(), - region: TypedArena::new(), - stability: TypedArena::new(), +impl<'tcx> GlobalArenas<'tcx> { + pub fn new() -> GlobalArenas<'tcx> { + GlobalArenas { layout: TypedArena::new(), - existential_predicates: TypedArena::new(), - generics: TypedArena::new(), trait_def: TypedArena::new(), adt_def: TypedArena::new(), - mir: TypedArena::new() + mir: TypedArena::new(), } } } pub struct CtxtInterners<'tcx> { - /// The arenas that types etc are allocated from. - arenas: &'tcx CtxtArenas<'tcx>, + /// The arena that types, regions, etc are allocated from + arena: &'tcx DroplessArena, /// Specifically use a speedy hash algorithm for these hash sets, /// they're accessed quite often. @@ -104,22 +89,18 @@ pub struct CtxtInterners<'tcx> { substs: RefCell>>>, bare_fn: RefCell>>>, region: RefCell>>, - stability: RefCell>, - layout: RefCell>, existential_predicates: RefCell>>>>, } impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> { - fn new(arenas: &'tcx CtxtArenas<'tcx>) -> CtxtInterners<'tcx> { + fn new(arena: &'tcx DroplessArena) -> CtxtInterners<'tcx> { CtxtInterners { - arenas: arenas, + arena: arena, type_: RefCell::new(FxHashSet()), type_list: RefCell::new(FxHashSet()), substs: RefCell::new(FxHashSet()), bare_fn: RefCell::new(FxHashSet()), region: RefCell::new(FxHashSet()), - stability: RefCell::new(FxHashSet()), - layout: RefCell::new(FxHashSet()), existential_predicates: RefCell::new(FxHashSet()), } } @@ -158,7 +139,7 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> { let ty_struct: TyS<'gcx> = unsafe { mem::transmute(ty_struct) }; - let ty: Ty<'gcx> = interner.arenas.type_.alloc(ty_struct); + let ty: Ty<'gcx> = interner.arena.alloc(ty_struct); global_interner.unwrap().insert(Interned(ty)); return ty; } @@ -174,7 +155,7 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> { } // Don't be &mut TyS. - let ty: Ty<'tcx> = self.arenas.type_.alloc(ty_struct); + let ty: Ty<'tcx> = self.arena.alloc(ty_struct); interner.insert(Interned(ty)); ty }; @@ -391,6 +372,7 @@ impl<'a, 'gcx, 'tcx> Deref for TyCtxt<'a, 'gcx, 'tcx> { } pub struct GlobalCtxt<'tcx> { + global_arenas: &'tcx GlobalArenas<'tcx>, global_interners: CtxtInterners<'tcx>, pub specializes_cache: RefCell, @@ -586,6 +568,10 @@ pub struct GlobalCtxt<'tcx> { /// Map from function to the `#[derive]` mode that it's defining. Only used /// by `proc-macro` crates. pub derive_macros: RefCell>, + + stability_interner: RefCell>, + + layout_interner: RefCell>, } impl<'tcx> GlobalCtxt<'tcx> { @@ -649,15 +635,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn alloc_generics(self, generics: ty::Generics<'gcx>) -> &'gcx ty::Generics<'gcx> { - self.global_interners.arenas.generics.alloc(generics) + self.global_arenas.generics.alloc(generics) } pub fn alloc_mir(self, mir: Mir<'gcx>) -> &'gcx RefCell> { - self.global_interners.arenas.mir.alloc(RefCell::new(mir)) + self.global_arenas.mir.alloc(RefCell::new(mir)) } pub fn alloc_trait_def(self, def: ty::TraitDef) -> &'gcx ty::TraitDef { - self.global_interners.arenas.trait_def.alloc(def) + self.global_arenas.trait_def.alloc(def) } pub fn alloc_adt_def(self, @@ -666,32 +652,28 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { variants: Vec) -> &'gcx ty::AdtDef { let def = ty::AdtDef::new(self, did, kind, variants); - self.global_interners.arenas.adt_def.alloc(def) + self.global_arenas.adt_def.alloc(def) } pub fn intern_stability(self, stab: attr::Stability) -> &'gcx attr::Stability { - if let Some(st) = self.global_interners.stability.borrow().get(&stab) { + if let Some(st) = self.stability_interner.borrow().get(&stab) { return st; } - let interned = self.global_interners.arenas.stability.alloc(stab); - if let Some(prev) = self.global_interners.stability - .borrow_mut() - .replace(interned) { + let interned = self.global_interners.arena.alloc(stab); + if let Some(prev) = self.stability_interner.borrow_mut().replace(interned) { bug!("Tried to overwrite interned Stability: {:?}", prev) } interned } pub fn intern_layout(self, layout: Layout) -> &'gcx Layout { - if let Some(layout) = self.global_interners.layout.borrow().get(&layout) { + if let Some(layout) = self.layout_interner.borrow().get(&layout) { return layout; } - let interned = self.global_interners.arenas.layout.alloc(layout); - if let Some(prev) = self.global_interners.layout - .borrow_mut() - .replace(interned) { + let interned = self.global_arenas.layout.alloc(layout); + if let Some(prev) = self.layout_interner.borrow_mut().replace(interned) { bug!("Tried to overwrite interned Layout: {:?}", prev) } interned @@ -728,24 +710,26 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// value (types, substs, etc.) can only be used while `ty::tls` has a valid /// reference to the context, to allow formatting values that need it. pub fn create_and_enter(s: &'tcx Session, - arenas: &'tcx CtxtArenas<'tcx>, + arenas: &'tcx GlobalArenas<'tcx>, + arena: &'tcx DroplessArena, resolutions: ty::Resolutions, named_region_map: resolve_lifetime::NamedRegionMap, map: ast_map::Map<'tcx>, region_maps: RegionMaps, lang_items: middle::lang_items::LanguageItems, stability: stability::Index<'tcx>, - crate_name: &str, + crate_name: &str, f: F) -> R where F: for<'b> FnOnce(TyCtxt<'b, 'tcx, 'tcx>) -> R { let data_layout = TargetDataLayout::parse(s); - let interners = CtxtInterners::new(arenas); + let interners = CtxtInterners::new(arena); let common_types = CommonTypes::new(&interners); let dep_graph = map.dep_graph.clone(); let fulfilled_predicates = traits::GlobalFulfilledPredicates::new(dep_graph.clone()); tls::enter_global(GlobalCtxt { specializes_cache: RefCell::new(traits::SpecializesCache::new()), + global_arenas: arenas, global_interners: interners, dep_graph: dep_graph.clone(), types: common_types, @@ -794,18 +778,20 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { crate_name: Symbol::intern(crate_name), data_layout: data_layout, layout_cache: RefCell::new(FxHashMap()), + layout_interner: RefCell::new(FxHashSet()), layout_depth: Cell::new(0), derive_macros: RefCell::new(NodeMap()), + stability_interner: RefCell::new(FxHashSet()), }, f) } } impl<'gcx: 'tcx, 'tcx> GlobalCtxt<'gcx> { - /// Call the closure with a local `TyCtxt` using the given arenas. - pub fn enter_local(&self, arenas: &'tcx CtxtArenas<'tcx>, f: F) -> R + /// Call the closure with a local `TyCtxt` using the given arena. + pub fn enter_local(&self, arena: &'tcx DroplessArena, f: F) -> R where F: for<'a> FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> R { - let interners = CtxtInterners::new(arenas); + let interners = CtxtInterners::new(arena); tls::enter(self, &interners, f) } } @@ -835,10 +821,8 @@ pub trait Lift<'tcx> { impl<'a, 'tcx> Lift<'tcx> for Ty<'a> { type Lifted = Ty<'tcx>; fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option> { - if let Some(&Interned(ty)) = tcx.interners.type_.borrow().get(&self.sty) { - if *self as *const _ == ty as *const _ { - return Some(ty); - } + if tcx.interners.arena.in_arena(*self as *const _) { + return Some(unsafe { mem::transmute(*self) }); } // Also try in the global tcx if we're not that. if !tcx.is_global() { @@ -855,10 +839,8 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> { if self.len() == 0 { return Some(Slice::empty()); } - if let Some(&Interned(substs)) = tcx.interners.substs.borrow().get(&self[..]) { - if *self as *const _ == substs as *const _ { - return Some(substs); - } + if tcx.interners.arena.in_arena(&self[..] as *const _) { + return Some(unsafe { mem::transmute(*self) }); } // Also try in the global tcx if we're not that. if !tcx.is_global() { @@ -872,10 +854,8 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Substs<'a> { impl<'a, 'tcx> Lift<'tcx> for &'a Region { type Lifted = &'tcx Region; fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Region> { - if let Some(&Interned(region)) = tcx.interners.region.borrow().get(*self) { - if *self as *const _ == region as *const _ { - return Some(region); - } + if tcx.interners.arena.in_arena(*self as *const _) { + return Some(unsafe { mem::transmute(*self) }); } // Also try in the global tcx if we're not that. if !tcx.is_global() { @@ -893,10 +873,8 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Slice> { if self.len() == 0 { return Some(Slice::empty()); } - if let Some(&Interned(list)) = tcx.interners.type_list.borrow().get(&self[..]) { - if *self as *const _ == list as *const _ { - return Some(list); - } + if tcx.interners.arena.in_arena(*self as *const _) { + return Some(unsafe { mem::transmute(*self) }); } // Also try in the global tcx if we're not that. if !tcx.is_global() { @@ -914,10 +892,8 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Slice> { if self.is_empty() { return Some(Slice::empty()); } - if let Some(&Interned(eps)) = tcx.interners.existential_predicates.borrow().get(&self[..]) { - if *self as *const _ == eps as *const _ { - return Some(eps); - } + if tcx.interners.arena.in_arena(*self as *const _) { + return Some(unsafe { mem::transmute(*self) }); } // Also try in the global tcx if we're not that. if !tcx.is_global() { @@ -932,10 +908,8 @@ impl<'a, 'tcx> Lift<'tcx> for &'a BareFnTy<'a> { type Lifted = &'tcx BareFnTy<'tcx>; fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx BareFnTy<'tcx>> { - if let Some(&Interned(fty)) = tcx.interners.bare_fn.borrow().get(*self) { - if *self as *const _ == fty as *const _ { - return Some(fty); - } + if tcx.interners.arena.in_arena(*self as *const _) { + return Some(unsafe { mem::transmute(*self) }); } // Also try in the global tcx if we're not that. if !tcx.is_global() { @@ -1101,8 +1075,8 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { println!("Substs interner: #{}", self.interners.substs.borrow().len()); println!("BareFnTy interner: #{}", self.interners.bare_fn.borrow().len()); println!("Region interner: #{}", self.interners.region.borrow().len()); - println!("Stability interner: #{}", self.interners.stability.borrow().len()); - println!("Layout interner: #{}", self.interners.layout.borrow().len()); + println!("Stability interner: #{}", self.stability_interner.borrow().len()); + println!("Layout interner: #{}", self.layout_interner.borrow().len()); } } @@ -1205,8 +1179,7 @@ macro_rules! intern_method { let v = unsafe { mem::transmute(v) }; - let i = ($alloc_to_ret)(self.global_interners.arenas.$name - .$alloc_method(v)); + let i = ($alloc_to_ret)(self.global_interners.arena.$alloc_method(v)); self.global_interners.$name.borrow_mut().insert(Interned(i)); return i; } @@ -1220,7 +1193,7 @@ macro_rules! intern_method { } } - let i = ($alloc_to_ret)(self.interners.arenas.$name.$alloc_method(v)); + let i = ($alloc_to_ret)(self.interners.arena.$alloc_method(v)); self.interners.$name.borrow_mut().insert(Interned(i)); i } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index b03a432de41..3e33d246b6d 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -68,8 +68,8 @@ pub use self::sty::Region::*; pub use self::sty::TypeVariants::*; pub use self::contents::TypeContents; -pub use self::context::{TyCtxt, tls}; -pub use self::context::{CtxtArenas, Lift, Tables}; +pub use self::context::{TyCtxt, GlobalArenas, tls}; +pub use self::context::{Lift, Tables}; pub use self::trait_def::{TraitDef, TraitFlags}; diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 291f0e0d50d..e9c14b4f99c 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -19,7 +19,7 @@ use rustc::session::search_paths::PathKind; use rustc::lint; use rustc::middle::{self, dependency_format, stability, reachable}; use rustc::middle::privacy::AccessLevels; -use rustc::ty::{self, TyCtxt, Resolutions}; +use rustc::ty::{self, TyCtxt, Resolutions, GlobalArenas}; use rustc::util::common::time; use rustc::util::nodemap::{NodeSet, NodeMap}; use rustc_borrowck as borrowck; @@ -55,6 +55,7 @@ use syntax::symbol::Symbol; use syntax::util::node_count::NodeCounter; use syntax; use syntax_ext; +use arena::DroplessArena; use derive_registrar; @@ -123,7 +124,8 @@ pub fn compile_input(sess: &Session, write_out_deps(sess, &outputs, &crate_name); - let arenas = ty::CtxtArenas::new(); + let arena = DroplessArena::new(); + let arenas = GlobalArenas::new(); // Construct the HIR map let hir_map = time(sess.time_passes(), @@ -138,6 +140,7 @@ pub fn compile_input(sess: &Session, sess, outdir, output, + &arena, &arenas, &cstore, &hir_map, @@ -164,6 +167,7 @@ pub fn compile_input(sess: &Session, hir_map, analysis, resolutions, + &arena, &arenas, &crate_name, |tcx, analysis, incremental_hashes_map, result| { @@ -331,7 +335,8 @@ pub struct CompileState<'a, 'tcx: 'a> { pub output_filenames: Option<&'a OutputFilenames>, pub out_dir: Option<&'a Path>, pub out_file: Option<&'a Path>, - pub arenas: Option<&'tcx ty::CtxtArenas<'tcx>>, + pub arena: Option<&'tcx DroplessArena>, + pub arenas: Option<&'tcx GlobalArenas<'tcx>>, pub expanded_crate: Option<&'a ast::Crate>, pub hir_crate: Option<&'a hir::Crate>, pub ast_map: Option<&'a hir_map::Map<'tcx>>, @@ -351,6 +356,7 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> { session: session, out_dir: out_dir.as_ref().map(|s| &**s), out_file: None, + arena: None, arenas: None, krate: None, registry: None, @@ -405,7 +411,8 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> { session: &'tcx Session, out_dir: &'a Option, out_file: &'a Option, - arenas: &'tcx ty::CtxtArenas<'tcx>, + arena: &'tcx DroplessArena, + arenas: &'tcx GlobalArenas<'tcx>, cstore: &'a CStore, hir_map: &'a hir_map::Map<'tcx>, analysis: &'a ty::CrateAnalysis<'static>, @@ -416,6 +423,7 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> { -> Self { CompileState { crate_name: Some(crate_name), + arena: Some(arena), arenas: Some(arenas), cstore: Some(cstore), ast_map: Some(hir_map), @@ -800,7 +808,8 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, hir_map: hir_map::Map<'tcx>, mut analysis: ty::CrateAnalysis<'tcx>, resolutions: Resolutions, - arenas: &'tcx ty::CtxtArenas<'tcx>, + arena: &'tcx DroplessArena, + arenas: &'tcx GlobalArenas<'tcx>, name: &str, f: F) -> Result @@ -858,6 +867,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, TyCtxt::create_and_enter(sess, arenas, + arena, resolutions, named_region_map, hir_map, diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 5ceec9edda3..ca31022b04c 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -462,6 +462,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { &state.expanded_crate.take().unwrap(), state.crate_name.unwrap(), ppm, + state.arena.unwrap(), state.arenas.unwrap(), opt_uii.clone(), state.out_file); diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 5103a55fd71..cc288619cde 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -17,7 +17,7 @@ use self::NodesMatchingUII::*; use {abort_on_err, driver}; -use rustc::ty::{self, TyCtxt, Resolutions}; +use rustc::ty::{self, TyCtxt, GlobalArenas, Resolutions}; use rustc::cfg; use rustc::cfg::graphviz::LabelledCFG; use rustc::dep_graph::DepGraph; @@ -51,6 +51,8 @@ use rustc::hir::map::blocks; use rustc::hir; use rustc::hir::print as pprust_hir; +use arena::DroplessArena; + #[derive(Copy, Clone, PartialEq, Debug)] pub enum PpSourceMode { PpmNormal, @@ -201,7 +203,8 @@ impl PpSourceMode { ast_map: &hir_map::Map<'tcx>, analysis: &ty::CrateAnalysis<'tcx>, resolutions: &Resolutions, - arenas: &'tcx ty::CtxtArenas<'tcx>, + arena: &'tcx DroplessArena, + arenas: &'tcx GlobalArenas<'tcx>, id: &str, payload: B, f: F) @@ -229,6 +232,7 @@ impl PpSourceMode { ast_map.clone(), analysis.clone(), resolutions.clone(), + arena, arenas, id, |tcx, _, _, _| { @@ -846,7 +850,8 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, krate: &ast::Crate, crate_name: &str, ppm: PpMode, - arenas: &'tcx ty::CtxtArenas<'tcx>, + arena: &'tcx DroplessArena, + arenas: &'tcx GlobalArenas<'tcx>, opt_uii: Option, ofile: Option<&Path>) { let dep_graph = DepGraph::new(false); @@ -858,6 +863,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, analysis, resolutions, crate_name, + arena, arenas, ppm, opt_uii, @@ -894,6 +900,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, ast_map, analysis, resolutions, + arena, arenas, crate_name, box out, @@ -917,6 +924,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, ast_map, analysis, resolutions, + arena, arenas, crate_name, (out, uii), @@ -959,7 +967,8 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session, analysis: &ty::CrateAnalysis<'tcx>, resolutions: &Resolutions, crate_name: &str, - arenas: &'tcx ty::CtxtArenas<'tcx>, + arena: &'tcx DroplessArena, + arenas: &'tcx GlobalArenas<'tcx>, ppm: PpMode, uii: Option, ofile: Option<&Path>) { @@ -977,6 +986,7 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session, ast_map.clone(), analysis.clone(), resolutions.clone(), + arena, arenas, crate_name, |tcx, _, _, _| { diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index cbab39c3908..887e586a311 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -38,6 +38,7 @@ use errors::{Level, DiagnosticBuilder}; use syntax::feature_gate::UnstableFeatures; use syntax::symbol::Symbol; use syntax_pos::DUMMY_SP; +use arena::DroplessArena; use rustc::hir; @@ -128,7 +129,8 @@ fn test_env(source_string: &str, }; let _ignore = dep_graph.in_ignore(); - let arenas = ty::CtxtArenas::new(); + let arena = DroplessArena::new(); + let arenas = ty::GlobalArenas::new(); let ast_map = hir_map::map_crate(&mut hir_forest, defs); // run just enough stuff to build a tcx: @@ -138,6 +140,7 @@ fn test_env(source_string: &str, let index = stability::Index::new(&ast_map); TyCtxt::create_and_enter(&sess, &arenas, + &arena, resolutions, named_region_map.unwrap(), ast_map, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index df25473ddd9..1f989c557d3 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -15,7 +15,7 @@ use rustc::session::{self, config}; use rustc::hir::def_id::DefId; use rustc::hir::def::{Def, ExportMap}; use rustc::middle::privacy::AccessLevels; -use rustc::ty::{self, TyCtxt, Ty}; +use rustc::ty::{self, TyCtxt, GlobalArenas, Ty}; use rustc::hir::map as hir_map; use rustc::lint; use rustc::util::nodemap::{FxHashMap, NodeMap}; @@ -37,6 +37,7 @@ use visit_ast::RustdocVisitor; use clean; use clean::Clean; use html::render::RenderInfo; +use arena::DroplessArena; pub use rustc::session::config::Input; pub use rustc::session::search_paths::SearchPaths; @@ -160,13 +161,15 @@ pub fn run_core(search_paths: SearchPaths, ).expect("phase_2_configure_and_expand aborted in rustdoc!") }; - let arenas = ty::CtxtArenas::new(); + let arena = DroplessArena::new(); + let arenas = GlobalArenas::new(); let hir_map = hir_map::map_crate(&mut hir_forest, defs); abort_on_err(driver::phase_3_run_analysis_passes(&sess, hir_map, analysis, resolutions, + &arena, &arenas, &name, |tcx, analysis, _, result| {