Skip to content

Commit

Permalink
Rollup merge of rust-lang#59545 - Zoxc:the-arena-3, r=michaelwoerister
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Centril committed May 22, 2019
2 parents dbfe70d + 6ad9f1b commit be7222a
Show file tree
Hide file tree
Showing 29 changed files with 209 additions and 230 deletions.
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2877,6 +2877,7 @@ dependencies = [
"rustc_errors 0.0.0",
"rustc_target 0.0.0",
"serialize 0.0.0",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntax 0.0.0",
"syntax_ext 0.0.0",
Expand Down
29 changes: 24 additions & 5 deletions src/libarena/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -486,9 +486,31 @@ impl DroplessArena {
}
}

#[inline]
unsafe fn write_from_iter<T, I: Iterator<Item = T>>(
&self,
mut iter: I,
len: usize,
mem: *mut T,
) -> &mut [T] {
let mut i = 0;
// Use a manual loop since LLVM manages to optimize it better for
// slice iterators
loop {
let value = iter.next();
if i >= len || value.is_none() {
// We only return as many items as the iterator gave us, even
// though it was supposed to give us `len`
return slice::from_raw_parts_mut(mem, i);
}
ptr::write(mem.offset(i as isize), value.unwrap());
i += 1;
}
}

#[inline]
pub fn alloc_from_iter<T, I: IntoIterator<Item = T>>(&self, iter: I) -> &mut [T] {
let mut iter = iter.into_iter();
let iter = iter.into_iter();
assert!(mem::size_of::<T>() != 0);
assert!(!mem::needs_drop::<T>());

Expand All @@ -505,10 +527,7 @@ impl DroplessArena {
let size = len.checked_mul(mem::size_of::<T>()).unwrap();
let mem = self.alloc_raw(size, mem::align_of::<T>()) as *mut _ as *mut T;
unsafe {
for i in 0..len {
ptr::write(mem.offset(i as isize), iter.next().unwrap())
}
slice::from_raw_parts_mut(mem, len)
self.write_from_iter(iter, len, mem)
}
}
(_, _) => {
Expand Down
24 changes: 22 additions & 2 deletions src/librustc/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ use std::cell::RefCell;
use std::marker::PhantomData;
use smallvec::SmallVec;

/// This declares a list of types which can be allocated by `Arena`.
///
/// The `few` modifier will cause allocation to use the shared arena and recording the destructor.
/// This is faster and more memory efficient if there's only a few allocations of the type.
/// Leaving `few` out will cause the type to get its own dedicated `TypedArena` which is
/// faster and more memory efficient if there is lots of allocations.
///
/// Specifying the `decode` modifier will add decode impls for &T and &[T] where T is the type
/// listed. These impls will appear in the implement_ty_decoder! macro.
#[macro_export]
macro_rules! arena_types {
($macro:path, $args:tt, $tcx:lifetime) => (
Expand All @@ -14,7 +23,7 @@ macro_rules! arena_types {
rustc::hir::def_id::DefId,
rustc::ty::subst::SubstsRef<$tcx>
)>,
[few] mir_keys: rustc::util::nodemap::DefIdSet,
[few, decode] mir_keys: rustc::util::nodemap::DefIdSet,
[decode] specialization_graph: rustc::traits::specialization_graph::Graph,
[] region_scope_tree: rustc::middle::region::ScopeTree,
[] item_local_set: rustc::util::nodemap::ItemLocalSet,
Expand Down Expand Up @@ -58,6 +67,17 @@ macro_rules! arena_types {
rustc::infer::canonical::Canonical<'tcx,
rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::Ty<'tcx>>
>,
[few] crate_inherent_impls: rustc::ty::CrateInherentImpls,
[decode] borrowck: rustc::middle::borrowck::BorrowCheckResult,
[few] upstream_monomorphizations:
rustc::util::nodemap::DefIdMap<
rustc_data_structures::fx::FxHashMap<
rustc::ty::subst::SubstsRef<'tcx>,
rustc::hir::def_id::CrateNum
>
>,
[few] resolve_lifetimes: rustc::middle::resolve_lifetime::ResolveLifetimes,
[decode] generic_predicates: rustc::ty::GenericPredicates<'tcx>,
], $tcx);
)
}
Expand Down Expand Up @@ -119,7 +139,7 @@ pub trait ArenaAllocatable {}

impl<T: Copy> ArenaAllocatable for T {}

pub unsafe trait ArenaField<'tcx>: Sized {
unsafe trait ArenaField<'tcx>: Sized {
/// Returns a specific arena to allocate from.
/// If None is returned, the DropArena will be used.
fn arena<'a>(arena: &'a Arena<'tcx>) -> Option<&'a TypedArena<Self>>;
Expand Down
23 changes: 9 additions & 14 deletions src/librustc/middle/resolve_lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use crate::rustc::lint;
use crate::session::Session;
use crate::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, HirIdMap, HirIdSet};
use errors::{Applicability, DiagnosticBuilder};
use rustc_data_structures::sync::Lrc;
use rustc_macros::HashStable;
use std::borrow::Cow;
use std::cell::Cell;
Expand Down Expand Up @@ -211,10 +210,10 @@ struct NamedRegionMap {
/// See [`NamedRegionMap`].
#[derive(Default)]
pub struct ResolveLifetimes {
defs: FxHashMap<LocalDefId, Lrc<FxHashMap<ItemLocalId, Region>>>,
late_bound: FxHashMap<LocalDefId, Lrc<FxHashSet<ItemLocalId>>>,
defs: FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Region>>,
late_bound: FxHashMap<LocalDefId, FxHashSet<ItemLocalId>>,
object_lifetime_defaults:
FxHashMap<LocalDefId, Lrc<FxHashMap<ItemLocalId, Lrc<Vec<ObjectLifetimeDefault>>>>>,
FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Vec<ObjectLifetimeDefault>>>,
}

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

named_region_map: |tcx, id| {
let id = LocalDefId::from_def_id(DefId::local(id)); // (*)
tcx.resolve_lifetimes(LOCAL_CRATE).defs.get(&id).cloned()
tcx.resolve_lifetimes(LOCAL_CRATE).defs.get(&id)
},

is_late_bound_map: |tcx, id| {
let id = LocalDefId::from_def_id(DefId::local(id)); // (*)
tcx.resolve_lifetimes(LOCAL_CRATE)
.late_bound
.get(&id)
.cloned()
},

object_lifetime_defaults_map: |tcx, id| {
let id = LocalDefId::from_def_id(DefId::local(id)); // (*)
tcx.resolve_lifetimes(LOCAL_CRATE)
.object_lifetime_defaults
.get(&id)
.cloned()
},

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

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

for (hir_id, v) in named_region_map.defs {
let map = rl.defs.entry(hir_id.owner_local_def_id()).or_default();
Lrc::get_mut(map).unwrap().insert(hir_id.local_id, v);
map.insert(hir_id.local_id, v);
}
for hir_id in named_region_map.late_bound {
let map = rl.late_bound
.entry(hir_id.owner_local_def_id())
.or_default();
Lrc::get_mut(map).unwrap().insert(hir_id.local_id);
map.insert(hir_id.local_id);
}
for (hir_id, v) in named_region_map.object_lifetime_defaults {
let map = rl.object_lifetime_defaults
.entry(hir_id.owner_local_def_id())
.or_default();
Lrc::get_mut(map)
.unwrap()
.insert(hir_id.local_id, Lrc::new(v));
map.insert(hir_id.local_id, v);
}

Lrc::new(rl)
tcx.arena.alloc(rl)
}

fn krate<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> NamedRegionMap {
Expand Down
38 changes: 19 additions & 19 deletions src/librustc/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ rustc_queries! {
/// predicate gets in the way of some checks, which are intended
/// to operate over only the actual where-clauses written by the
/// user.)
query predicates_of(_: DefId) -> Lrc<ty::GenericPredicates<'tcx>> {}
query predicates_of(_: DefId) -> &'tcx ty::GenericPredicates<'tcx> {}

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

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

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

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

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

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

Other {
query used_trait_imports(_: DefId) -> Lrc<DefIdSet> {}
query used_trait_imports(_: DefId) -> &'tcx DefIdSet {}
}

TypeChecking {
Expand All @@ -373,7 +373,7 @@ rustc_queries! {
}

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

/// Borrow checks the function body. If this is a closure, returns
/// additional requirements that the closure's creator must verify.
Expand All @@ -385,7 +385,7 @@ rustc_queries! {
/// Not meant to be used directly outside of coherence.
/// (Defined only for `LOCAL_CRATE`.)
query crate_inherent_impls(k: CrateNum)
-> Lrc<CrateInherentImpls> {
-> &'tcx CrateInherentImpls {
eval_always
desc { "all inherent impls defined in crate `{:?}`", k }
}
Expand Down Expand Up @@ -683,11 +683,11 @@ rustc_queries! {
Codegen {
query upstream_monomorphizations(
k: CrateNum
) -> Lrc<DefIdMap<Lrc<FxHashMap<SubstsRef<'tcx>, CrateNum>>>> {
) -> &'tcx DefIdMap<FxHashMap<SubstsRef<'tcx>, CrateNum>> {
desc { "collecting available upstream monomorphizations `{:?}`", k }
}
query upstream_monomorphizations_for(_: DefId)
-> Option<Lrc<FxHashMap<SubstsRef<'tcx>, CrateNum>>> {}
-> Option<&'tcx FxHashMap<SubstsRef<'tcx>, CrateNum>> {}
}

Other {
Expand Down Expand Up @@ -726,12 +726,12 @@ rustc_queries! {

TypeChecking {
query implementations_of_trait(_: (CrateNum, DefId))
-> Lrc<Vec<DefId>> {
-> &'tcx [DefId] {
no_force
desc { "looking up implementations of a trait in a crate" }
}
query all_trait_implementations(_: CrateNum)
-> Lrc<Vec<DefId>> {
-> &'tcx [DefId] {
desc { "looking up all (?) trait implementations" }
}
}
Expand All @@ -756,19 +756,19 @@ rustc_queries! {

BorrowChecking {
// Lifetime resolution. See `middle::resolve_lifetimes`.
query resolve_lifetimes(_: CrateNum) -> Lrc<ResolveLifetimes> {
query resolve_lifetimes(_: CrateNum) -> &'tcx ResolveLifetimes {
desc { "resolving lifetimes" }
}
query named_region_map(_: DefIndex) ->
Option<Lrc<FxHashMap<ItemLocalId, Region>>> {
Option<&'tcx FxHashMap<ItemLocalId, Region>> {
desc { "looking up a named region" }
}
query is_late_bound_map(_: DefIndex) ->
Option<Lrc<FxHashSet<ItemLocalId>>> {
Option<&'tcx FxHashSet<ItemLocalId>> {
desc { "testing if a region is late bound" }
}
query object_lifetime_defaults_map(_: DefIndex)
-> Option<Lrc<FxHashMap<ItemLocalId, Lrc<Vec<ObjectLifetimeDefault>>>>> {
-> Option<&'tcx FxHashMap<ItemLocalId, Vec<ObjectLifetimeDefault>>> {
desc { "looking up lifetime defaults for a region" }
}
}
Expand All @@ -786,7 +786,7 @@ rustc_queries! {
eval_always
desc { "fetching what a crate is named" }
}
query item_children(_: DefId) -> Lrc<Vec<Export<hir::HirId>>> {}
query item_children(_: DefId) -> &'tcx [Export<hir::HirId>] {}
query extern_mod_stmt_cnum(_: DefId) -> Option<CrateNum> {}

query get_lib_features(_: CrateNum) -> Lrc<LibFeatures> {
Expand Down
18 changes: 16 additions & 2 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
}
}

pub struct Common<'tcx> {
pub empty_predicates: ty::GenericPredicates<'tcx>,
}

pub struct CommonTypes<'tcx> {
pub unit: Ty<'tcx>,
pub bool: Ty<'tcx>,
Expand Down Expand Up @@ -1045,6 +1049,9 @@ pub struct GlobalCtxt<'tcx> {

pub dep_graph: DepGraph,

/// Common objects.
pub common: Common<'tcx>,

/// Common types, pre-interned for your convenience.
pub types: CommonTypes<'tcx>,

Expand Down Expand Up @@ -1252,6 +1259,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
s.fatal(&err);
});
let interners = CtxtInterners::new(&arenas.interner);
let common = Common {
empty_predicates: ty::GenericPredicates {
parent: None,
predicates: vec![],
},
};
let common_types = CommonTypes::new(&interners);
let common_lifetimes = CommonLifetimes::new(&interners);
let common_consts = CommonConsts::new(&interners, &common_types);
Expand Down Expand Up @@ -1308,6 +1321,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
global_arenas: &arenas.global,
global_interners: interners,
dep_graph,
common,
types: common_types,
lifetimes: common_lifetimes,
consts: common_consts,
Expand Down Expand Up @@ -2982,10 +2996,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}

pub fn object_lifetime_defaults(self, id: HirId)
-> Option<Lrc<Vec<ObjectLifetimeDefault>>>
-> Option<&'gcx [ObjectLifetimeDefault]>
{
self.object_lifetime_defaults_map(id.owner)
.and_then(|map| map.get(&id.local_id).cloned())
.and_then(|map| map.get(&id.local_id).map(|v| &**v))
}
}

Expand Down
Loading

0 comments on commit be7222a

Please sign in to comment.