Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make CrateNum allocation more thread-safe. #50538

Merged
merged 3 commits into from
May 11, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions src/librustc_metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}

Expand Down Expand Up @@ -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),
}
}
Expand Down Expand Up @@ -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() {
Expand Down
38 changes: 19 additions & 19 deletions src/librustc_metadata/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,32 +96,30 @@ pub struct CStore {
impl CStore {
pub fn new(metadata_loader: Box<MetadataLoader + Sync>) -> CStore {
CStore {
metas: RwLock::new(IndexVec::new()),
metas: RwLock::new(IndexVec::from_elem_n(None, 1)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first entry is for LOCAL_CRATE here right? Do we call set_crate_data for that?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's for the local crate. The entry will always be None. It's just there to make array indices match CrateNums.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add that as a comment?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

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 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 fn get_crate_data(&self, cnum: CrateNum) -> Lrc<CrateMetadata> {
pub(super) fn get_crate_data(&self, cnum: CrateNum) -> Lrc<CrateMetadata> {
self.metas.borrow()[cnum].clone().unwrap()
}

pub fn set_crate_data(&self, cnum: CrateNum, data: Lrc<CrateMetadata>) {
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);
pub(super) fn set_crate_data(&self, cnum: CrateNum, data: Lrc<CrateMetadata>) {
let mut metas = self.metas.borrow_mut();
assert!(metas[cnum].is_none(), "Overwriting crate metadata entry");
metas[cnum] = Some(data);
}

pub fn iter_crate_data<I>(&self, mut i: I)
pub(super) fn iter_crate_data<I>(&self, mut i: I)
where I: FnMut(CrateNum, &Lrc<CrateMetadata>)
{
for (k, v) in self.metas.borrow().iter_enumerated() {
Expand All @@ -131,14 +129,16 @@ impl CStore {
}
}

pub fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec<CrateNum> {
pub(super) fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec<CrateNum> {
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<CrateNum>, krate: CrateNum) {
pub(super) fn push_dependencies_in_postorder(&self,
ordering: &mut Vec<CrateNum>,
krate: CrateNum) {
if ordering.contains(&krate) {
return;
}
Expand All @@ -153,7 +153,7 @@ impl CStore {
ordering.push(krate);
}

pub fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
pub(super) fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
let mut ordering = Vec::new();
for (num, v) in self.metas.borrow().iter_enumerated() {
if let &Some(_) = v {
Expand All @@ -163,11 +163,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<CrateNum> {
pub(super) fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> {
self.extern_mod_crate_map.borrow().get(&emod_id).cloned()
}
}
Expand Down