Skip to content

Commit 3ee5405

Browse files
committed
wip
1 parent 235ea68 commit 3ee5405

File tree

2 files changed

+80
-79
lines changed

2 files changed

+80
-79
lines changed

src/librustc/ty/context.rs

+39-72
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ impl<'tcx> GlobalArenas<'tcx> {
125125
}
126126
}
127127

128-
type InternedSet<'tcx, T> = Lock<FxHashSet<Interned<'tcx, T>>>;
128+
type InternedSet<'tcx, T> = Lock<FxInterner<Interned<'tcx, T>>>;
129129

130130
pub struct CtxtInterners<'tcx> {
131131
/// The arena that types, regions, etc are allocated from
@@ -789,12 +789,9 @@ impl<'tcx> CommonTypes<'tcx> {
789789

790790
let mk = |sty| CtxtInterners::intern_ty(interners, interners, sty);
791791
let mk_region = |r| {
792-
if let Some(r) = interners.region.borrow().get(&r) {
793-
return r.0;
794-
}
795-
let r = interners.arena.alloc(r);
796-
interners.region.borrow_mut().insert(Interned(r));
797-
&*r
792+
interners.region.borrow_mut().intern(r, |r| {
793+
Interned(interners.arena.alloc(r))
794+
}).0
798795
};
799796
CommonTypes {
800797
bool: mk(TyBool),
@@ -905,14 +902,14 @@ pub struct GlobalCtxt<'tcx> {
905902
/// Data layout specification for the current target.
906903
pub data_layout: TargetDataLayout,
907904

908-
stability_interner: Lock<FxHashSet<&'tcx attr::Stability>>,
905+
stability_interner: Lock<FxInterner<&'tcx attr::Stability>>,
909906

910907
/// Stores the value of constants (and deduplicates the actual memory)
911908
allocation_interner: Lock<FxHashSet<&'tcx Allocation>>,
912909

913910
pub alloc_map: Lock<interpret::AllocMap<'tcx, &'tcx Allocation>>,
914911

915-
layout_interner: Lock<FxHashSet<&'tcx LayoutDetails>>,
912+
layout_interner: Lock<FxInterner<&'tcx LayoutDetails>>,
916913

917914
/// A general purpose channel to throw data out the back towards LLVM worker
918915
/// threads.
@@ -995,16 +992,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
995992
self,
996993
alloc: Allocation,
997994
) -> &'gcx Allocation {
998-
let allocs = &mut self.allocation_interner.borrow_mut();
999-
if let Some(alloc) = allocs.get(&alloc) {
1000-
return alloc;
1001-
}
1002-
1003-
let interned = self.global_arenas.const_allocs.alloc(alloc);
1004-
if let Some(prev) = allocs.replace(interned) {
1005-
bug!("Tried to overwrite interned Allocation: {:#?}", prev)
1006-
}
1007-
interned
995+
self.allocation_interner.borrow_mut().intern(alloc, |alloc| {
996+
self.global_arenas.const_allocs.alloc(alloc)
997+
})
1008998
}
1009999

10101000
/// Allocates a byte or string literal for `mir::interpret`
@@ -1016,29 +1006,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
10161006
}
10171007

10181008
pub fn intern_stability(self, stab: attr::Stability) -> &'gcx attr::Stability {
1019-
let mut stability_interner = self.stability_interner.borrow_mut();
1020-
if let Some(st) = stability_interner.get(&stab) {
1021-
return st;
1022-
}
1023-
1024-
let interned = self.global_interners.arena.alloc(stab);
1025-
if let Some(prev) = stability_interner.replace(interned) {
1026-
bug!("Tried to overwrite interned Stability: {:?}", prev)
1027-
}
1028-
interned
1009+
self.stability_interner.borrow_mut().intern(stab, |stab| {
1010+
self.global_interners.arena.alloc(stab)
1011+
})
10291012
}
10301013

10311014
pub fn intern_layout(self, layout: LayoutDetails) -> &'gcx LayoutDetails {
1032-
let mut layout_interner = self.layout_interner.borrow_mut();
1033-
if let Some(layout) = layout_interner.get(&layout) {
1034-
return layout;
1035-
}
1036-
1037-
let interned = self.global_arenas.layout.alloc(layout);
1038-
if let Some(prev) = layout_interner.replace(interned) {
1039-
bug!("Tried to overwrite interned Layout: {:?}", prev)
1040-
}
1041-
interned
1015+
self.layout_interner.borrow_mut().intern(layout, |layout| {
1016+
self.global_arenas.layout.alloc(layout)
1017+
})
10421018
}
10431019

10441020
pub fn lift<T: ?Sized + Lift<'tcx>>(self, value: &T) -> Option<T::Lifted> {
@@ -1160,8 +1136,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
11601136
evaluation_cache: traits::EvaluationCache::new(),
11611137
crate_name: Symbol::intern(crate_name),
11621138
data_layout,
1163-
layout_interner: Lock::new(FxHashSet()),
1164-
stability_interner: Lock::new(FxHashSet()),
1139+
layout_interner: Default::default(),
1140+
stability_interner: Default::default(),
11651141
allocation_interner: Lock::new(FxHashSet()),
11661142
alloc_map: Lock::new(interpret::AllocMap::new()),
11671143
tx_to_llvm_workers: Lock::new(tx),
@@ -1898,7 +1874,7 @@ macro_rules! sty_debug_print {
18981874
($ctxt: expr, $($variant: ident),*) => {{
18991875
// curious inner module to allow variant names to be used as
19001876
// variable names.
1901-
#[allow(non_snake_case)]
1877+
#[allow(non_snake_case, warnings)]
19021878
mod inner {
19031879
use ty::{self, TyCtxt};
19041880
use ty::context::Interned;
@@ -2085,37 +2061,28 @@ macro_rules! intern_method {
20852061
// determine that all contents are in the global tcx.
20862062
// See comments on Lift for why we can't use that.
20872063
if ($keep_in_local_tcx)(&v) {
2088-
let mut interner = self.interners.$name.borrow_mut();
2089-
if let Some(&Interned(v)) = interner.get(key) {
2090-
return v;
2091-
}
2092-
2093-
// Make sure we don't end up with inference
2094-
// types/regions in the global tcx.
2095-
if self.is_global() {
2096-
bug!("Attempted to intern `{:?}` which contains \
2097-
inference types/regions in the global type context",
2098-
v);
2099-
}
2100-
2101-
let i = $alloc_method(&self.interners.arena, v);
2102-
interner.insert(Interned(i));
2103-
i
2064+
self.interners.$name.borrow_mut().intern_ref(key, || {
2065+
// Make sure we don't end up with inference
2066+
// types/regions in the global tcx.
2067+
if self.is_global() {
2068+
bug!("Attempted to intern `{:?}` which contains \
2069+
inference types/regions in the global type context",
2070+
v);
2071+
}
2072+
2073+
Interned($alloc_method(&self.interners.arena, v))
2074+
}).0
21042075
} else {
2105-
let mut interner = self.global_interners.$name.borrow_mut();
2106-
if let Some(&Interned(v)) = interner.get(key) {
2107-
return v;
2108-
}
2109-
2110-
// This transmutes $alloc<'tcx> to $alloc<'gcx>
2111-
let v = unsafe {
2112-
mem::transmute(v)
2113-
};
2114-
let i: &$lt_tcx $ty = $alloc_method(&self.global_interners.arena, v);
2115-
// Cast to 'gcx
2116-
let i = unsafe { mem::transmute(i) };
2117-
interner.insert(Interned(i));
2118-
i
2076+
self.global_interners.$name.borrow_mut().intern_ref(key, || {
2077+
// This transmutes $alloc<'tcx> to $alloc<'gcx>
2078+
let v = unsafe {
2079+
mem::transmute(v)
2080+
};
2081+
let i: &$lt_tcx $ty = $alloc_method(&self.global_interners.arena, v);
2082+
// Cast to 'gcx
2083+
let i = unsafe { mem::transmute(i) };
2084+
Interned(i)
2085+
}).0
21192086
}
21202087
}
21212088
}

src/librustc_data_structures/interner.rs

+41-7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
111
use std::marker::PhantomData;
212
use std::hash::Hash;
313
use std::hash::Hasher;
@@ -7,6 +17,7 @@ use std::ptr::{Unique, NonNull};
717
use std::alloc::{Global, Alloc};
818
use std::collections::hash_map::RandomState;
919
use std::borrow::Borrow;
20+
use std::fmt;
1021

1122
const ENTRIES_PER_GROUP: usize = 5;
1223

@@ -88,7 +99,7 @@ impl Drop for Table {
8899
}
89100

90101
impl Table {
91-
unsafe fn new_uninitialized(group_count: usize) -> Table {
102+
fn new(group_count: usize) -> Table {
92103
assert!(size_of::<Group>() == 64);
93104
let groups: NonNull<Group> = Global.alloc_array(group_count).unwrap();
94105
let capacity2 = group_count * ENTRIES_PER_GROUP;
@@ -110,7 +121,7 @@ impl Table {
110121
group_mask: group_count.wrapping_sub(1),
111122
size: 0,
112123
capacity,
113-
groups: Unique::new_unchecked(groups.as_ptr()),
124+
groups: unsafe { Unique::new_unchecked(groups.as_ptr()) },
114125
}
115126
}
116127

@@ -126,7 +137,7 @@ impl Table {
126137
let group = unsafe {
127138
&(*group_ptr)
128139
};
129-
match unsafe { group.search_for_empty() } {
140+
match group.search_for_empty() {
130141
Some(pos) => return RawEntry {
131142
group: group_ptr,
132143
pos,
@@ -150,7 +161,7 @@ impl Table {
150161
let group = unsafe {
151162
&(*group_ptr)
152163
};
153-
let r = unsafe { group.search_with(&mut eq, hash as u32) } ;
164+
let r = group.search_with(&mut eq, hash as u32);
154165
match r {
155166
Some((pos, empty)) => return RawEntry {
156167
group: group_ptr,
@@ -182,6 +193,12 @@ pub struct Interner<K: Eq + Hash, S = RandomState> {
182193
marker: PhantomData<K>,
183194
}
184195

196+
impl<K: Eq + Hash, S> fmt::Debug for Interner<K, S> {
197+
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
198+
"Interner".fmt(f)
199+
}
200+
}
201+
185202
impl<K: Eq + Hash, S: Default> Default for Interner<K, S> {
186203
fn default() -> Self {
187204
assert!(size_of::<K>() == 8);
@@ -211,9 +228,7 @@ impl<K: Eq + Hash, S: BuildHasher> Interner<K, S> {
211228
#[inline(never)]
212229
#[cold]
213230
fn expand(&mut self) {
214-
let mut new_table = unsafe {
215-
Table::new_uninitialized((self.table.group_mask + 1) << 1)
216-
};
231+
let mut new_table = Table::new((self.table.group_mask + 1) << 1);
217232
new_table.size = self.table.size;
218233
self.table.iter(|h, v| {
219234
let spot = new_table.search_for_empty(h as u64);
@@ -236,6 +251,25 @@ impl<K: Eq + Hash, S: BuildHasher> Interner<K, S> {
236251
self.table.size
237252
}
238253

254+
#[inline]
255+
pub fn intern_ref<Q: ?Sized, F: FnOnce() -> K>(&mut self, value: &Q, make: F) -> &K
256+
where K: Borrow<Q>,
257+
Q: Hash + Eq
258+
{
259+
self.incr();
260+
let hash = make_hash(&self.hash_builder, value);
261+
let spot = self.table.search_with::<K, _>(|k| value.eq(k.borrow()), hash);
262+
unsafe {
263+
if spot.empty {
264+
self.table.size += 1;
265+
(*spot.group).size += 1;
266+
let key = make();
267+
(*spot.group).set(spot.pos, hash as u32, *(&key as *const _ as *const u64));
268+
}
269+
&*((*spot.group).values.get_unchecked(spot.pos) as *const _ as *const K)
270+
}
271+
}
272+
239273
#[inline]
240274
pub fn intern<Q, F: FnOnce(Q) -> K>(&mut self, value: Q, make: F) -> &K
241275
where K: Borrow<Q>,

0 commit comments

Comments
 (0)