Skip to content

Commit

Permalink
Lift using interners instead of in_arena
Browse files Browse the repository at this point in the history
  • Loading branch information
Zoxc committed Jan 1, 2020
1 parent 490d5ac commit 8f52664
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 17 deletions.
39 changes: 22 additions & 17 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ use crate::util::nodemap::{FxHashMap, FxHashSet};
use arena::SyncDroplessArena;
use errors::DiagnosticBuilder;
use rustc_data_structures::profiling::SelfProfilerRef;
use rustc_data_structures::sharded::ShardedHashMap;
use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
use rustc_data_structures::stable_hasher::{
hash_stable_hashmap, HashStable, StableHasher, StableVec,
};
Expand Down Expand Up @@ -1557,11 +1557,11 @@ pub trait Lift<'tcx>: fmt::Debug {
}

macro_rules! nop_lift {
($ty:ty => $lifted:ty) => {
($set:ident; $ty:ty => $lifted:ty) => {
impl<'a, 'tcx> Lift<'tcx> for $ty {
type Lifted = $lifted;
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
if tcx.interners.arena.in_arena(*self as *const _) {
if tcx.interners.$set.contains_pointer_to(&Interned(*self)) {
Some(unsafe { mem::transmute(*self) })
} else {
None
Expand All @@ -1572,14 +1572,14 @@ macro_rules! nop_lift {
}

macro_rules! nop_list_lift {
($ty:ty => $lifted:ty) => {
($set:ident; $ty:ty => $lifted:ty) => {
impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> {
type Lifted = &'tcx List<$lifted>;
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
if self.is_empty() {
return Some(List::empty());
}
if tcx.interners.arena.in_arena(*self as *const _) {
if tcx.interners.$set.contains_pointer_to(&Interned(*self)) {
Some(unsafe { mem::transmute(*self) })
} else {
None
Expand All @@ -1589,21 +1589,21 @@ macro_rules! nop_list_lift {
};
}

nop_lift! {Ty<'a> => Ty<'tcx>}
nop_lift! {Region<'a> => Region<'tcx>}
nop_lift! {Goal<'a> => Goal<'tcx>}
nop_lift! {&'a Const<'a> => &'tcx Const<'tcx>}
nop_lift! {type_; Ty<'a> => Ty<'tcx>}
nop_lift! {region; Region<'a> => Region<'tcx>}
nop_lift! {goal; Goal<'a> => Goal<'tcx>}
nop_lift! {const_; &'a Const<'a> => &'tcx Const<'tcx>}

nop_list_lift! {Goal<'a> => Goal<'tcx>}
nop_list_lift! {Clause<'a> => Clause<'tcx>}
nop_list_lift! {Ty<'a> => Ty<'tcx>}
nop_list_lift! {ExistentialPredicate<'a> => ExistentialPredicate<'tcx>}
nop_list_lift! {Predicate<'a> => Predicate<'tcx>}
nop_list_lift! {CanonicalVarInfo => CanonicalVarInfo}
nop_list_lift! {ProjectionKind => ProjectionKind}
nop_list_lift! {goal_list; Goal<'a> => Goal<'tcx>}
nop_list_lift! {clauses; Clause<'a> => Clause<'tcx>}
nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>}
nop_list_lift! {existential_predicates; ExistentialPredicate<'a> => ExistentialPredicate<'tcx>}
nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>}
nop_list_lift! {canonical_var_infos; CanonicalVarInfo => CanonicalVarInfo}
nop_list_lift! {projs; ProjectionKind => ProjectionKind}

// This is the impl for `&'a InternalSubsts<'a>`.
nop_list_lift! {GenericArg<'a> => GenericArg<'tcx>}
nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>}

pub mod tls {
use super::{ptr_eq, GlobalCtxt, TyCtxt};
Expand Down Expand Up @@ -1927,6 +1927,11 @@ impl<'tcx, T: 'tcx + ?Sized> Clone for Interned<'tcx, T> {
}
impl<'tcx, T: 'tcx + ?Sized> Copy for Interned<'tcx, T> {}

unsafe impl<'tcx, T: 'tcx + ?Sized> IntoPointer for Interned<'tcx, T> {
fn into_pointer(&self) -> *const () {
self.0 as *const _ as *const ()
}
}
// N.B., an `Interned<Ty>` compares and hashes as a `TyKind`.
impl<'tcx> PartialEq for Interned<'tcx, TyS<'tcx>> {
fn eq(&self, other: &Interned<'tcx, TyS<'tcx>>) -> bool {
Expand Down
14 changes: 14 additions & 0 deletions src/librustc_data_structures/sharded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,20 @@ impl<K: Eq + Hash + Copy> ShardedHashMap<K, ()> {
}
}

pub unsafe trait IntoPointer {
/// Returns a pointer which outlives `self`.
fn into_pointer(&self) -> *const ();
}

impl<K: Eq + Hash + Copy + IntoPointer> ShardedHashMap<K, ()> {
pub fn contains_pointer_to<T: Hash + IntoPointer>(&self, value: &T) -> bool {
let hash = make_hash(&value);
let shard = self.get_shard_by_hash(hash).lock();
let value = value.into_pointer();
shard.raw_entry().from_hash(hash, |entry| entry.into_pointer() == value).is_some()
}
}

#[inline]
fn make_hash<K: Hash + ?Sized>(val: &K) -> u64 {
let mut state = FxHasher::default();
Expand Down

0 comments on commit 8f52664

Please sign in to comment.