Skip to content

Commit

Permalink
Auto merge of #59540 - Zoxc:the-arena-2, r=<try>
Browse files Browse the repository at this point in the history
[WIP] Use arenas to avoid Lrc in queries #1

Based on #59536.
  • Loading branch information
bors committed Apr 13, 2019
2 parents 99da733 + 9c3de34 commit f426a56
Show file tree
Hide file tree
Showing 12 changed files with 81 additions and 90 deletions.
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2812,6 +2812,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
1 change: 1 addition & 0 deletions src/librustc/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ macro_rules! arena_types {
)>,
[few] mir_keys: rustc::util::nodemap::DefIdSet,
[decode] specialization_graph: rustc::traits::specialization_graph::Graph,
[few] crate_inherent_impls: rustc::ty::CrateInherentImpls,
], $tcx);
)
}
Expand Down
12 changes: 6 additions & 6 deletions src/librustc/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ rustc_queries! {

/// Returns the inferred outlives predicates (e.g., for `struct
/// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`).
query inferred_outlives_of(_: DefId) -> Lrc<Vec<ty::Predicate<'tcx>>> {}
query inferred_outlives_of(_: DefId) -> &'tcx [ty::Predicate<'tcx>] {}

/// Maps from the `DefId` of a trait to the list of
/// super-predicates. This is a subset of the full list of
Expand Down Expand Up @@ -240,13 +240,13 @@ rustc_queries! {

/// Get a map with the variance of every item; use `item_variance`
/// instead.
query crate_variances(_: CrateNum) -> Lrc<ty::CrateVariancesMap> {
query crate_variances(_: CrateNum) -> Lrc<ty::CrateVariancesMap<'tcx>> {
desc { "computing the variances for items in this crate" }
}

/// Maps from def-id of a type or region parameter to its
/// (inferred) variance.
query variances_of(_: DefId) -> Lrc<Vec<ty::Variance>> {}
query variances_of(_: DefId) -> &'tcx [ty::Variance] {}
}

TypeChecking {
Expand All @@ -259,7 +259,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 @@ -274,7 +274,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 @@ -380,7 +380,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
45 changes: 19 additions & 26 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,15 +330,11 @@ pub enum Variance {
/// `tcx.variances_of()` to get the variance for a *particular*
/// item.
#[derive(HashStable)]
pub struct CrateVariancesMap {
pub struct CrateVariancesMap<'tcx> {
/// For each item with generics, maps to a vector of the variance
/// of its generics. If an item has no generics, it will have no
/// entry.
pub variances: FxHashMap<DefId, Lrc<Vec<ty::Variance>>>,

/// An empty vector, useful for cloning.
#[stable_hasher(ignore)]
pub empty_variance: Lrc<Vec<ty::Variance>>,
pub variances: FxHashMap<DefId, &'tcx [ty::Variance]>,
}

impl Variance {
Expand Down Expand Up @@ -1110,11 +1106,7 @@ pub struct CratePredicatesMap<'tcx> {
/// For each struct with outlive bounds, maps to a vector of the
/// predicate of its outlive bounds. If an item has no outlives
/// bounds, it will have no entry.
pub predicates: FxHashMap<DefId, Lrc<Vec<ty::Predicate<'tcx>>>>,

/// An empty vector, useful for cloning.
#[stable_hasher(ignore)]
pub empty_predicate: Lrc<Vec<ty::Predicate<'tcx>>>,
pub predicates: FxHashMap<DefId, &'tcx [ty::Predicate<'tcx>]>,
}

impl<'tcx> AsRef<Predicate<'tcx>> for Predicate<'tcx> {
Expand Down Expand Up @@ -3091,7 +3083,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {

pub struct AssociatedItemsIterator<'a, 'gcx: 'tcx, 'tcx: 'a> {
tcx: TyCtxt<'a, 'gcx, 'tcx>,
def_ids: Lrc<Vec<DefId>>,
def_ids: &'gcx [DefId],
next_index: usize,
}

Expand Down Expand Up @@ -3180,26 +3172,27 @@ fn adt_sized_constraint<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

fn associated_item_def_ids<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId)
-> Lrc<Vec<DefId>> {
-> &'tcx [DefId] {
let id = tcx.hir().as_local_hir_id(def_id).unwrap();
let item = tcx.hir().expect_item_by_hir_id(id);
let vec: Vec<_> = match item.node {
match item.node {
hir::ItemKind::Trait(.., ref trait_item_refs) => {
trait_item_refs.iter()
.map(|trait_item_ref| trait_item_ref.id)
.map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id))
.collect()
tcx.arena.alloc_from_iter(
trait_item_refs.iter()
.map(|trait_item_ref| trait_item_ref.id)
.map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id))
)
}
hir::ItemKind::Impl(.., ref impl_item_refs) => {
impl_item_refs.iter()
.map(|impl_item_ref| impl_item_ref.id)
.map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id))
.collect()
tcx.arena.alloc_from_iter(
impl_item_refs.iter()
.map(|impl_item_ref| impl_item_ref.id)
.map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id))
)
}
hir::ItemKind::TraitAlias(..) => vec![],
hir::ItemKind::TraitAlias(..) => &[],
_ => span_bug!(item.span, "associated_item_def_ids: not impl or trait")
};
Lrc::new(vec)
}
}

fn def_span<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Span {
Expand Down Expand Up @@ -3385,7 +3378,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
/// (constructing this map requires touching the entire crate).
#[derive(Clone, Debug, Default, HashStable)]
pub struct CrateInherentImpls {
pub inherent_impls: DefIdMap<Lrc<Vec<DefId>>>,
pub inherent_impls: DefIdMap<Vec<DefId>>,
}

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable)]
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/ty/relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pub trait TypeRelation<'a, 'gcx: 'a+'tcx, 'tcx: 'a> : Sized {
b_subst);

let opt_variances = self.tcx().variances_of(item_def_id);
relate_substs(self, Some(&opt_variances), a_subst, b_subst)
relate_substs(self, Some(opt_variances), a_subst, b_subst)
}

/// Switch variance for the purpose of relating `a` and `b`.
Expand Down Expand Up @@ -122,7 +122,7 @@ impl<'tcx> Relate<'tcx> for ty::TypeAndMut<'tcx> {
}

pub fn relate_substs<'a, 'gcx, 'tcx, R>(relation: &mut R,
variances: Option<&Vec<ty::Variance>>,
variances: Option<&[ty::Variance]>,
a_subst: SubstsRef<'tcx>,
b_subst: SubstsRef<'tcx>)
-> RelateResult<'tcx, SubstsRef<'tcx>>
Expand Down
1 change: 1 addition & 0 deletions src/librustc_metadata/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ crate-type = ["dylib"]
flate2 = "1.0"
log = "0.4"
memmap = "0.6"
smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
rustc = { path = "../librustc" }
rustc_data_structures = { path = "../librustc_data_structures" }
errors = { path = "../librustc_errors", package = "rustc_errors" }
Expand Down
9 changes: 5 additions & 4 deletions src/librustc_metadata/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use rustc::hir::map::definitions::DefPathTable;
use rustc::util::nodemap::DefIdMap;
use rustc_data_structures::svh::Svh;

use smallvec::SmallVec;
use std::any::Any;
use rustc_data_structures::sync::Lrc;
use std::sync::Arc;
Expand Down Expand Up @@ -105,12 +106,12 @@ provide! { <'tcx> tcx, def_id, other, cdata,
let _ = cdata;
tcx.calculate_dtor(def_id, &mut |_,_| Ok(()))
}
variances_of => { Lrc::new(cdata.get_item_variances(def_id.index)) }
variances_of => { tcx.arena.alloc_from_iter(cdata.get_item_variances(def_id.index)) }
associated_item_def_ids => {
let mut result = vec![];
let mut result = SmallVec::<[_; 8]>::new();
cdata.each_child_of_item(def_id.index,
|child| result.push(child.def.def_id()), tcx.sess);
Lrc::new(result)
tcx.arena.alloc_from_iter(result)
}
associated_item => { cdata.get_associated_item(def_id.index) }
impl_trait_ref => { cdata.get_impl_trait(def_id.index, tcx) }
Expand All @@ -133,7 +134,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
(cdata.mir_const_qualif(def_id.index), Lrc::new(BitSet::new_empty(0)))
}
fn_sig => { cdata.fn_sig(def_id.index, tcx) }
inherent_impls => { Lrc::new(cdata.get_inherent_implementations_for_type(def_id.index)) }
inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
is_const_fn_raw => { cdata.is_const_fn_raw(def_id.index) }
is_foreign_item => { cdata.is_foreign_item(def_id.index) }
describe_def => { cdata.get_def(def_id.index) }
Expand Down
15 changes: 9 additions & 6 deletions src/librustc_metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -998,12 +998,15 @@ impl<'a, 'tcx> CrateMetadata {
None
}

pub fn get_inherent_implementations_for_type(&self, id: DefIndex) -> Vec<DefId> {
self.entry(id)
.inherent_impls
.decode(self)
.map(|index| self.local_def_id(index))
.collect()
pub fn get_inherent_implementations_for_type(
&self,
tcx: TyCtxt<'_, 'tcx, '_>,
id: DefIndex
) -> &'tcx [DefId] {
tcx.arena.alloc_from_iter(self.entry(id)
.inherent_impls
.decode(self)
.map(|index| self.local_def_id(index)))
}

pub fn get_implementations_for_trait(&self,
Expand Down
24 changes: 7 additions & 17 deletions src/librustc_typeck/coherence/inherent_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@ use rustc::hir;
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::ty::{self, CrateInherentImpls, TyCtxt};

use rustc_data_structures::sync::Lrc;
use syntax::ast;
use syntax_pos::Span;

/// On-demand query: yields a map containing all types mapped to their inherent impls.
pub fn crate_inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
crate_num: CrateNum)
-> Lrc<CrateInherentImpls> {
-> &'tcx CrateInherentImpls {
assert_eq!(crate_num, LOCAL_CRATE);

let krate = tcx.hir().krate();
Expand All @@ -29,13 +28,13 @@ pub fn crate_inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
impls_map: Default::default(),
};
krate.visit_all_item_likes(&mut collect);
Lrc::new(collect.impls_map)
tcx.arena.alloc(collect.impls_map)
}

/// On-demand query: yields a vector of the inherent impls for a specific type.
pub fn inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
ty_def_id: DefId)
-> Lrc<Vec<DefId>> {
-> &'tcx [DefId] {
assert!(ty_def_id.is_local());

// NB. Until we adopt the red-green dep-tracking algorithm (see
Expand All @@ -53,15 +52,11 @@ pub fn inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
//
// [the plan]: https://github.com/rust-lang/rust-roadmap/issues/4

thread_local! {
static EMPTY_DEF_ID_VEC: Lrc<Vec<DefId>> = Lrc::new(vec![])
}

let result = tcx.dep_graph.with_ignore(|| {
let crate_map = tcx.crate_inherent_impls(ty_def_id.krate);
match crate_map.inherent_impls.get(&ty_def_id) {
Some(v) => v.clone(),
None => EMPTY_DEF_ID_VEC.with(|v| v.clone())
Some(v) => &v[..],
None => &[],
}
});

Expand Down Expand Up @@ -289,13 +284,8 @@ impl<'a, 'tcx> InherentCollect<'a, 'tcx> {
// type def ID, if there is a base type for this implementation and
// the implementation does not have any associated traits.
let impl_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
let mut rc_vec = self.impls_map.inherent_impls
.entry(def_id)
.or_default();

// At this point, there should not be any clones of the
// `Lrc`, so we can still safely push into it in place:
Lrc::get_mut(&mut rc_vec).unwrap().push(impl_def_id);
let vec = self.impls_map.inherent_impls.entry(def_id).or_default();
vec.push(impl_def_id);
} else {
struct_span_err!(self.tcx.sess,
item.span,
Expand Down
19 changes: 8 additions & 11 deletions src/librustc_typeck/outlives/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub fn provide(providers: &mut Providers<'_>) {
fn inferred_outlives_of<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
item_def_id: DefId,
) -> Lrc<Vec<ty::Predicate<'tcx>>> {
) -> &'tcx [ty::Predicate<'tcx>] {
let id = tcx
.hir()
.as_local_hir_id(item_def_id)
Expand All @@ -37,8 +37,8 @@ fn inferred_outlives_of<'a, 'tcx>(
let predicates = crate_map
.predicates
.get(&item_def_id)
.unwrap_or(&crate_map.empty_predicate)
.clone();
.map(|p| *p)
.unwrap_or(&[]);

if tcx.has_attr(item_def_id, "rustc_outlives") {
let mut pred: Vec<String> = predicates
Expand All @@ -63,10 +63,10 @@ fn inferred_outlives_of<'a, 'tcx>(
predicates
}

_ => Lrc::new(Vec::new()),
_ => &[],
},

_ => Lrc::new(Vec::new()),
_ => &[],
}
}

Expand Down Expand Up @@ -96,7 +96,7 @@ fn inferred_outlives_crate<'tcx>(
let predicates = global_inferred_outlives
.iter()
.map(|(&def_id, set)| {
let vec: Vec<ty::Predicate<'tcx>> = set
let predicates = tcx.arena.alloc_from_iter(set
.iter()
.filter_map(
|ty::OutlivesPredicate(kind1, region2)| match kind1.unpack() {
Expand All @@ -115,14 +115,11 @@ fn inferred_outlives_crate<'tcx>(
None
}
},
).collect();
(def_id, Lrc::new(vec))
));
(def_id, &*predicates)
}).collect();

let empty_predicate = Lrc::new(Vec::new());

Lrc::new(ty::CratePredicatesMap {
predicates,
empty_predicate,
})
}
8 changes: 4 additions & 4 deletions src/librustc_typeck/variance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub fn provide(providers: &mut Providers<'_>) {
}

fn crate_variances<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum)
-> Lrc<CrateVariancesMap> {
-> Lrc<CrateVariancesMap<'tcx>> {
assert_eq!(crate_num, LOCAL_CRATE);
let mut arena = arena::TypedArena::default();
let terms_cx = terms::determine_parameters_to_be_inferred(tcx, &mut arena);
Expand All @@ -45,7 +45,7 @@ fn crate_variances<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum)
}

fn variances_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId)
-> Lrc<Vec<ty::Variance>> {
-> &'tcx [ty::Variance] {
let id = tcx.hir().as_local_hir_id(item_def_id).expect("expected local def-id");
let unsupported = || {
// Variance not relevant.
Expand Down Expand Up @@ -88,6 +88,6 @@ fn variances_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId)

let crate_map = tcx.crate_variances(LOCAL_CRATE);
crate_map.variances.get(&item_def_id)
.unwrap_or(&crate_map.empty_variance)
.clone()
.map(|p| *p)
.unwrap_or(&[])
}
Loading

0 comments on commit f426a56

Please sign in to comment.