diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 63ea24d89ff..99945ebf8c4 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -22,7 +22,7 @@ use rustc_codegen_ssa::back::link::emit_metadata; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_codegen_utils::link::filename_for_metadata; use rustc_data_structures::{box_region_allow_access, declare_box_region_type, parallel}; -use rustc_data_structures::sync::{Lrc, ParallelIterator, par_iter}; +use rustc_data_structures::sync::{Lrc, Once, ParallelIterator, par_iter}; use rustc_errors::PResult; use rustc_incremental; use rustc_metadata::cstore; @@ -740,44 +740,41 @@ pub fn default_provide_extern(providers: &mut ty::query::Providers<'_>) { rustc_codegen_ssa::provide_extern(providers); } -declare_box_region_type!( - pub BoxedGlobalCtxt, - for('tcx), - (&'tcx GlobalCtxt<'tcx>) -> ((), ()) -); +pub struct BoxedGlobalCtxt<'tcx>(&'tcx GlobalCtxt<'tcx>); -impl BoxedGlobalCtxt { +impl<'gcx> BoxedGlobalCtxt<'gcx> { pub fn enter(&mut self, f: F) -> R where F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> R, { - self.access(|gcx| ty::tls::enter_global(gcx, |tcx| f(tcx))) + ty::tls::enter_global(self.0, |tcx| f(tcx)) + } + + pub fn print_stats(&self) { + self.0.queries.print_stats() } } -pub fn create_global_ctxt( - compiler: &Compiler, +pub fn create_global_ctxt<'gcx>( + compiler: &'gcx Compiler, lint_store: Lrc, - mut hir_forest: hir::map::Forest, + hir_forest: &'gcx hir::map::Forest, mut resolver_outputs: ResolverOutputs, outputs: OutputFilenames, crate_name: &str, -) -> BoxedGlobalCtxt { - let sess = compiler.session().clone(); + global_ctxt: &'gcx Once>, + arenas: &'gcx Once, +) -> BoxedGlobalCtxt<'gcx> { + let sess = &compiler.session(); let codegen_backend = compiler.codegen_backend().clone(); - let crate_name = crate_name.to_string(); let defs = mem::take(&mut resolver_outputs.definitions); let override_queries = compiler.override_queries; - let ((), result) = BoxedGlobalCtxt::new(static move || { - let sess = &*sess; - - let global_ctxt: Option>; - let arenas = AllArenas::new(); + let arenas = arenas.init_locking(|| AllArenas::new()); // Construct the HIR map. let hir_map = time(sess, "indexing HIR", || { - hir::map::map_crate(sess, &*resolver_outputs.cstore, &mut hir_forest, defs) + hir::map::map_crate(sess, &*resolver_outputs.cstore, &hir_forest, defs) }); let query_result_on_disk_cache = time(sess, "load query result cache", || { @@ -796,7 +793,7 @@ pub fn create_global_ctxt( callback(sess, &mut local_providers, &mut extern_providers); } - let gcx = TyCtxt::create_global_ctxt( + let gcx = global_ctxt.init_locking(move || TyCtxt::create_global_ctxt( sess, lint_store, local_providers, @@ -807,26 +804,15 @@ pub fn create_global_ctxt( query_result_on_disk_cache, &crate_name, &outputs - ); + )); - global_ctxt = Some(gcx); - let gcx = global_ctxt.as_ref().unwrap(); - - ty::tls::enter_global(gcx, |tcx| { + ty::tls::enter_global(&gcx, |tcx| { // Do some initialization of the DepGraph that can only be done with the // tcx available. time(tcx.sess, "dep graph tcx init", || rustc_incremental::dep_graph_tcx_init(tcx)); }); - yield BoxedGlobalCtxt::initial_yield(()); - box_region_allow_access!(for('tcx), (&'tcx GlobalCtxt<'tcx>), (gcx)); - - if sess.opts.debugging_opts.query_stats { - gcx.queries.print_stats(); - } - }); - - result + BoxedGlobalCtxt(gcx) } /// Runs the resolution, type-checking, region checking and other diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 3b03cfc12bc..a90483f8c71 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -2,7 +2,7 @@ use crate::interface::{Compiler, Result}; use crate::passes::{self, BoxedResolver, BoxedGlobalCtxt}; use rustc_incremental::DepGraphFuture; -use rustc_data_structures::sync::Lrc; +use rustc_data_structures::sync::{Lrc, Once}; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc::session::config::{OutputFilenames, OutputType}; use rustc::util::common::{time, ErrorReported}; @@ -12,7 +12,7 @@ use rustc::session::Session; use rustc::lint::LintStore; use rustc::hir::def_id::LOCAL_CRATE; use rustc::ty::steal::Steal; -use rustc::ty::ResolverOutputs; +use rustc::ty::{AllArenas, ResolverOutputs, GlobalCtxt}; use rustc::dep_graph::DepGraph; use std::cell::{Ref, RefMut, RefCell}; use std::rc::Rc; @@ -70,6 +70,9 @@ impl Default for Query { pub struct Queries<'comp> { compiler: &'comp Compiler, + gcx: Once>, + arenas: Once, + forest: Once, dep_graph_future: Query>, parse: Query, @@ -77,9 +80,9 @@ pub struct Queries<'comp> { register_plugins: Query<(ast::Crate, Lrc)>, expansion: Query<(ast::Crate, Steal>>, Lrc)>, dep_graph: Query, - lower_to_hir: Query<(Steal, Steal)>, + lower_to_hir: Query<(&'comp hir::map::Forest, Steal)>, prepare_outputs: Query, - global_ctxt: Query, + global_ctxt: Query>, ongoing_codegen: Query>, } @@ -87,6 +90,9 @@ impl<'comp> Queries<'comp> { pub fn new(compiler: &'comp Compiler) -> Queries<'comp> { Queries { compiler, + gcx: Once::new(), + arenas: Once::new(), + forest: Once::new(), dep_graph_future: Default::default(), parse: Default::default(), crate_name: Default::default(), @@ -209,15 +215,15 @@ impl<'comp> Queries<'comp> { } pub fn lower_to_hir( - &self, - ) -> Result<&Query<(Steal, Steal)>> { + &'comp self, + ) -> Result<&Query<(&'comp hir::map::Forest, Steal)>> { self.lower_to_hir.compute(|| { let expansion_result = self.expansion()?; let peeked = expansion_result.peek(); let krate = &peeked.0; let resolver = peeked.1.steal(); let lint_store = &peeked.2; - let hir = Steal::new(resolver.borrow_mut().access(|resolver| { + let hir = resolver.borrow_mut().access(|resolver| { passes::lower_to_hir( self.session(), lint_store, @@ -225,7 +231,8 @@ impl<'comp> Queries<'comp> { &*self.dep_graph()?.peek(), &krate ) - })?); + })?; + let hir = self.forest.init_locking(|| hir); Ok((hir, Steal::new(BoxedResolver::to_resolver_outputs(resolver)))) }) } @@ -242,25 +249,27 @@ impl<'comp> Queries<'comp> { }) } - pub fn global_ctxt(&self) -> Result<&Query> { + pub fn global_ctxt(&'comp self) -> Result<&Query>> { self.global_ctxt.compute(|| { let crate_name = self.crate_name()?.peek().clone(); let outputs = self.prepare_outputs()?.peek().clone(); let lint_store = self.expansion()?.peek().2.clone(); - let hir = self.lower_to_hir()?; - let hir = hir.peek(); - let (hir_forest, resolver_outputs) = &*hir; + let hir = self.lower_to_hir()?.peek(); + let (ref hir_forest, ref resolver_outputs) = &*hir; Ok(passes::create_global_ctxt( self.compiler, lint_store, - hir_forest.steal(), + hir_forest, resolver_outputs.steal(), outputs, - &crate_name)) + &crate_name, + &self.gcx, + &self.arenas, + )) }) } - pub fn ongoing_codegen(&self) -> Result<&Query>> { + pub fn ongoing_codegen(&'comp self) -> Result<&Query>> { self.ongoing_codegen.compute(|| { let outputs = self.prepare_outputs()?; self.global_ctxt()?.peek_mut().enter(|tcx| { @@ -278,7 +287,7 @@ impl<'comp> Queries<'comp> { }) } - pub fn linker(&self) -> Result { + pub fn linker(&'comp self) -> Result { let dep_graph = self.dep_graph()?; let prepare_outputs = self.prepare_outputs()?; let ongoing_codegen = self.ongoing_codegen()?; @@ -317,10 +326,18 @@ impl Linker { impl Compiler { pub fn enter(&self, f: F) -> T - where F: FnOnce(&Queries<'_>) -> T + where F: for<'tcx> FnOnce(&'tcx Queries<'tcx>) -> T { let queries = Queries::new(&self); - f(&queries) + let ret = f(&queries); + + if self.session().opts.debugging_opts.query_stats { + if let Ok(gcx) = queries.global_ctxt() { + gcx.peek().print_stats(); + } + } + + ret } // This method is different to all the other methods in `Compiler` because diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 44d3dac1660..d09eb0b2fc2 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -88,7 +88,7 @@ pub fn run(options: Options) -> i32 { let tests = interface::run_compiler(config, |compiler| compiler.enter(|queries| { let lower_to_hir = queries.lower_to_hir()?; - let mut opts = scrape_test_config(lower_to_hir.peek().0.borrow().krate()); + let mut opts = scrape_test_config(lower_to_hir.peek().0.krate()); opts.display_warnings |= options.display_warnings; let enable_per_target_ignores = options.enable_per_target_ignores; let mut collector = Collector::new(