Skip to content

Commit be7222a

Browse files
authored
Rollup merge of rust-lang#59545 - Zoxc:the-arena-3, r=michaelwoerister
Use arenas to avoid Lrc in queries rust-lang#2 The `Remove subtle Default impl for Value` makes the compilation stop due earlier due to cycle errors, since there's no longer a default value to continue the compilation with. Based on rust-lang#59540.
2 parents dbfe70d + 6ad9f1b commit be7222a

29 files changed

+209
-230
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -2877,6 +2877,7 @@ dependencies = [
28772877
"rustc_errors 0.0.0",
28782878
"rustc_target 0.0.0",
28792879
"serialize 0.0.0",
2880+
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
28802881
"stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
28812882
"syntax 0.0.0",
28822883
"syntax_ext 0.0.0",

src/libarena/lib.rs

+24-5
Original file line numberDiff line numberDiff line change
@@ -486,9 +486,31 @@ impl DroplessArena {
486486
}
487487
}
488488

489+
#[inline]
490+
unsafe fn write_from_iter<T, I: Iterator<Item = T>>(
491+
&self,
492+
mut iter: I,
493+
len: usize,
494+
mem: *mut T,
495+
) -> &mut [T] {
496+
let mut i = 0;
497+
// Use a manual loop since LLVM manages to optimize it better for
498+
// slice iterators
499+
loop {
500+
let value = iter.next();
501+
if i >= len || value.is_none() {
502+
// We only return as many items as the iterator gave us, even
503+
// though it was supposed to give us `len`
504+
return slice::from_raw_parts_mut(mem, i);
505+
}
506+
ptr::write(mem.offset(i as isize), value.unwrap());
507+
i += 1;
508+
}
509+
}
510+
489511
#[inline]
490512
pub fn alloc_from_iter<T, I: IntoIterator<Item = T>>(&self, iter: I) -> &mut [T] {
491-
let mut iter = iter.into_iter();
513+
let iter = iter.into_iter();
492514
assert!(mem::size_of::<T>() != 0);
493515
assert!(!mem::needs_drop::<T>());
494516

@@ -505,10 +527,7 @@ impl DroplessArena {
505527
let size = len.checked_mul(mem::size_of::<T>()).unwrap();
506528
let mem = self.alloc_raw(size, mem::align_of::<T>()) as *mut _ as *mut T;
507529
unsafe {
508-
for i in 0..len {
509-
ptr::write(mem.offset(i as isize), iter.next().unwrap())
510-
}
511-
slice::from_raw_parts_mut(mem, len)
530+
self.write_from_iter(iter, len, mem)
512531
}
513532
}
514533
(_, _) => {

src/librustc/arena.rs

+22-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ use std::cell::RefCell;
66
use std::marker::PhantomData;
77
use smallvec::SmallVec;
88

9+
/// This declares a list of types which can be allocated by `Arena`.
10+
///
11+
/// The `few` modifier will cause allocation to use the shared arena and recording the destructor.
12+
/// This is faster and more memory efficient if there's only a few allocations of the type.
13+
/// Leaving `few` out will cause the type to get its own dedicated `TypedArena` which is
14+
/// faster and more memory efficient if there is lots of allocations.
15+
///
16+
/// Specifying the `decode` modifier will add decode impls for &T and &[T] where T is the type
17+
/// listed. These impls will appear in the implement_ty_decoder! macro.
918
#[macro_export]
1019
macro_rules! arena_types {
1120
($macro:path, $args:tt, $tcx:lifetime) => (
@@ -14,7 +23,7 @@ macro_rules! arena_types {
1423
rustc::hir::def_id::DefId,
1524
rustc::ty::subst::SubstsRef<$tcx>
1625
)>,
17-
[few] mir_keys: rustc::util::nodemap::DefIdSet,
26+
[few, decode] mir_keys: rustc::util::nodemap::DefIdSet,
1827
[decode] specialization_graph: rustc::traits::specialization_graph::Graph,
1928
[] region_scope_tree: rustc::middle::region::ScopeTree,
2029
[] item_local_set: rustc::util::nodemap::ItemLocalSet,
@@ -58,6 +67,17 @@ macro_rules! arena_types {
5867
rustc::infer::canonical::Canonical<'tcx,
5968
rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::Ty<'tcx>>
6069
>,
70+
[few] crate_inherent_impls: rustc::ty::CrateInherentImpls,
71+
[decode] borrowck: rustc::middle::borrowck::BorrowCheckResult,
72+
[few] upstream_monomorphizations:
73+
rustc::util::nodemap::DefIdMap<
74+
rustc_data_structures::fx::FxHashMap<
75+
rustc::ty::subst::SubstsRef<'tcx>,
76+
rustc::hir::def_id::CrateNum
77+
>
78+
>,
79+
[few] resolve_lifetimes: rustc::middle::resolve_lifetime::ResolveLifetimes,
80+
[decode] generic_predicates: rustc::ty::GenericPredicates<'tcx>,
6181
], $tcx);
6282
)
6383
}
@@ -119,7 +139,7 @@ pub trait ArenaAllocatable {}
119139

120140
impl<T: Copy> ArenaAllocatable for T {}
121141

122-
pub unsafe trait ArenaField<'tcx>: Sized {
142+
unsafe trait ArenaField<'tcx>: Sized {
123143
/// Returns a specific arena to allocate from.
124144
/// If None is returned, the DropArena will be used.
125145
fn arena<'a>(arena: &'a Arena<'tcx>) -> Option<&'a TypedArena<Self>>;

src/librustc/middle/resolve_lifetime.rs

+9-14
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use crate::rustc::lint;
1515
use crate::session::Session;
1616
use crate::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, HirIdMap, HirIdSet};
1717
use errors::{Applicability, DiagnosticBuilder};
18-
use rustc_data_structures::sync::Lrc;
1918
use rustc_macros::HashStable;
2019
use std::borrow::Cow;
2120
use std::cell::Cell;
@@ -211,10 +210,10 @@ struct NamedRegionMap {
211210
/// See [`NamedRegionMap`].
212211
#[derive(Default)]
213212
pub struct ResolveLifetimes {
214-
defs: FxHashMap<LocalDefId, Lrc<FxHashMap<ItemLocalId, Region>>>,
215-
late_bound: FxHashMap<LocalDefId, Lrc<FxHashSet<ItemLocalId>>>,
213+
defs: FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Region>>,
214+
late_bound: FxHashMap<LocalDefId, FxHashSet<ItemLocalId>>,
216215
object_lifetime_defaults:
217-
FxHashMap<LocalDefId, Lrc<FxHashMap<ItemLocalId, Lrc<Vec<ObjectLifetimeDefault>>>>>,
216+
FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Vec<ObjectLifetimeDefault>>>,
218217
}
219218

220219
impl_stable_hash_for!(struct crate::middle::resolve_lifetime::ResolveLifetimes {
@@ -347,23 +346,21 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
347346

348347
named_region_map: |tcx, id| {
349348
let id = LocalDefId::from_def_id(DefId::local(id)); // (*)
350-
tcx.resolve_lifetimes(LOCAL_CRATE).defs.get(&id).cloned()
349+
tcx.resolve_lifetimes(LOCAL_CRATE).defs.get(&id)
351350
},
352351

353352
is_late_bound_map: |tcx, id| {
354353
let id = LocalDefId::from_def_id(DefId::local(id)); // (*)
355354
tcx.resolve_lifetimes(LOCAL_CRATE)
356355
.late_bound
357356
.get(&id)
358-
.cloned()
359357
},
360358

361359
object_lifetime_defaults_map: |tcx, id| {
362360
let id = LocalDefId::from_def_id(DefId::local(id)); // (*)
363361
tcx.resolve_lifetimes(LOCAL_CRATE)
364362
.object_lifetime_defaults
365363
.get(&id)
366-
.cloned()
367364
},
368365

369366
..*providers
@@ -379,7 +376,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
379376
fn resolve_lifetimes<'tcx>(
380377
tcx: TyCtxt<'_, 'tcx, 'tcx>,
381378
for_krate: CrateNum,
382-
) -> Lrc<ResolveLifetimes> {
379+
) -> &'tcx ResolveLifetimes {
383380
assert_eq!(for_krate, LOCAL_CRATE);
384381

385382
let named_region_map = krate(tcx);
@@ -388,24 +385,22 @@ fn resolve_lifetimes<'tcx>(
388385

389386
for (hir_id, v) in named_region_map.defs {
390387
let map = rl.defs.entry(hir_id.owner_local_def_id()).or_default();
391-
Lrc::get_mut(map).unwrap().insert(hir_id.local_id, v);
388+
map.insert(hir_id.local_id, v);
392389
}
393390
for hir_id in named_region_map.late_bound {
394391
let map = rl.late_bound
395392
.entry(hir_id.owner_local_def_id())
396393
.or_default();
397-
Lrc::get_mut(map).unwrap().insert(hir_id.local_id);
394+
map.insert(hir_id.local_id);
398395
}
399396
for (hir_id, v) in named_region_map.object_lifetime_defaults {
400397
let map = rl.object_lifetime_defaults
401398
.entry(hir_id.owner_local_def_id())
402399
.or_default();
403-
Lrc::get_mut(map)
404-
.unwrap()
405-
.insert(hir_id.local_id, Lrc::new(v));
400+
map.insert(hir_id.local_id, v);
406401
}
407402

408-
Lrc::new(rl)
403+
tcx.arena.alloc(rl)
409404
}
410405

411406
fn krate<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> NamedRegionMap {

src/librustc/query/mod.rs

+19-19
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ rustc_queries! {
6161
/// predicate gets in the way of some checks, which are intended
6262
/// to operate over only the actual where-clauses written by the
6363
/// user.)
64-
query predicates_of(_: DefId) -> Lrc<ty::GenericPredicates<'tcx>> {}
64+
query predicates_of(_: DefId) -> &'tcx ty::GenericPredicates<'tcx> {}
6565

6666
query native_libraries(_: CrateNum) -> Lrc<Vec<NativeLibrary>> {
6767
desc { "looking up the native libraries of a linked crate" }
@@ -166,11 +166,11 @@ rustc_queries! {
166166
/// equal to the `explicit_predicates_of` predicates plus the
167167
/// `inferred_outlives_of` predicates.
168168
query predicates_defined_on(_: DefId)
169-
-> Lrc<ty::GenericPredicates<'tcx>> {}
169+
-> &'tcx ty::GenericPredicates<'tcx> {}
170170

171171
/// Returns the predicates written explicit by the user.
172172
query explicit_predicates_of(_: DefId)
173-
-> Lrc<ty::GenericPredicates<'tcx>> {}
173+
-> &'tcx ty::GenericPredicates<'tcx> {}
174174

175175
/// Returns the inferred outlives predicates (e.g., for `struct
176176
/// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`).
@@ -182,14 +182,14 @@ rustc_queries! {
182182
/// evaluate them even during type conversion, often before the
183183
/// full predicates are available (note that supertraits have
184184
/// additional acyclicity requirements).
185-
query super_predicates_of(key: DefId) -> Lrc<ty::GenericPredicates<'tcx>> {
185+
query super_predicates_of(key: DefId) -> &'tcx ty::GenericPredicates<'tcx> {
186186
desc { |tcx| "computing the supertraits of `{}`", tcx.def_path_str(key) }
187187
}
188188

189189
/// To avoid cycles within the predicates of a single item we compute
190190
/// per-type-parameter predicates for resolving `T::AssocTy`.
191191
query type_param_predicates(key: (DefId, DefId))
192-
-> Lrc<ty::GenericPredicates<'tcx>> {
192+
-> &'tcx ty::GenericPredicates<'tcx> {
193193
no_force
194194
desc { |tcx| "computing the bounds for type parameter `{}`", {
195195
let id = tcx.hir().as_local_hir_id(key.1).unwrap();
@@ -264,7 +264,7 @@ rustc_queries! {
264264

265265
Other {
266266
/// Maps from an impl/trait def-id to a list of the def-ids of its items
267-
query associated_item_def_ids(_: DefId) -> Lrc<Vec<DefId>> {}
267+
query associated_item_def_ids(_: DefId) -> &'tcx [DefId] {}
268268

269269
/// Maps from a trait item to the trait item "descriptor"
270270
query associated_item(_: DefId) -> ty::AssociatedItem {}
@@ -279,7 +279,7 @@ rustc_queries! {
279279
/// Maps a DefId of a type to a list of its inherent impls.
280280
/// Contains implementations of methods that are inherent to a type.
281281
/// Methods in these implementations don't need to be exported.
282-
query inherent_impls(_: DefId) -> Lrc<Vec<DefId>> {
282+
query inherent_impls(_: DefId) -> &'tcx [DefId] {
283283
eval_always
284284
}
285285
}
@@ -361,7 +361,7 @@ rustc_queries! {
361361
}
362362

363363
Other {
364-
query used_trait_imports(_: DefId) -> Lrc<DefIdSet> {}
364+
query used_trait_imports(_: DefId) -> &'tcx DefIdSet {}
365365
}
366366

367367
TypeChecking {
@@ -373,7 +373,7 @@ rustc_queries! {
373373
}
374374

375375
BorrowChecking {
376-
query borrowck(_: DefId) -> Lrc<BorrowCheckResult> {}
376+
query borrowck(_: DefId) -> &'tcx BorrowCheckResult {}
377377

378378
/// Borrow checks the function body. If this is a closure, returns
379379
/// additional requirements that the closure's creator must verify.
@@ -385,7 +385,7 @@ rustc_queries! {
385385
/// Not meant to be used directly outside of coherence.
386386
/// (Defined only for `LOCAL_CRATE`.)
387387
query crate_inherent_impls(k: CrateNum)
388-
-> Lrc<CrateInherentImpls> {
388+
-> &'tcx CrateInherentImpls {
389389
eval_always
390390
desc { "all inherent impls defined in crate `{:?}`", k }
391391
}
@@ -683,11 +683,11 @@ rustc_queries! {
683683
Codegen {
684684
query upstream_monomorphizations(
685685
k: CrateNum
686-
) -> Lrc<DefIdMap<Lrc<FxHashMap<SubstsRef<'tcx>, CrateNum>>>> {
686+
) -> &'tcx DefIdMap<FxHashMap<SubstsRef<'tcx>, CrateNum>> {
687687
desc { "collecting available upstream monomorphizations `{:?}`", k }
688688
}
689689
query upstream_monomorphizations_for(_: DefId)
690-
-> Option<Lrc<FxHashMap<SubstsRef<'tcx>, CrateNum>>> {}
690+
-> Option<&'tcx FxHashMap<SubstsRef<'tcx>, CrateNum>> {}
691691
}
692692

693693
Other {
@@ -726,12 +726,12 @@ rustc_queries! {
726726

727727
TypeChecking {
728728
query implementations_of_trait(_: (CrateNum, DefId))
729-
-> Lrc<Vec<DefId>> {
729+
-> &'tcx [DefId] {
730730
no_force
731731
desc { "looking up implementations of a trait in a crate" }
732732
}
733733
query all_trait_implementations(_: CrateNum)
734-
-> Lrc<Vec<DefId>> {
734+
-> &'tcx [DefId] {
735735
desc { "looking up all (?) trait implementations" }
736736
}
737737
}
@@ -756,19 +756,19 @@ rustc_queries! {
756756

757757
BorrowChecking {
758758
// Lifetime resolution. See `middle::resolve_lifetimes`.
759-
query resolve_lifetimes(_: CrateNum) -> Lrc<ResolveLifetimes> {
759+
query resolve_lifetimes(_: CrateNum) -> &'tcx ResolveLifetimes {
760760
desc { "resolving lifetimes" }
761761
}
762762
query named_region_map(_: DefIndex) ->
763-
Option<Lrc<FxHashMap<ItemLocalId, Region>>> {
763+
Option<&'tcx FxHashMap<ItemLocalId, Region>> {
764764
desc { "looking up a named region" }
765765
}
766766
query is_late_bound_map(_: DefIndex) ->
767-
Option<Lrc<FxHashSet<ItemLocalId>>> {
767+
Option<&'tcx FxHashSet<ItemLocalId>> {
768768
desc { "testing if a region is late bound" }
769769
}
770770
query object_lifetime_defaults_map(_: DefIndex)
771-
-> Option<Lrc<FxHashMap<ItemLocalId, Lrc<Vec<ObjectLifetimeDefault>>>>> {
771+
-> Option<&'tcx FxHashMap<ItemLocalId, Vec<ObjectLifetimeDefault>>> {
772772
desc { "looking up lifetime defaults for a region" }
773773
}
774774
}
@@ -786,7 +786,7 @@ rustc_queries! {
786786
eval_always
787787
desc { "fetching what a crate is named" }
788788
}
789-
query item_children(_: DefId) -> Lrc<Vec<Export<hir::HirId>>> {}
789+
query item_children(_: DefId) -> &'tcx [Export<hir::HirId>] {}
790790
query extern_mod_stmt_cnum(_: DefId) -> Option<CrateNum> {}
791791

792792
query get_lib_features(_: CrateNum) -> Lrc<LibFeatures> {

src/librustc/ty/context.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,10 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
201201
}
202202
}
203203

204+
pub struct Common<'tcx> {
205+
pub empty_predicates: ty::GenericPredicates<'tcx>,
206+
}
207+
204208
pub struct CommonTypes<'tcx> {
205209
pub unit: Ty<'tcx>,
206210
pub bool: Ty<'tcx>,
@@ -1045,6 +1049,9 @@ pub struct GlobalCtxt<'tcx> {
10451049

10461050
pub dep_graph: DepGraph,
10471051

1052+
/// Common objects.
1053+
pub common: Common<'tcx>,
1054+
10481055
/// Common types, pre-interned for your convenience.
10491056
pub types: CommonTypes<'tcx>,
10501057

@@ -1252,6 +1259,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12521259
s.fatal(&err);
12531260
});
12541261
let interners = CtxtInterners::new(&arenas.interner);
1262+
let common = Common {
1263+
empty_predicates: ty::GenericPredicates {
1264+
parent: None,
1265+
predicates: vec![],
1266+
},
1267+
};
12551268
let common_types = CommonTypes::new(&interners);
12561269
let common_lifetimes = CommonLifetimes::new(&interners);
12571270
let common_consts = CommonConsts::new(&interners, &common_types);
@@ -1308,6 +1321,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
13081321
global_arenas: &arenas.global,
13091322
global_interners: interners,
13101323
dep_graph,
1324+
common,
13111325
types: common_types,
13121326
lifetimes: common_lifetimes,
13131327
consts: common_consts,
@@ -2982,10 +2996,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
29822996
}
29832997

29842998
pub fn object_lifetime_defaults(self, id: HirId)
2985-
-> Option<Lrc<Vec<ObjectLifetimeDefault>>>
2999+
-> Option<&'gcx [ObjectLifetimeDefault]>
29863000
{
29873001
self.object_lifetime_defaults_map(id.owner)
2988-
.and_then(|map| map.get(&id.local_id).cloned())
3002+
.and_then(|map| map.get(&id.local_id).map(|v| &**v))
29893003
}
29903004
}
29913005

0 commit comments

Comments
 (0)