Skip to content

Commit 5561737

Browse files
committed
Auto merge of #14211 - Eh2406:default-without-lock, r=epage
dont make new constant InternedString in hot path ### What does this PR try to resolve? `InternedString::new` always takes a `Mutex` lock. This is not a big deal because `new` is usually only called as external io is done (i.e not in a hot loop) and cargo is single threaded so the lock is not contested. However, dealing with the "default" feature happens deep within the resolver (i.e in a hot loop). So we may as well remove this overhead. I can get runtime benchmarks if that is desired. For context: My pubgrub work would very much like to run cargoes resolver simultaneously in multiple threads. This `Mutex` is a major obstacle for that effort. ### How should we test and review this PR? Internal re-factor and test still pass. Also confirmed the semantics of `static` in https://rust-lang.zulipchat.com/#narrow/stream/122651-general/topic/Const.20evaluation.20and.20equality ### Additional information There are other constant InternedString's in `src/cargo/core/profiles.rs`. I don't think they are in a hot enough path to justify more `static`s. But I will change if requested.
2 parents cff67a9 + 106c86a commit 5561737

File tree

4 files changed

+25
-15
lines changed

4 files changed

+25
-15
lines changed

src/cargo/core/resolver/dep_cache.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use crate::core::{
2121
};
2222
use crate::sources::source::QueryKind;
2323
use crate::util::errors::CargoResult;
24-
use crate::util::interning::InternedString;
24+
use crate::util::interning::{InternedString, INTERNED_DEFAULT};
2525

2626
use anyhow::Context as _;
2727
use std::collections::{BTreeSet, HashMap, HashSet};
@@ -348,7 +348,7 @@ fn build_requirements<'a, 'b: 'a>(
348348

349349
let handle_default = |uses_default_features, reqs: &mut Requirements<'_>| {
350350
if uses_default_features && s.features().contains_key("default") {
351-
if let Err(e) = reqs.require_feature(InternedString::new("default")) {
351+
if let Err(e) = reqs.require_feature(INTERNED_DEFAULT) {
352352
return Err(e.into_activate_error(parent, s));
353353
}
354354
}

src/cargo/core/resolver/features.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use crate::core::dependency::{ArtifactTarget, DepKind, Dependency};
4343
use crate::core::resolver::types::FeaturesSet;
4444
use crate::core::resolver::{Resolve, ResolveBehavior};
4545
use crate::core::{FeatureValue, PackageId, PackageIdSpec, PackageSet, Workspace};
46-
use crate::util::interning::InternedString;
46+
use crate::util::interning::{InternedString, INTERNED_DEFAULT};
4747
use crate::util::CargoResult;
4848
use anyhow::{bail, Context};
4949
use itertools::Itertools;
@@ -745,9 +745,8 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
745745
.iter()
746746
.map(|f| FeatureValue::new(*f))
747747
.collect();
748-
let default = InternedString::new("default");
749-
if dep.uses_default_features() && feature_map.contains_key(&default) {
750-
result.push(FeatureValue::Feature(default));
748+
if dep.uses_default_features() && feature_map.contains_key(&INTERNED_DEFAULT) {
749+
result.push(FeatureValue::Feature(INTERNED_DEFAULT));
751750
}
752751
result
753752
}
@@ -762,9 +761,8 @@ impl<'a, 'gctx> FeatureResolver<'a, 'gctx> {
762761
let feature_map = summary.features();
763762

764763
let mut result: Vec<FeatureValue> = cli_features.features.iter().cloned().collect();
765-
let default = InternedString::new("default");
766-
if cli_features.uses_default_features && feature_map.contains_key(&default) {
767-
result.push(FeatureValue::Feature(default));
764+
if cli_features.uses_default_features && feature_map.contains_key(&INTERNED_DEFAULT) {
765+
result.push(FeatureValue::Feature(INTERNED_DEFAULT));
768766
}
769767

770768
if cli_features.all_features {

src/cargo/ops/tree/graph.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::core::dependency::DepKind;
66
use crate::core::resolver::features::{CliFeatures, FeaturesFor, ResolvedFeatures};
77
use crate::core::resolver::Resolve;
88
use crate::core::{FeatureMap, FeatureValue, Package, PackageId, PackageIdSpec, Workspace};
9-
use crate::util::interning::InternedString;
9+
use crate::util::interning::{InternedString, INTERNED_DEFAULT};
1010
use crate::util::CargoResult;
1111
use std::collections::{HashMap, HashSet};
1212

@@ -415,7 +415,7 @@ fn add_pkg(
415415
if dep.uses_default_features() {
416416
add_feature(
417417
graph,
418-
InternedString::new("default"),
418+
INTERNED_DEFAULT,
419419
Some(from_index),
420420
dep_index,
421421
EdgeKind::Dep(dep.kind()),
@@ -505,7 +505,7 @@ fn add_cli_features(
505505
}
506506

507507
if cli_features.uses_default_features {
508-
to_add.insert(FeatureValue::Feature(InternedString::new("default")));
508+
to_add.insert(FeatureValue::Feature(INTERNED_DEFAULT));
509509
}
510510
to_add.extend(cli_features.features.iter().cloned());
511511

src/cargo/util/interning.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,19 @@ use std::str;
1313
use std::sync::Mutex;
1414
use std::sync::OnceLock;
1515

16-
static STRING_CACHE: OnceLock<Mutex<HashSet<&'static str>>> = OnceLock::new();
16+
pub static INTERNED_DEFAULT: InternedString = InternedString { inner: "default" };
17+
18+
fn interned_storage() -> std::sync::MutexGuard<'static, HashSet<&'static str>> {
19+
static STRING_CACHE: OnceLock<Mutex<HashSet<&'static str>>> = OnceLock::new();
20+
STRING_CACHE
21+
.get_or_init(|| {
22+
let mut out: HashSet<&'static str> = Default::default();
23+
out.insert(INTERNED_DEFAULT.as_str());
24+
Mutex::new(out)
25+
})
26+
.lock()
27+
.unwrap()
28+
}
1729

1830
#[derive(Clone, Copy)]
1931
pub struct InternedString {
@@ -60,8 +72,8 @@ impl Eq for InternedString {}
6072

6173
impl InternedString {
6274
pub fn new(str: &str) -> InternedString {
63-
let mut cache = STRING_CACHE.get_or_init(Default::default).lock().unwrap();
64-
let s = cache.get(str).cloned().unwrap_or_else(|| {
75+
let mut cache = interned_storage();
76+
let s = cache.get(str).copied().unwrap_or_else(|| {
6577
let s = str.to_string().leak();
6678
cache.insert(s);
6779
s

0 commit comments

Comments
 (0)