Skip to content

Commit 8c016c3

Browse files
authored
Rollup merge of #67791 - Zoxc:lift-interning, r=eddyb
Implement Lift using interners instead of in_arena r? @eddyb cc @cjgillot
2 parents d3589aa + f4968c8 commit 8c016c3

File tree

8 files changed

+67
-132
lines changed

8 files changed

+67
-132
lines changed

src/libarena/lib.rs

-73
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
extern crate alloc;
2222

2323
use rustc_data_structures::cold_path;
24-
use rustc_data_structures::sync::MTLock;
2524
use smallvec::SmallVec;
2625

2726
use std::cell::{Cell, RefCell};
@@ -116,11 +115,6 @@ impl<T> Default for TypedArena<T> {
116115
}
117116

118117
impl<T> TypedArena<T> {
119-
pub fn in_arena(&self, ptr: *const T) -> bool {
120-
let ptr = ptr as *const T as *mut T;
121-
122-
self.chunks.borrow().iter().any(|chunk| chunk.start() <= ptr && ptr < chunk.end())
123-
}
124118
/// Allocates an object in the `TypedArena`, returning a reference to it.
125119
#[inline]
126120
pub fn alloc(&self, object: T) -> &mut T {
@@ -334,12 +328,6 @@ impl Default for DroplessArena {
334328
}
335329

336330
impl DroplessArena {
337-
pub fn in_arena<T: ?Sized>(&self, ptr: *const T) -> bool {
338-
let ptr = ptr as *const u8 as *mut u8;
339-
340-
self.chunks.borrow().iter().any(|chunk| chunk.start() <= ptr && ptr < chunk.end())
341-
}
342-
343331
#[inline]
344332
fn align(&self, align: usize) {
345333
let final_address = ((self.ptr.get() as usize) + align - 1) & !(align - 1);
@@ -500,66 +488,5 @@ impl DroplessArena {
500488
}
501489
}
502490

503-
#[derive(Default)]
504-
// FIXME(@Zoxc): this type is entirely unused in rustc
505-
pub struct SyncTypedArena<T> {
506-
lock: MTLock<TypedArena<T>>,
507-
}
508-
509-
impl<T> SyncTypedArena<T> {
510-
#[inline(always)]
511-
pub fn alloc(&self, object: T) -> &mut T {
512-
// Extend the lifetime of the result since it's limited to the lock guard
513-
unsafe { &mut *(self.lock.lock().alloc(object) as *mut T) }
514-
}
515-
516-
#[inline(always)]
517-
pub fn alloc_slice(&self, slice: &[T]) -> &mut [T]
518-
where
519-
T: Copy,
520-
{
521-
// Extend the lifetime of the result since it's limited to the lock guard
522-
unsafe { &mut *(self.lock.lock().alloc_slice(slice) as *mut [T]) }
523-
}
524-
525-
#[inline(always)]
526-
pub fn clear(&mut self) {
527-
self.lock.get_mut().clear();
528-
}
529-
}
530-
531-
#[derive(Default)]
532-
pub struct SyncDroplessArena {
533-
lock: MTLock<DroplessArena>,
534-
}
535-
536-
impl SyncDroplessArena {
537-
#[inline(always)]
538-
pub fn in_arena<T: ?Sized>(&self, ptr: *const T) -> bool {
539-
self.lock.lock().in_arena(ptr)
540-
}
541-
542-
#[inline(always)]
543-
pub fn alloc_raw(&self, bytes: usize, align: usize) -> &mut [u8] {
544-
// Extend the lifetime of the result since it's limited to the lock guard
545-
unsafe { &mut *(self.lock.lock().alloc_raw(bytes, align) as *mut [u8]) }
546-
}
547-
548-
#[inline(always)]
549-
pub fn alloc<T>(&self, object: T) -> &mut T {
550-
// Extend the lifetime of the result since it's limited to the lock guard
551-
unsafe { &mut *(self.lock.lock().alloc(object) as *mut T) }
552-
}
553-
554-
#[inline(always)]
555-
pub fn alloc_slice<T>(&self, slice: &[T]) -> &mut [T]
556-
where
557-
T: Copy,
558-
{
559-
// Extend the lifetime of the result since it's limited to the lock guard
560-
unsafe { &mut *(self.lock.lock().alloc_slice(slice) as *mut [T]) }
561-
}
562-
}
563-
564491
#[cfg(test)]
565492
mod tests;

src/librustc/arena.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ macro_rules! arena_types {
123123
[few] inferred_outlives_crate: rustc::ty::CratePredicatesMap<'tcx>,
124124
[] upvars: rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>,
125125

126+
// Interned types
127+
[] tys: rustc::ty::TyS<$tcx>,
128+
126129
// HIR types
127130
[few] hir_forest: rustc::hir::map::Forest<$tcx>,
128131
[] arm: rustc_hir::Arm<$tcx>,
@@ -176,7 +179,7 @@ macro_rules! declare_arena {
176179
([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => {
177180
#[derive(Default)]
178181
pub struct Arena<$tcx> {
179-
dropless: DroplessArena,
182+
pub dropless: DroplessArena,
180183
drop: DropArena,
181184
$($name: arena_for_type!($a[$ty]),)*
182185
}

src/librustc/ty/context.rs

+26-33
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,9 @@ use rustc_session::config::CrateType;
5151
use rustc_session::config::{BorrowckMode, OutputFilenames};
5252
use rustc_session::Session;
5353

54-
use arena::SyncDroplessArena;
5554
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
5655
use rustc_data_structures::profiling::SelfProfilerRef;
57-
use rustc_data_structures::sharded::ShardedHashMap;
56+
use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
5857
use rustc_data_structures::stable_hasher::{
5958
hash_stable_hashmap, HashStable, StableHasher, StableVec,
6059
};
@@ -83,21 +82,11 @@ use syntax::ast;
8382
use syntax::attr;
8483
use syntax::expand::allocator::AllocatorKind;
8584

86-
pub struct AllArenas {
87-
pub interner: SyncDroplessArena,
88-
}
89-
90-
impl AllArenas {
91-
pub fn new() -> Self {
92-
AllArenas { interner: SyncDroplessArena::default() }
93-
}
94-
}
95-
9685
type InternedSet<'tcx, T> = ShardedHashMap<Interned<'tcx, T>, ()>;
9786

9887
pub struct CtxtInterners<'tcx> {
9988
/// The arena that types, regions, etc. are allocated from.
100-
arena: &'tcx SyncDroplessArena,
89+
arena: &'tcx WorkerLocal<Arena<'tcx>>,
10190

10291
/// Specifically use a speedy hash algorithm for these hash sets, since
10392
/// they're accessed quite often.
@@ -117,7 +106,7 @@ pub struct CtxtInterners<'tcx> {
117106
}
118107

119108
impl<'tcx> CtxtInterners<'tcx> {
120-
fn new(arena: &'tcx SyncDroplessArena) -> CtxtInterners<'tcx> {
109+
fn new(arena: &'tcx WorkerLocal<Arena<'tcx>>) -> CtxtInterners<'tcx> {
121110
CtxtInterners {
122111
arena,
123112
type_: Default::default(),
@@ -1125,7 +1114,6 @@ impl<'tcx> TyCtxt<'tcx> {
11251114
lint_store: Lrc<dyn Any + sync::Send + sync::Sync>,
11261115
local_providers: ty::query::Providers<'tcx>,
11271116
extern_providers: ty::query::Providers<'tcx>,
1128-
arenas: &'tcx AllArenas,
11291117
arena: &'tcx WorkerLocal<Arena<'tcx>>,
11301118
resolutions: ty::ResolverOutputs,
11311119
hir: hir_map::Map<'tcx>,
@@ -1136,7 +1124,7 @@ impl<'tcx> TyCtxt<'tcx> {
11361124
let data_layout = TargetDataLayout::parse(&s.target.target).unwrap_or_else(|err| {
11371125
s.fatal(&err);
11381126
});
1139-
let interners = CtxtInterners::new(&arenas.interner);
1127+
let interners = CtxtInterners::new(arena);
11401128
let common_types = CommonTypes::new(&interners);
11411129
let common_lifetimes = CommonLifetimes::new(&interners);
11421130
let common_consts = CommonConsts::new(&interners, &common_types);
@@ -1567,11 +1555,11 @@ pub trait Lift<'tcx>: fmt::Debug {
15671555
}
15681556

15691557
macro_rules! nop_lift {
1570-
($ty:ty => $lifted:ty) => {
1558+
($set:ident; $ty:ty => $lifted:ty) => {
15711559
impl<'a, 'tcx> Lift<'tcx> for $ty {
15721560
type Lifted = $lifted;
15731561
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
1574-
if tcx.interners.arena.in_arena(*self as *const _) {
1562+
if tcx.interners.$set.contains_pointer_to(&Interned(*self)) {
15751563
Some(unsafe { mem::transmute(*self) })
15761564
} else {
15771565
None
@@ -1582,14 +1570,14 @@ macro_rules! nop_lift {
15821570
}
15831571

15841572
macro_rules! nop_list_lift {
1585-
($ty:ty => $lifted:ty) => {
1573+
($set:ident; $ty:ty => $lifted:ty) => {
15861574
impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> {
15871575
type Lifted = &'tcx List<$lifted>;
15881576
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
15891577
if self.is_empty() {
15901578
return Some(List::empty());
15911579
}
1592-
if tcx.interners.arena.in_arena(*self as *const _) {
1580+
if tcx.interners.$set.contains_pointer_to(&Interned(*self)) {
15931581
Some(unsafe { mem::transmute(*self) })
15941582
} else {
15951583
None
@@ -1599,21 +1587,21 @@ macro_rules! nop_list_lift {
15991587
};
16001588
}
16011589

1602-
nop_lift! {Ty<'a> => Ty<'tcx>}
1603-
nop_lift! {Region<'a> => Region<'tcx>}
1604-
nop_lift! {Goal<'a> => Goal<'tcx>}
1605-
nop_lift! {&'a Const<'a> => &'tcx Const<'tcx>}
1590+
nop_lift! {type_; Ty<'a> => Ty<'tcx>}
1591+
nop_lift! {region; Region<'a> => Region<'tcx>}
1592+
nop_lift! {goal; Goal<'a> => Goal<'tcx>}
1593+
nop_lift! {const_; &'a Const<'a> => &'tcx Const<'tcx>}
16061594

1607-
nop_list_lift! {Goal<'a> => Goal<'tcx>}
1608-
nop_list_lift! {Clause<'a> => Clause<'tcx>}
1609-
nop_list_lift! {Ty<'a> => Ty<'tcx>}
1610-
nop_list_lift! {ExistentialPredicate<'a> => ExistentialPredicate<'tcx>}
1611-
nop_list_lift! {Predicate<'a> => Predicate<'tcx>}
1612-
nop_list_lift! {CanonicalVarInfo => CanonicalVarInfo}
1613-
nop_list_lift! {ProjectionKind => ProjectionKind}
1595+
nop_list_lift! {goal_list; Goal<'a> => Goal<'tcx>}
1596+
nop_list_lift! {clauses; Clause<'a> => Clause<'tcx>}
1597+
nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>}
1598+
nop_list_lift! {existential_predicates; ExistentialPredicate<'a> => ExistentialPredicate<'tcx>}
1599+
nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>}
1600+
nop_list_lift! {canonical_var_infos; CanonicalVarInfo => CanonicalVarInfo}
1601+
nop_list_lift! {projs; ProjectionKind => ProjectionKind}
16141602

16151603
// This is the impl for `&'a InternalSubsts<'a>`.
1616-
nop_list_lift! {GenericArg<'a> => GenericArg<'tcx>}
1604+
nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>}
16171605

16181606
pub mod tls {
16191607
use super::{ptr_eq, GlobalCtxt, TyCtxt};
@@ -1937,6 +1925,11 @@ impl<'tcx, T: 'tcx + ?Sized> Clone for Interned<'tcx, T> {
19371925
}
19381926
impl<'tcx, T: 'tcx + ?Sized> Copy for Interned<'tcx, T> {}
19391927

1928+
impl<'tcx, T: 'tcx + ?Sized> IntoPointer for Interned<'tcx, T> {
1929+
fn into_pointer(&self) -> *const () {
1930+
self.0 as *const _ as *const ()
1931+
}
1932+
}
19401933
// N.B., an `Interned<Ty>` compares and hashes as a `TyKind`.
19411934
impl<'tcx> PartialEq for Interned<'tcx, TyS<'tcx>> {
19421935
fn eq(&self, other: &Interned<'tcx, TyS<'tcx>>) -> bool {
@@ -2089,7 +2082,7 @@ macro_rules! slice_interners {
20892082
$(impl<'tcx> TyCtxt<'tcx> {
20902083
pub fn $method(self, v: &[$ty]) -> &'tcx List<$ty> {
20912084
self.interners.$field.intern_ref(v, || {
2092-
Interned(List::from_arena(&self.interners.arena, v))
2085+
Interned(List::from_arena(&*self.arena, v))
20932086
}).0
20942087
}
20952088
})+

src/librustc/ty/mod.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pub use self::BorrowKind::*;
66
pub use self::IntVarValue::*;
77
pub use self::Variance::*;
88

9+
use crate::arena::Arena;
910
use crate::hir::exports::ExportMap;
1011
use crate::hir::map as hir_map;
1112

@@ -25,7 +26,6 @@ use crate::ty::layout::VariantIdx;
2526
use crate::ty::subst::{InternalSubsts, Subst, SubstsRef};
2627
use crate::ty::util::{Discr, IntTypeExt};
2728
use crate::ty::walk::TypeWalker;
28-
use arena::SyncDroplessArena;
2929
use rustc_data_structures::captures::Captures;
3030
use rustc_data_structures::fx::FxHashMap;
3131
use rustc_data_structures::fx::FxIndexMap;
@@ -74,7 +74,7 @@ pub use crate::ty::diagnostics::*;
7474
pub use self::binding::BindingMode;
7575
pub use self::binding::BindingMode::*;
7676

77-
pub use self::context::{keep_local, tls, AllArenas, FreeRegionInfo, TyCtxt};
77+
pub use self::context::{keep_local, tls, FreeRegionInfo, TyCtxt};
7878
pub use self::context::{
7979
CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, ResolvedOpaqueTy,
8080
UserType, UserTypeAnnotationIndex,
@@ -604,7 +604,7 @@ unsafe impl<T: Sync> Sync for List<T> {}
604604

605605
impl<T: Copy> List<T> {
606606
#[inline]
607-
fn from_arena<'tcx>(arena: &'tcx SyncDroplessArena, slice: &[T]) -> &'tcx List<T> {
607+
fn from_arena<'tcx>(arena: &'tcx Arena<'tcx>, slice: &[T]) -> &'tcx List<T> {
608608
assert!(!mem::needs_drop::<T>());
609609
assert!(mem::size_of::<T>() != 0);
610610
assert!(slice.len() != 0);
@@ -617,7 +617,9 @@ impl<T: Copy> List<T> {
617617

618618
let size = offset + slice.len() * mem::size_of::<T>();
619619

620-
let mem = arena.alloc_raw(size, cmp::max(mem::align_of::<T>(), mem::align_of::<usize>()));
620+
let mem = arena
621+
.dropless
622+
.alloc_raw(size, cmp::max(mem::align_of::<T>(), mem::align_of::<usize>()));
621623
unsafe {
622624
let result = &mut *(mem.as_mut_ptr() as *mut List<T>);
623625
// Write the length

src/librustc_data_structures/sharded.rs

+14
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,20 @@ impl<K: Eq + Hash + Copy> ShardedHashMap<K, ()> {
137137
}
138138
}
139139

140+
pub trait IntoPointer {
141+
/// Returns a pointer which outlives `self`.
142+
fn into_pointer(&self) -> *const ();
143+
}
144+
145+
impl<K: Eq + Hash + Copy + IntoPointer> ShardedHashMap<K, ()> {
146+
pub fn contains_pointer_to<T: Hash + IntoPointer>(&self, value: &T) -> bool {
147+
let hash = make_hash(&value);
148+
let shard = self.get_shard_by_hash(hash).lock();
149+
let value = value.into_pointer();
150+
shard.raw_entry().from_hash(hash, |entry| entry.into_pointer() == value).is_some()
151+
}
152+
}
153+
140154
#[inline]
141155
fn make_hash<K: Hash + ?Sized>(val: &K) -> u64 {
142156
let mut state = FxHasher::default();

src/librustc_interface/passes.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc::session::search_paths::PathKind;
1515
use rustc::session::Session;
1616
use rustc::traits;
1717
use rustc::ty::steal::Steal;
18-
use rustc::ty::{self, AllArenas, GlobalCtxt, ResolverOutputs, TyCtxt};
18+
use rustc::ty::{self, GlobalCtxt, ResolverOutputs, TyCtxt};
1919
use rustc::util::common::ErrorReported;
2020
use rustc_builtin_macros;
2121
use rustc_codegen_ssa::back::link::emit_metadata;
@@ -715,7 +715,6 @@ pub fn create_global_ctxt<'tcx>(
715715
outputs: OutputFilenames,
716716
crate_name: &str,
717717
global_ctxt: &'tcx Once<GlobalCtxt<'tcx>>,
718-
all_arenas: &'tcx AllArenas,
719718
arena: &'tcx WorkerLocal<Arena<'tcx>>,
720719
) -> QueryContext<'tcx> {
721720
let sess = &compiler.session();
@@ -746,7 +745,6 @@ pub fn create_global_ctxt<'tcx>(
746745
lint_store,
747746
local_providers,
748747
extern_providers,
749-
&all_arenas,
750748
arena,
751749
resolver_outputs,
752750
hir_map,

src/librustc_interface/queries.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc::hir::map;
77
use rustc::session::config::{OutputFilenames, OutputType};
88
use rustc::session::Session;
99
use rustc::ty::steal::Steal;
10-
use rustc::ty::{AllArenas, GlobalCtxt, ResolverOutputs};
10+
use rustc::ty::{GlobalCtxt, ResolverOutputs};
1111
use rustc::util::common::ErrorReported;
1212
use rustc_codegen_utils::codegen_backend::CodegenBackend;
1313
use rustc_data_structures::sync::{Lrc, Once, WorkerLocal};
@@ -66,7 +66,6 @@ pub struct Queries<'tcx> {
6666
compiler: &'tcx Compiler,
6767
gcx: Once<GlobalCtxt<'tcx>>,
6868

69-
all_arenas: AllArenas,
7069
arena: WorkerLocal<Arena<'tcx>>,
7170

7271
dep_graph_future: Query<Option<DepGraphFuture>>,
@@ -86,7 +85,6 @@ impl<'tcx> Queries<'tcx> {
8685
Queries {
8786
compiler,
8887
gcx: Once::new(),
89-
all_arenas: AllArenas::new(),
9088
arena: WorkerLocal::new(|_| Arena::default()),
9189
dep_graph_future: Default::default(),
9290
parse: Default::default(),
@@ -265,7 +263,6 @@ impl<'tcx> Queries<'tcx> {
265263
outputs,
266264
&crate_name,
267265
&self.gcx,
268-
&self.all_arenas,
269266
&self.arena,
270267
))
271268
})

0 commit comments

Comments
 (0)