From 31d2012ef7468a3da17299c9964e8b01d68a67fc Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 8 May 2018 16:50:48 +0200 Subject: [PATCH 1/3] Adapt some method visibilities in librustc_metadata::cstore. --- src/librustc_metadata/cstore.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 64bbcf436cb9e..abecee2277c4b 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -104,15 +104,15 @@ impl CStore { /// You cannot use this function to allocate a CrateNum in a thread-safe manner. /// It is currently only used in CrateLoader which is single-threaded code. - pub fn next_crate_num(&self) -> CrateNum { + pub(super) fn next_crate_num(&self) -> CrateNum { CrateNum::new(self.metas.borrow().len() + 1) } - pub fn get_crate_data(&self, cnum: CrateNum) -> Lrc { + pub(super) fn get_crate_data(&self, cnum: CrateNum) -> Lrc { self.metas.borrow()[cnum].clone().unwrap() } - pub fn set_crate_data(&self, cnum: CrateNum, data: Lrc) { + pub(super) fn set_crate_data(&self, cnum: CrateNum, data: Lrc) { use rustc_data_structures::indexed_vec::Idx; let mut met = self.metas.borrow_mut(); while met.len() <= cnum.index() { @@ -121,7 +121,7 @@ impl CStore { met[cnum] = Some(data); } - pub fn iter_crate_data(&self, mut i: I) + pub(super) fn iter_crate_data(&self, mut i: I) where I: FnMut(CrateNum, &Lrc) { for (k, v) in self.metas.borrow().iter_enumerated() { @@ -131,14 +131,16 @@ impl CStore { } } - pub fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec { + pub(super) fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec { let mut ordering = Vec::new(); self.push_dependencies_in_postorder(&mut ordering, krate); ordering.reverse(); ordering } - pub fn push_dependencies_in_postorder(&self, ordering: &mut Vec, krate: CrateNum) { + pub(super) fn push_dependencies_in_postorder(&self, + ordering: &mut Vec, + krate: CrateNum) { if ordering.contains(&krate) { return; } @@ -153,7 +155,7 @@ impl CStore { ordering.push(krate); } - pub fn do_postorder_cnums_untracked(&self) -> Vec { + pub(super) fn do_postorder_cnums_untracked(&self) -> Vec { let mut ordering = Vec::new(); for (num, v) in self.metas.borrow().iter_enumerated() { if let &Some(_) = v { @@ -163,11 +165,11 @@ impl CStore { return ordering } - pub fn add_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId, cnum: CrateNum) { + pub(super) fn add_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId, cnum: CrateNum) { self.extern_mod_crate_map.borrow_mut().insert(emod_id, cnum); } - pub fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option { + pub(super) fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option { self.extern_mod_crate_map.borrow().get(&emod_id).cloned() } } From b8b957d4792be619a3251c917199fe7e7c01997c Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 8 May 2018 17:15:42 +0200 Subject: [PATCH 2/3] Make CrateNum allocation more thread-safe. --- src/librustc_metadata/creader.rs | 5 +---- src/librustc_metadata/cstore.rs | 20 +++++++++----------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index d0237071a6058..d9038105da08b 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -51,7 +51,6 @@ pub struct Library { pub struct CrateLoader<'a> { pub sess: &'a Session, cstore: &'a CStore, - next_crate_num: CrateNum, local_crate_name: Symbol, } @@ -102,7 +101,6 @@ impl<'a> CrateLoader<'a> { CrateLoader { sess, cstore, - next_crate_num: cstore.next_crate_num(), local_crate_name: Symbol::intern(local_crate_name), } } @@ -198,8 +196,7 @@ impl<'a> CrateLoader<'a> { self.verify_no_symbol_conflicts(span, &crate_root); // Claim this crate number and cache it - let cnum = self.next_crate_num; - self.next_crate_num = CrateNum::from_u32(cnum.as_u32() + 1); + let cnum = self.cstore.alloc_new_crate_num(); // Stash paths for top-most crate locally if necessary. let crate_paths = if root.is_none() { diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index abecee2277c4b..4872d560d27f0 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -96,16 +96,17 @@ pub struct CStore { impl CStore { pub fn new(metadata_loader: Box) -> CStore { CStore { - metas: RwLock::new(IndexVec::new()), + metas: RwLock::new(IndexVec::from_elem_n(None, 1)), extern_mod_crate_map: Lock::new(FxHashMap()), metadata_loader, } } - /// You cannot use this function to allocate a CrateNum in a thread-safe manner. - /// It is currently only used in CrateLoader which is single-threaded code. - pub(super) fn next_crate_num(&self) -> CrateNum { - CrateNum::new(self.metas.borrow().len() + 1) + pub(super) fn alloc_new_crate_num(&self) -> CrateNum { + let mut metas = self.metas.borrow_mut(); + let cnum = CrateNum::new(metas.len()); + metas.push(None); + cnum } pub(super) fn get_crate_data(&self, cnum: CrateNum) -> Lrc { @@ -113,12 +114,9 @@ impl CStore { } pub(super) fn set_crate_data(&self, cnum: CrateNum, data: Lrc) { - use rustc_data_structures::indexed_vec::Idx; - let mut met = self.metas.borrow_mut(); - while met.len() <= cnum.index() { - met.push(None); - } - met[cnum] = Some(data); + let mut metas = self.metas.borrow_mut(); + assert!(metas[cnum].is_none(), "Overwriting crate metadata entry"); + metas[cnum] = Some(data); } pub(super) fn iter_crate_data(&self, mut i: I) From 4537025c7193b4f1412807ab15f723f51ff0b01e Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 9 May 2018 21:32:18 +0200 Subject: [PATCH 3/3] Add comment about first element in CStore::metas. --- src/librustc_metadata/cstore.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 4872d560d27f0..0c54ec7c27ab2 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -96,6 +96,10 @@ pub struct CStore { impl CStore { pub fn new(metadata_loader: Box) -> CStore { CStore { + // We add an empty entry for LOCAL_CRATE (which maps to zero) in + // order to make array indices in `metas` match with the + // corresponding `CrateNum`. This first entry will always remain + // `None`. metas: RwLock::new(IndexVec::from_elem_n(None, 1)), extern_mod_crate_map: Lock::new(FxHashMap()), metadata_loader,