Skip to content

Commit 6a47d09

Browse files
authored
Rollup merge of rust-lang#119589 - petrochenkov:cdatalock, r=Mark-Simulacrum
cstore: Remove unnecessary locking from `CrateMetadata` Locks and atomics in `CrateMetadata` fields were necessary before rust-lang#107765 when `CStore` was cloneable, but now they are not necessary and can be removed after restructuring the code a bit to please borrow checker. All remaining locked fields in `CrateMetadata` are lazily populated caches.
2 parents ef4860c + 4bc3552 commit 6a47d09

File tree

3 files changed

+58
-58
lines changed

3 files changed

+58
-58
lines changed

compiler/rustc_metadata/src/creader.rs

+21-20
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,10 @@ impl CStore {
196196
CrateMetadataRef { cdata, cstore: self }
197197
}
198198

199+
pub(crate) fn get_crate_data_mut(&mut self, cnum: CrateNum) -> &mut CrateMetadata {
200+
self.metas[cnum].as_mut().unwrap_or_else(|| panic!("Failed to get crate data for {cnum:?}"))
201+
}
202+
199203
fn set_crate_data(&mut self, cnum: CrateNum, data: CrateMetadata) {
200204
assert!(self.metas[cnum].is_none(), "Overwriting crate metadata entry");
201205
self.metas[cnum] = Some(Box::new(data));
@@ -207,6 +211,12 @@ impl CStore {
207211
.filter_map(|(cnum, data)| data.as_deref().map(|data| (cnum, data)))
208212
}
209213

214+
fn iter_crate_data_mut(&mut self) -> impl Iterator<Item = (CrateNum, &mut CrateMetadata)> {
215+
self.metas
216+
.iter_enumerated_mut()
217+
.filter_map(|(cnum, data)| data.as_deref_mut().map(|data| (cnum, data)))
218+
}
219+
210220
fn push_dependencies_in_postorder(&self, deps: &mut Vec<CrateNum>, cnum: CrateNum) {
211221
if !deps.contains(&cnum) {
212222
let data = self.get_crate_data(cnum);
@@ -586,11 +596,11 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
586596

587597
match result {
588598
(LoadResult::Previous(cnum), None) => {
589-
let data = self.cstore.get_crate_data(cnum);
599+
let data = self.cstore.get_crate_data_mut(cnum);
590600
if data.is_proc_macro_crate() {
591601
dep_kind = CrateDepKind::MacrosOnly;
592602
}
593-
data.update_dep_kind(|data_dep_kind| cmp::max(data_dep_kind, dep_kind));
603+
data.set_dep_kind(cmp::max(data.dep_kind(), dep_kind));
594604
if let Some(private_dep) = private_dep {
595605
data.update_and_private_dep(private_dep);
596606
}
@@ -637,17 +647,6 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
637647
}))
638648
}
639649

640-
fn update_extern_crate(&self, cnum: CrateNum, extern_crate: ExternCrate) {
641-
let cmeta = self.cstore.get_crate_data(cnum);
642-
if cmeta.update_extern_crate(extern_crate) {
643-
// Propagate the extern crate info to dependencies if it was updated.
644-
let extern_crate = ExternCrate { dependency_of: cnum, ..extern_crate };
645-
for dep_cnum in cmeta.dependencies() {
646-
self.update_extern_crate(dep_cnum, extern_crate);
647-
}
648-
}
649-
}
650-
651650
// Go through the crate metadata and load any crates that it references
652651
fn resolve_crate_deps(
653652
&mut self,
@@ -726,17 +725,19 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
726725
let mut runtime_found = false;
727726
let mut needs_panic_runtime = attr::contains_name(&krate.attrs, sym::needs_panic_runtime);
728727

728+
let mut panic_runtimes = Vec::new();
729729
for (cnum, data) in self.cstore.iter_crate_data() {
730730
needs_panic_runtime = needs_panic_runtime || data.needs_panic_runtime();
731731
if data.is_panic_runtime() {
732732
// Inject a dependency from all #![needs_panic_runtime] to this
733733
// #![panic_runtime] crate.
734-
self.inject_dependency_if(cnum, "a panic runtime", &|data| {
735-
data.needs_panic_runtime()
736-
});
734+
panic_runtimes.push(cnum);
737735
runtime_found = runtime_found || data.dep_kind() == CrateDepKind::Explicit;
738736
}
739737
}
738+
for cnum in panic_runtimes {
739+
self.inject_dependency_if(cnum, "a panic runtime", &|data| data.needs_panic_runtime());
740+
}
740741

741742
// If an explicitly linked and matching panic runtime was found, or if
742743
// we just don't need one at all, then we're done here and there's
@@ -917,7 +918,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
917918
}
918919

919920
fn inject_dependency_if(
920-
&self,
921+
&mut self,
921922
krate: CrateNum,
922923
what: &str,
923924
needs_dep: &dyn Fn(&CrateMetadata) -> bool,
@@ -947,7 +948,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
947948
// crate provided for this compile, but in order for this compilation to
948949
// be successfully linked we need to inject a dependency (to order the
949950
// crates on the command line correctly).
950-
for (cnum, data) in self.cstore.iter_crate_data() {
951+
for (cnum, data) in self.cstore.iter_crate_data_mut() {
951952
if needs_dep(data) {
952953
info!("injecting a dep from {} to {}", cnum, krate);
953954
data.add_dependency(krate);
@@ -1031,7 +1032,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
10311032
let cnum = self.resolve_crate(name, item.span, dep_kind)?;
10321033

10331034
let path_len = definitions.def_path(def_id).data.len();
1034-
self.update_extern_crate(
1035+
self.cstore.update_extern_crate(
10351036
cnum,
10361037
ExternCrate {
10371038
src: ExternCrateSource::Extern(def_id.to_def_id()),
@@ -1049,7 +1050,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
10491050
pub fn process_path_extern(&mut self, name: Symbol, span: Span) -> Option<CrateNum> {
10501051
let cnum = self.resolve_crate(name, span, CrateDepKind::Explicit)?;
10511052

1052-
self.update_extern_crate(
1053+
self.cstore.update_extern_crate(
10531054
cnum,
10541055
ExternCrate {
10551056
src: ExternCrateSource::Path,

compiler/rustc_metadata/src/rmeta/decoder.rs

+19-20
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_ast as ast;
88
use rustc_data_structures::captures::Captures;
99
use rustc_data_structures::fingerprint::Fingerprint;
1010
use rustc_data_structures::owned_slice::OwnedSlice;
11-
use rustc_data_structures::sync::{AppendOnlyVec, AtomicBool, Lock, Lrc, OnceLock};
11+
use rustc_data_structures::sync::{Lock, Lrc, OnceLock};
1212
use rustc_data_structures::unhash::UnhashMap;
1313
use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
1414
use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, DeriveProcMacro};
@@ -31,7 +31,6 @@ use rustc_span::{BytePos, Pos, SpanData, SyntaxContext, DUMMY_SP};
3131
use proc_macro::bridge::client::ProcMacro;
3232
use std::iter::TrustedLen;
3333
use std::path::Path;
34-
use std::sync::atomic::Ordering;
3534
use std::{io, iter, mem};
3635

3736
pub(super) use cstore_impl::provide;
@@ -96,15 +95,15 @@ pub(crate) struct CrateMetadata {
9695
/// IDs as they are seen from the current compilation session.
9796
cnum_map: CrateNumMap,
9897
/// Same ID set as `cnum_map` plus maybe some injected crates like panic runtime.
99-
dependencies: AppendOnlyVec<CrateNum>,
98+
dependencies: Vec<CrateNum>,
10099
/// How to link (or not link) this crate to the currently compiled crate.
101-
dep_kind: Lock<CrateDepKind>,
100+
dep_kind: CrateDepKind,
102101
/// Filesystem location of this crate.
103102
source: Lrc<CrateSource>,
104103
/// Whether or not this crate should be consider a private dependency.
105104
/// Used by the 'exported_private_dependencies' lint, and for determining
106105
/// whether to emit suggestions that reference this crate.
107-
private_dep: AtomicBool,
106+
private_dep: bool,
108107
/// The hash for the host proc macro. Used to support `-Z dual-proc-macro`.
109108
host_hash: Option<Svh>,
110109

@@ -118,7 +117,7 @@ pub(crate) struct CrateMetadata {
118117
// --- Data used only for improving diagnostics ---
119118
/// Information about the `extern crate` item or path that caused this crate to be loaded.
120119
/// If this is `None`, then the crate was injected (e.g., by the allocator).
121-
extern_crate: Lock<Option<ExternCrate>>,
120+
extern_crate: Option<ExternCrate>,
122121
}
123122

124123
/// Holds information about a rustc_span::SourceFile imported from another crate.
@@ -1818,11 +1817,11 @@ impl CrateMetadata {
18181817
cnum,
18191818
cnum_map,
18201819
dependencies,
1821-
dep_kind: Lock::new(dep_kind),
1820+
dep_kind,
18221821
source: Lrc::new(source),
1823-
private_dep: AtomicBool::new(private_dep),
1822+
private_dep,
18241823
host_hash,
1825-
extern_crate: Lock::new(None),
1824+
extern_crate: None,
18261825
hygiene_context: Default::default(),
18271826
def_key_cache: Default::default(),
18281827
};
@@ -1839,18 +1838,18 @@ impl CrateMetadata {
18391838
}
18401839

18411840
pub(crate) fn dependencies(&self) -> impl Iterator<Item = CrateNum> + '_ {
1842-
self.dependencies.iter()
1841+
self.dependencies.iter().copied()
18431842
}
18441843

1845-
pub(crate) fn add_dependency(&self, cnum: CrateNum) {
1844+
pub(crate) fn add_dependency(&mut self, cnum: CrateNum) {
18461845
self.dependencies.push(cnum);
18471846
}
18481847

1849-
pub(crate) fn update_extern_crate(&self, new_extern_crate: ExternCrate) -> bool {
1850-
let mut extern_crate = self.extern_crate.borrow_mut();
1851-
let update = Some(new_extern_crate.rank()) > extern_crate.as_ref().map(ExternCrate::rank);
1848+
pub(crate) fn update_extern_crate(&mut self, new_extern_crate: ExternCrate) -> bool {
1849+
let update =
1850+
Some(new_extern_crate.rank()) > self.extern_crate.as_ref().map(ExternCrate::rank);
18521851
if update {
1853-
*extern_crate = Some(new_extern_crate);
1852+
self.extern_crate = Some(new_extern_crate);
18541853
}
18551854
update
18561855
}
@@ -1860,15 +1859,15 @@ impl CrateMetadata {
18601859
}
18611860

18621861
pub(crate) fn dep_kind(&self) -> CrateDepKind {
1863-
*self.dep_kind.lock()
1862+
self.dep_kind
18641863
}
18651864

1866-
pub(crate) fn update_dep_kind(&self, f: impl FnOnce(CrateDepKind) -> CrateDepKind) {
1867-
self.dep_kind.with_lock(|dep_kind| *dep_kind = f(*dep_kind))
1865+
pub(crate) fn set_dep_kind(&mut self, dep_kind: CrateDepKind) {
1866+
self.dep_kind = dep_kind;
18681867
}
18691868

1870-
pub(crate) fn update_and_private_dep(&self, private_dep: bool) {
1871-
self.private_dep.fetch_and(private_dep, Ordering::SeqCst);
1869+
pub(crate) fn update_and_private_dep(&mut self, private_dep: bool) {
1870+
self.private_dep &= private_dep;
18721871
}
18731872

18741873
pub(crate) fn required_panic_strategy(&self) -> Option<PanicStrategy> {

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+18-18
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc_middle::query::LocalCrate;
1919
use rustc_middle::ty::fast_reject::SimplifiedType;
2020
use rustc_middle::ty::{self, TyCtxt};
2121
use rustc_middle::util::Providers;
22-
use rustc_session::cstore::CrateStore;
22+
use rustc_session::cstore::{CrateStore, ExternCrate};
2323
use rustc_session::{Session, StableCrateId};
2424
use rustc_span::hygiene::{ExpnHash, ExpnId};
2525
use rustc_span::symbol::{kw, Symbol};
@@ -290,13 +290,7 @@ provide! { tcx, def_id, other, cdata,
290290
cross_crate_inlinable => { cdata.cross_crate_inlinable(def_id.index) }
291291

292292
dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) }
293-
is_private_dep => {
294-
// Parallel compiler needs to synchronize type checking and linting (which use this flag)
295-
// so that they happen strictly crate loading. Otherwise, the full list of available
296-
// impls aren't loaded yet.
297-
use std::sync::atomic::Ordering;
298-
cdata.private_dep.load(Ordering::Acquire)
299-
}
293+
is_private_dep => { cdata.private_dep }
300294
is_panic_runtime => { cdata.root.panic_runtime }
301295
is_compiler_builtins => { cdata.root.compiler_builtins }
302296
has_global_allocator => { cdata.root.has_global_allocator }
@@ -305,10 +299,7 @@ provide! { tcx, def_id, other, cdata,
305299
is_profiler_runtime => { cdata.root.profiler_runtime }
306300
required_panic_strategy => { cdata.root.required_panic_strategy }
307301
panic_in_drop_strategy => { cdata.root.panic_in_drop_strategy }
308-
extern_crate => {
309-
let r = *cdata.extern_crate.lock();
310-
r.map(|c| &*tcx.arena.alloc(c))
311-
}
302+
extern_crate => { cdata.extern_crate.map(|c| &*tcx.arena.alloc(c)) }
312303
is_no_builtins => { cdata.root.no_builtins }
313304
symbol_mangling_version => { cdata.root.symbol_mangling_version }
314305
reachable_non_generics => {
@@ -339,10 +330,7 @@ provide! { tcx, def_id, other, cdata,
339330
implementations_of_trait => { cdata.get_implementations_of_trait(tcx, other) }
340331
crate_incoherent_impls => { cdata.get_incoherent_impls(tcx, other) }
341332

342-
dep_kind => {
343-
let r = *cdata.dep_kind.lock();
344-
r
345-
}
333+
dep_kind => { cdata.dep_kind }
346334
module_children => {
347335
tcx.arena.alloc_from_iter(cdata.get_module_children(def_id.index, tcx.sess))
348336
}
@@ -357,8 +345,7 @@ provide! { tcx, def_id, other, cdata,
357345
missing_lang_items => { cdata.get_missing_lang_items(tcx) }
358346

359347
missing_extern_crate_item => {
360-
let r = matches!(*cdata.extern_crate.borrow(), Some(extern_crate) if !extern_crate.is_direct());
361-
r
348+
matches!(cdata.extern_crate, Some(extern_crate) if !extern_crate.is_direct())
362349
}
363350

364351
used_crate_source => { Lrc::clone(&cdata.source) }
@@ -581,6 +568,19 @@ impl CStore {
581568
) -> Span {
582569
self.get_crate_data(cnum).get_proc_macro_quoted_span(id, sess)
583570
}
571+
572+
pub(crate) fn update_extern_crate(&mut self, cnum: CrateNum, extern_crate: ExternCrate) {
573+
let cmeta = self.get_crate_data_mut(cnum);
574+
if cmeta.update_extern_crate(extern_crate) {
575+
// Propagate the extern crate info to dependencies if it was updated.
576+
let extern_crate = ExternCrate { dependency_of: cnum, ..extern_crate };
577+
let dependencies = std::mem::take(&mut cmeta.dependencies);
578+
for &dep_cnum in &dependencies {
579+
self.update_extern_crate(dep_cnum, extern_crate);
580+
}
581+
self.get_crate_data_mut(cnum).dependencies = dependencies;
582+
}
583+
}
584584
}
585585

586586
impl CrateStore for CStore {

0 commit comments

Comments
 (0)