Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit ee89a51

Browse files
committed
Auto merge of rust-lang#137135 - klensy:triomphe-0, r=<try>
use triomphe::Arc for InternedObligationCauseCode instead of Arc This nicely cuts memory reads (reported by dhat), while marginally reducing maxrss for some stresstest. Lets see perf?
2 parents 4229b80 + b470b56 commit ee89a51

File tree

14 files changed

+96
-4
lines changed

14 files changed

+96
-4
lines changed

Cargo.lock

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3666,6 +3666,7 @@ dependencies = [
36663666
"tempfile",
36673667
"thin-vec",
36683668
"tracing",
3669+
"triomphe",
36693670
"windows 0.59.0",
36703671
]
36713672

@@ -4183,6 +4184,7 @@ dependencies = [
41834184
"smallvec",
41844185
"thin-vec",
41854186
"tracing",
4187+
"triomphe",
41864188
]
41874189

41884190
[[package]]
@@ -4492,6 +4494,7 @@ dependencies = [
44924494
"smallvec",
44934495
"tempfile",
44944496
"thin-vec",
4497+
"triomphe",
44954498
]
44964499

44974500
[[package]]
@@ -4694,6 +4697,7 @@ dependencies = [
46944697
"smallvec",
46954698
"thin-vec",
46964699
"tracing",
4700+
"triomphe",
46974701
]
46984702

46994703
[[package]]
@@ -5630,6 +5634,15 @@ dependencies = [
56305634
"tracing-subscriber",
56315635
]
56325636

5637+
[[package]]
5638+
name = "triomphe"
5639+
version = "0.1.14"
5640+
source = "git+https://github.com/Manishearth/triomphe.git?rev=6ff0527036632be33a6ed45e5e8a0fb6243dee47#6ff0527036632be33a6ed45e5e8a0fb6243dee47"
5641+
dependencies = [
5642+
"serde",
5643+
"stable_deref_trait",
5644+
]
5645+
56335646
[[package]]
56345647
name = "twox-hash"
56355648
version = "1.6.3"

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,6 @@ codegen-units = 1
9393
# FIXME: LTO cannot be enabled for binaries in a workspace
9494
# <https://github.com/rust-lang/cargo/issues/9330>
9595
# lto = true
96+
97+
[patch.crates-io]
98+
triomphe = { git = 'https://github.com/Manishearth/triomphe.git', rev = '6ff0527036632be33a6ed45e5e8a0fb6243dee47' }

compiler/rustc_data_structures/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ stacker = "0.1.17"
2626
tempfile = "3.2"
2727
thin-vec = "0.2.12"
2828
tracing = "0.1"
29+
triomphe = { version = "0.1.14", features = ["unstable_dropck_eyepatch"] }
2930
# tidy-alphabetical-end
3031

3132
[dependencies.parking_lot]

compiler/rustc_data_structures/src/marker.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ impl_dyn_send!(
6565
[std::sync::Mutex<T> where T: ?Sized+ DynSend]
6666
[std::sync::mpsc::Sender<T> where T: DynSend]
6767
[std::sync::Arc<T> where T: ?Sized + DynSync + DynSend]
68+
[triomphe::Arc<T> where T: ?Sized + DynSync + DynSend]
6869
[std::sync::LazyLock<T, F> where T: DynSend, F: DynSend]
6970
[std::collections::HashSet<K, S> where K: DynSend, S: DynSend]
7071
[std::collections::HashMap<K, V, S> where K: DynSend, V: DynSend, S: DynSend]
@@ -139,6 +140,7 @@ impl_dyn_sync!(
139140
[std::sync::OnceLock<T> where T: DynSend + DynSync]
140141
[std::sync::Mutex<T> where T: ?Sized + DynSend]
141142
[std::sync::Arc<T> where T: ?Sized + DynSync + DynSend]
143+
[triomphe::Arc<T> where T: ?Sized + DynSync + DynSend]
142144
[std::sync::LazyLock<T, F> where T: DynSend + DynSync, F: DynSend]
143145
[std::collections::HashSet<K, S> where K: DynSync, S: DynSync]
144146
[std::collections::HashMap<K, V, S> where K: DynSync, V: DynSync, S: DynSync]

compiler/rustc_data_structures/src/stable_hasher.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,13 @@ impl<T: ?Sized + HashStable<CTX>, CTX> HashStable<CTX> for ::std::sync::Arc<T> {
395395
}
396396
}
397397

398+
impl<T: ?Sized + HashStable<CTX>, CTX> HashStable<CTX> for ::triomphe::Arc<T> {
399+
#[inline]
400+
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
401+
(**self).hash_stable(ctx, hasher);
402+
}
403+
}
404+
398405
impl<CTX> HashStable<CTX> for str {
399406
#[inline]
400407
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {

compiler/rustc_middle/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ rustc_type_ir = { path = "../rustc_type_ir" }
3636
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
3737
thin-vec = "0.2.12"
3838
tracing = "0.1"
39+
triomphe = "0.1.14"
3940
# tidy-alphabetical-end
4041

4142
[features]

compiler/rustc_middle/src/traits/mod.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@ mod structural_impls;
1010

1111
use std::borrow::Cow;
1212
use std::hash::{Hash, Hasher};
13-
use std::sync::Arc;
1413

1514
use rustc_errors::{Applicability, Diag, EmissionGuarantee};
16-
use rustc_hir as hir;
1715
use rustc_hir::HirId;
1816
use rustc_hir::def_id::DefId;
1917
use rustc_macros::{
@@ -23,6 +21,7 @@ use rustc_span::def_id::{CRATE_DEF_ID, LocalDefId};
2321
use rustc_span::{DUMMY_SP, Span, Symbol};
2422
use smallvec::{SmallVec, smallvec};
2523
use thin_vec::ThinVec;
24+
use {rustc_hir as hir, triomphe};
2625

2726
pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache};
2827
use crate::mir::ConstraintCategory;
@@ -157,7 +156,7 @@ pub struct UnifyReceiverContext<'tcx> {
157156
pub struct InternedObligationCauseCode<'tcx> {
158157
/// `None` for `ObligationCauseCode::Misc` (a common case, occurs ~60% of
159158
/// the time). `Some` otherwise.
160-
code: Option<Arc<ObligationCauseCode<'tcx>>>,
159+
code: Option<triomphe::Arc<ObligationCauseCode<'tcx>>>,
161160
}
162161

163162
impl<'tcx> std::fmt::Debug for InternedObligationCauseCode<'tcx> {
@@ -171,7 +170,11 @@ impl<'tcx> ObligationCauseCode<'tcx> {
171170
#[inline(always)]
172171
fn into(self) -> InternedObligationCauseCode<'tcx> {
173172
InternedObligationCauseCode {
174-
code: if let ObligationCauseCode::Misc = self { None } else { Some(Arc::new(self)) },
173+
code: if let ObligationCauseCode::Misc = self {
174+
None
175+
} else {
176+
Some(triomphe::Arc::new(self))
177+
},
175178
}
176179
}
177180
}

compiler/rustc_serialize/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ edition = "2021"
88
indexmap = "2.0.0"
99
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
1010
thin-vec = "0.2.12"
11+
triomphe = "0.1.14"
1112
# tidy-alphabetical-end
1213

1314
[dev-dependencies]

compiler/rustc_serialize/src/serialize.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use std::sync::Arc;
1212

1313
use smallvec::{Array, SmallVec};
1414
use thin_vec::ThinVec;
15+
use triomphe;
1516

1617
/// A byte that [cannot occur in UTF8 sequences][utf8]. Used to mark the end of a string.
1718
/// This way we can skip validation and still be relatively sure that deserialization
@@ -486,6 +487,18 @@ impl<D: Decoder, T: Decodable<D>> Decodable<D> for Arc<T> {
486487
}
487488
}
488489

490+
impl<S: Encoder, T: Encodable<S>> Encodable<S> for triomphe::Arc<T> {
491+
fn encode(&self, s: &mut S) {
492+
(**self).encode(s);
493+
}
494+
}
495+
496+
impl<D: Decoder, T: Decodable<D>> Decodable<D> for triomphe::Arc<T> {
497+
fn decode(d: &mut D) -> triomphe::Arc<T> {
498+
triomphe::Arc::new(Decodable::decode(d))
499+
}
500+
}
501+
489502
impl<S: Encoder, T: ?Sized + Encodable<S>> Encodable<S> for Box<T> {
490503
fn encode(&self, s: &mut S) {
491504
(**self).encode(s)

compiler/rustc_type_ir/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ rustc_type_ir_macros = { path = "../rustc_type_ir_macros" }
1919
smallvec = { version = "1.8.1", default-features = false }
2020
thin-vec = "0.2.12"
2121
tracing = "0.1"
22+
triomphe = "0.1.14"
2223
# tidy-alphabetical-end
2324

2425
[features]

compiler/rustc_type_ir/src/fold.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ use std::sync::Arc;
5151
use rustc_index::{Idx, IndexVec};
5252
use thin_vec::ThinVec;
5353
use tracing::{debug, instrument};
54+
use triomphe;
5455

5556
use crate::inherent::*;
5657
use crate::visit::{TypeVisitable, TypeVisitableExt as _};
@@ -310,6 +311,43 @@ impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Arc<T> {
310311
}
311312
}
312313

314+
impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for triomphe::Arc<T> {
315+
fn try_fold_with<F: FallibleTypeFolder<I>>(mut self, folder: &mut F) -> Result<Self, F::Error> {
316+
// We merely want to replace the contained `T`, if at all possible,
317+
// so that we don't needlessly allocate a new `Arc` or indeed clone
318+
// the contained type.
319+
unsafe {
320+
// First step is to ensure that we have a unique reference to
321+
// the contained type, which `Arc::make_mut` will accomplish (by
322+
// allocating a new `Arc` and cloning the `T` only if required).
323+
// This is done *before* casting to `Arc<ManuallyDrop<T>>` so that
324+
// panicking during `make_mut` does not leak the `T`.
325+
triomphe::Arc::make_mut(&mut self);
326+
327+
// Casting to `Arc<ManuallyDrop<T>>` is safe because `ManuallyDrop`
328+
// is `repr(transparent)`.
329+
let ptr = triomphe::Arc::into_raw(self).cast::<mem::ManuallyDrop<T>>();
330+
let mut unique = triomphe::Arc::from_raw(ptr);
331+
332+
// Call to `Arc::make_mut` above guarantees that `unique` is the
333+
// sole reference to the contained value, so we can avoid doing
334+
// a checked `get_mut` here.
335+
let slot = triomphe::Arc::get_mut(&mut unique).unwrap_unchecked();
336+
337+
// Semantically move the contained type out from `unique`, fold
338+
// it, then move the folded value back into `unique`. Should
339+
// folding fail, `ManuallyDrop` ensures that the "moved-out"
340+
// value is not re-dropped.
341+
let owned = mem::ManuallyDrop::take(slot);
342+
let folded = owned.try_fold_with(folder)?;
343+
*slot = mem::ManuallyDrop::new(folded);
344+
345+
// Cast back to `Arc<T>`.
346+
Ok(triomphe::Arc::from_raw(triomphe::Arc::into_raw(unique).cast()))
347+
}
348+
}
349+
}
350+
313351
impl<I: Interner, T: TypeFoldable<I>> TypeFoldable<I> for Box<T> {
314352
fn try_fold_with<F: FallibleTypeFolder<I>>(mut self, folder: &mut F) -> Result<Self, F::Error> {
315353
*self = (*self).try_fold_with(folder)?;

compiler/rustc_type_ir/src/visit.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,12 @@ impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Arc<T> {
173173
}
174174
}
175175

176+
impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for triomphe::Arc<T> {
177+
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
178+
(**self).visit_with(visitor)
179+
}
180+
}
181+
176182
impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Box<T> {
177183
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
178184
(**self).visit_with(visitor)

src/tools/tidy/src/deps.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
407407
"tracing-log",
408408
"tracing-subscriber",
409409
"tracing-tree",
410+
"triomphe",
410411
"twox-hash",
411412
"type-map",
412413
"typenum",

src/tools/tidy/src/extdeps.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ const ALLOWED_SOURCES: &[&str] = &[
88
r#""registry+https://github.com/rust-lang/crates.io-index""#,
99
// This is `rust_team_data` used by `site` in src/tools/rustc-perf,
1010
r#""git+https://github.com/rust-lang/team#a5260e76d3aa894c64c56e6ddc8545b9a98043ec""#,
11+
// temporary to test
12+
r#""git+https://github.com/Manishearth/triomphe.git?rev=6ff0527036632be33a6ed45e5e8a0fb6243dee47#6ff0527036632be33a6ed45e5e8a0fb6243dee47""#,
1113
];
1214

1315
/// Checks for external package sources. `root` is the path to the directory that contains the

0 commit comments

Comments
 (0)