Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ddc5418

Browse files
committedMay 22, 2018
Introduce AllocType which indicates what AllocIds point to
1 parent 9016750 commit ddc5418

File tree

11 files changed

+251
-284
lines changed

11 files changed

+251
-284
lines changed
 

‎src/librustc/ich/impls_ty.rs

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -420,17 +420,6 @@ impl_stable_hash_for!(struct mir::interpret::MemoryPointer {
420420
offset
421421
});
422422

423-
enum AllocDiscriminant {
424-
Alloc,
425-
Static,
426-
Function,
427-
}
428-
impl_stable_hash_for!(enum self::AllocDiscriminant {
429-
Alloc,
430-
Static,
431-
Function
432-
});
433-
434423
impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
435424
fn hash_stable<W: StableHasherResult>(
436425
&self,
@@ -440,30 +429,29 @@ impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
440429
ty::tls::with_opt(|tcx| {
441430
trace!("hashing {:?}", *self);
442431
let tcx = tcx.expect("can't hash AllocIds during hir lowering");
443-
if let Some(def_id) = tcx.interpret_interner.get_static(*self) {
444-
AllocDiscriminant::Static.hash_stable(hcx, hasher);
445-
trace!("hashing {:?} as static {:?}", *self, def_id);
446-
def_id.hash_stable(hcx, hasher);
447-
} else if let Some(alloc) = tcx.interpret_interner.get_alloc(*self) {
448-
AllocDiscriminant::Alloc.hash_stable(hcx, hasher);
449-
if hcx.alloc_id_recursion_tracker.insert(*self) {
450-
trace!("hashing {:?} as alloc {:#?}", *self, alloc);
451-
alloc.hash_stable(hcx, hasher);
452-
assert!(hcx.alloc_id_recursion_tracker.remove(self));
453-
} else {
454-
trace!("skipping hashing of {:?} due to recursion", *self);
455-
}
456-
} else if let Some(inst) = tcx.interpret_interner.get_fn(*self) {
457-
trace!("hashing {:?} as fn {:#?}", *self, inst);
458-
AllocDiscriminant::Function.hash_stable(hcx, hasher);
459-
inst.hash_stable(hcx, hasher);
460-
} else {
461-
bug!("no allocation for {}", self);
462-
}
432+
let alloc_kind = tcx.alloc_map.lock().get(*self).expect("no value for AllocId");
433+
alloc_kind.hash_stable(hcx, hasher);
463434
});
464435
}
465436
}
466437

438+
impl<'a, 'gcx, M: HashStable<StableHashingContext<'a>>> HashStable<StableHashingContext<'a>>
439+
for mir::interpret::AllocType<'gcx, M> {
440+
fn hash_stable<W: StableHasherResult>(&self,
441+
hcx: &mut StableHashingContext<'a>,
442+
hasher: &mut StableHasher<W>) {
443+
use mir::interpret::AllocType::*;
444+
445+
mem::discriminant(self).hash_stable(hcx, hasher);
446+
447+
match *self {
448+
Function(instance) => instance.hash_stable(hcx, hasher),
449+
Static(def_id) => def_id.hash_stable(hcx, hasher),
450+
Memory(ref mem) => mem.hash_stable(hcx, hasher),
451+
}
452+
}
453+
}
454+
467455
impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::Allocation {
468456
fn hash_stable<W: StableHasherResult>(
469457
&self,

‎src/librustc/mir/interpret/mod.rs

Lines changed: 119 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@ use std::collections::BTreeMap;
1616
use std::fmt;
1717
use mir;
1818
use hir::def_id::DefId;
19-
use ty::{self, TyCtxt};
19+
use ty::{self, TyCtxt, Instance};
2020
use ty::layout::{self, Align, HasDataLayout, Size};
2121
use middle::region;
2222
use std::iter;
2323
use std::io;
24+
use std::hash::Hash;
2425
use syntax::ast::Mutability;
2526
use rustc_serialize::{Encoder, Decoder, Decodable, Encodable};
27+
use rustc_data_structures::fx::FxHashMap;
2628
use byteorder::{WriteBytesExt, ReadBytesExt, LittleEndian, BigEndian};
2729

2830
#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
@@ -150,7 +152,7 @@ impl<'tcx> MemoryPointer {
150152
}
151153

152154

153-
#[derive(Copy, Clone, Default, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)]
155+
#[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)]
154156
pub struct AllocId(pub u64);
155157

156158
impl ::rustc_serialize::UseSpecializedEncodable for AllocId {}
@@ -171,20 +173,25 @@ pub fn specialized_encode_alloc_id<
171173
tcx: TyCtxt<'a, 'tcx, 'tcx>,
172174
alloc_id: AllocId,
173175
) -> Result<(), E::Error> {
174-
if let Some(alloc) = tcx.interpret_interner.get_alloc(alloc_id) {
175-
trace!("encoding {:?} with {:#?}", alloc_id, alloc);
176-
AllocKind::Alloc.encode(encoder)?;
177-
alloc.encode(encoder)?;
178-
} else if let Some(fn_instance) = tcx.interpret_interner.get_fn(alloc_id) {
179-
trace!("encoding {:?} with {:#?}", alloc_id, fn_instance);
180-
AllocKind::Fn.encode(encoder)?;
181-
fn_instance.encode(encoder)?;
182-
} else if let Some(did) = tcx.interpret_interner.get_static(alloc_id) {
183-
// referring to statics doesn't need to know about their allocations, just about its DefId
184-
AllocKind::Static.encode(encoder)?;
185-
did.encode(encoder)?;
186-
} else {
187-
bug!("alloc id without corresponding allocation: {}", alloc_id);
176+
let alloc_type: AllocType<'tcx, &'tcx Allocation> =
177+
tcx.alloc_map.lock().get(alloc_id).expect("no value for AllocId");
178+
match alloc_type {
179+
AllocType::Memory(alloc) => {
180+
trace!("encoding {:?} with {:#?}", alloc_id, alloc);
181+
AllocKind::Alloc.encode(encoder)?;
182+
alloc.encode(encoder)?;
183+
}
184+
AllocType::Function(fn_instance) => {
185+
trace!("encoding {:?} with {:#?}", alloc_id, fn_instance);
186+
AllocKind::Fn.encode(encoder)?;
187+
fn_instance.encode(encoder)?;
188+
}
189+
AllocType::Static(did) => {
190+
// referring to statics doesn't need to know about their allocations,
191+
// just about its DefId
192+
AllocKind::Static.encode(encoder)?;
193+
did.encode(encoder)?;
194+
}
188195
}
189196
Ok(())
190197
}
@@ -200,31 +207,30 @@ pub fn specialized_decode_alloc_id<
200207
) -> Result<AllocId, D::Error> {
201208
match AllocKind::decode(decoder)? {
202209
AllocKind::Alloc => {
203-
let alloc_id = tcx.interpret_interner.reserve();
210+
let alloc_id = tcx.alloc_map.lock().reserve();
204211
trace!("creating alloc id {:?}", alloc_id);
205212
// insert early to allow recursive allocs
206213
cache(decoder, alloc_id);
207214

208-
let allocation = Allocation::decode(decoder)?;
215+
let allocation = <&'tcx Allocation as Decodable>::decode(decoder)?;
209216
trace!("decoded alloc {:?} {:#?}", alloc_id, allocation);
210-
let allocation = tcx.intern_const_alloc(allocation);
211-
tcx.interpret_interner.intern_at_reserved(alloc_id, allocation);
217+
tcx.alloc_map.lock().set_id_memory(alloc_id, allocation);
212218

213219
Ok(alloc_id)
214220
},
215221
AllocKind::Fn => {
216222
trace!("creating fn alloc id");
217223
let instance = ty::Instance::decode(decoder)?;
218224
trace!("decoded fn alloc instance: {:?}", instance);
219-
let id = tcx.interpret_interner.create_fn_alloc(instance);
225+
let id = tcx.alloc_map.lock().create_fn_alloc(instance);
220226
trace!("created fn alloc id: {:?}", id);
221227
cache(decoder, id);
222228
Ok(id)
223229
},
224230
AllocKind::Static => {
225231
trace!("creating extern static alloc id at");
226232
let did = DefId::decode(decoder)?;
227-
let alloc_id = tcx.interpret_interner.cache_static(did);
233+
let alloc_id = tcx.alloc_map.lock().intern_static(did);
228234
cache(decoder, alloc_id);
229235
Ok(alloc_id)
230236
},
@@ -237,6 +243,97 @@ impl fmt::Display for AllocId {
237243
}
238244
}
239245

246+
#[derive(Debug, Clone, Eq, PartialEq, Hash, RustcDecodable, RustcEncodable)]
247+
pub enum AllocType<'tcx, M> {
248+
/// The alloc id is used as a function pointer
249+
Function(Instance<'tcx>),
250+
/// The alloc id points to a static variable
251+
Static(DefId),
252+
/// The alloc id points to memory
253+
Memory(M)
254+
}
255+
256+
pub struct AllocMap<'tcx, M> {
257+
/// Lets you know what an AllocId refers to
258+
id_to_type: FxHashMap<AllocId, AllocType<'tcx, M>>,
259+
260+
/// Used to ensure that functions and statics only get one associated AllocId
261+
type_interner: FxHashMap<AllocType<'tcx, M>, AllocId>,
262+
263+
/// The AllocId to assign to the next requested id.
264+
/// Always incremented, never gets smaller.
265+
next_id: AllocId,
266+
}
267+
268+
impl<'tcx, M: fmt::Debug + Eq + Hash + Clone> AllocMap<'tcx, M> {
269+
pub fn new() -> Self {
270+
AllocMap {
271+
id_to_type: FxHashMap(),
272+
type_interner: FxHashMap(),
273+
next_id: AllocId(0),
274+
}
275+
}
276+
277+
/// obtains a new allocation ID that can be referenced but does not
278+
/// yet have an allocation backing it.
279+
pub fn reserve(
280+
&mut self,
281+
) -> AllocId {
282+
let next = self.next_id;
283+
self.next_id.0 = self.next_id.0
284+
.checked_add(1)
285+
.expect("You overflowed a u64 by incrementing by 1... \
286+
You've just earned yourself a free drink if we ever meet. \
287+
Seriously, how did you do that?!");
288+
next
289+
}
290+
291+
fn intern(&mut self, alloc_type: AllocType<'tcx, M>) -> AllocId {
292+
if let Some(&alloc_id) = self.type_interner.get(&alloc_type) {
293+
return alloc_id;
294+
}
295+
let id = self.reserve();
296+
debug!("creating alloc_type {:?} with id {}", alloc_type, id);
297+
self.id_to_type.insert(id, alloc_type.clone());
298+
self.type_interner.insert(alloc_type, id);
299+
id
300+
}
301+
302+
// FIXME: Check if functions have identity. If not, we should not intern these,
303+
// but instead create a new id per use.
304+
// Alternatively we could just make comparing function pointers an error.
305+
pub fn create_fn_alloc(&mut self, instance: Instance<'tcx>) -> AllocId {
306+
self.intern(AllocType::Function(instance))
307+
}
308+
309+
pub fn get(&self, id: AllocId) -> Option<AllocType<'tcx, M>> {
310+
self.id_to_type.get(&id).cloned()
311+
}
312+
313+
pub fn unwrap_memory(&self, id: AllocId) -> M {
314+
match self.get(id) {
315+
Some(AllocType::Memory(mem)) => mem,
316+
_ => bug!("expected allocation id {} to point to memory", id),
317+
}
318+
}
319+
320+
pub fn intern_static(&mut self, static_id: DefId) -> AllocId {
321+
self.intern(AllocType::Static(static_id))
322+
}
323+
324+
pub fn allocate(&mut self, mem: M) -> AllocId {
325+
let id = self.reserve();
326+
self.set_id_memory(id, mem);
327+
id
328+
}
329+
330+
pub fn set_id_memory(&mut self, id: AllocId, mem: M) {
331+
if let Some(old) = self.id_to_type.insert(id, AllocType::Memory(mem)) {
332+
bug!("tried to set allocation id {}, but it was already existing as {:#?}", id, old);
333+
}
334+
}
335+
}
336+
240337
#[derive(Clone, Debug, Eq, PartialEq, Hash, RustcEncodable, RustcDecodable)]
241338
pub struct Allocation {
242339
/// The actual bytes of the allocation.

‎src/librustc/mir/mod.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,17 +1908,15 @@ pub fn print_miri_value<W: Write>(value: Value, ty: Ty, f: &mut W) -> fmt::Resul
19081908
(Value::ByValPair(PrimVal::Ptr(ptr), PrimVal::Bytes(len)),
19091909
&TyRef(_, &ty::TyS { sty: TyStr, .. }, _)) => {
19101910
ty::tls::with(|tcx| {
1911-
let alloc = tcx
1912-
.interpret_interner
1913-
.get_alloc(ptr.alloc_id);
1914-
if let Some(alloc) = alloc {
1915-
assert_eq!(len as usize as u128, len);
1916-
let slice = &alloc.bytes[(ptr.offset.bytes() as usize)..][..(len as usize)];
1917-
let s = ::std::str::from_utf8(slice)
1918-
.expect("non utf8 str from miri");
1919-
write!(f, "{:?}", s)
1920-
} else {
1921-
write!(f, "pointer to erroneous constant {:?}, {:?}", ptr, len)
1911+
match tcx.alloc_map.lock().get(ptr.alloc_id) {
1912+
Some(interpret::AllocType::Memory(alloc)) => {
1913+
assert_eq!(len as usize as u128, len);
1914+
let slice = &alloc.bytes[(ptr.offset.bytes() as usize)..][..(len as usize)];
1915+
let s = ::std::str::from_utf8(slice)
1916+
.expect("non utf8 str from miri");
1917+
write!(f, "{:?}", s)
1918+
}
1919+
_ => write!(f, "pointer to erroneous constant {:?}, {:?}", ptr, len),
19221920
}
19231921
})
19241922
},

‎src/librustc/ty/context.rs

Lines changed: 3 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ use mir::{self, Mir, interpret};
3535
use mir::interpret::Allocation;
3636
use ty::subst::{Kind, Substs, Subst};
3737
use ty::ReprOptions;
38-
use ty::Instance;
3938
use traits;
4039
use traits::{Clause, Clauses, Goal, Goals};
4140
use ty::{self, Ty, TypeAndMut};
@@ -918,7 +917,7 @@ pub struct GlobalCtxt<'tcx> {
918917
/// Stores the value of constants (and deduplicates the actual memory)
919918
allocation_interner: Lock<FxHashSet<&'tcx Allocation>>,
920919

921-
pub interpret_interner: InterpretInterner<'tcx>,
920+
pub alloc_map: Lock<interpret::AllocMap<'tcx, &'tcx Allocation>>,
922921

923922
layout_interner: Lock<FxHashSet<&'tcx LayoutDetails>>,
924923

@@ -933,110 +932,6 @@ pub struct GlobalCtxt<'tcx> {
933932
output_filenames: Arc<OutputFilenames>,
934933
}
935934

936-
/// Everything needed to efficiently work with interned allocations
937-
#[derive(Debug, Default)]
938-
pub struct InterpretInterner<'tcx> {
939-
inner: Lock<InterpretInternerInner<'tcx>>,
940-
}
941-
942-
#[derive(Debug, Default)]
943-
struct InterpretInternerInner<'tcx> {
944-
/// Allows obtaining function instance handles via a unique identifier
945-
functions: FxHashMap<interpret::AllocId, Instance<'tcx>>,
946-
947-
/// Inverse map of `interpret_functions`.
948-
/// Used so we don't allocate a new pointer every time we need one
949-
function_cache: FxHashMap<Instance<'tcx>, interpret::AllocId>,
950-
951-
/// Allows obtaining const allocs via a unique identifier
952-
alloc_by_id: FxHashMap<interpret::AllocId, &'tcx interpret::Allocation>,
953-
954-
/// Allows obtaining static def ids via a unique id
955-
statics: FxHashMap<interpret::AllocId, DefId>,
956-
957-
/// The AllocId to assign to the next new regular allocation.
958-
/// Always incremented, never gets smaller.
959-
next_id: interpret::AllocId,
960-
961-
/// Inverse map of `statics`
962-
/// Used so we don't allocate a new pointer every time we need one
963-
static_cache: FxHashMap<DefId, interpret::AllocId>,
964-
}
965-
966-
impl<'tcx> InterpretInterner<'tcx> {
967-
pub fn create_fn_alloc(&self, instance: Instance<'tcx>) -> interpret::AllocId {
968-
if let Some(&alloc_id) = self.inner.borrow().function_cache.get(&instance) {
969-
return alloc_id;
970-
}
971-
let id = self.reserve();
972-
debug!("creating fn ptr: {}", id);
973-
let mut inner = self.inner.borrow_mut();
974-
inner.functions.insert(id, instance);
975-
inner.function_cache.insert(instance, id);
976-
id
977-
}
978-
979-
pub fn get_fn(
980-
&self,
981-
id: interpret::AllocId,
982-
) -> Option<Instance<'tcx>> {
983-
self.inner.borrow().functions.get(&id).cloned()
984-
}
985-
986-
pub fn get_alloc(
987-
&self,
988-
id: interpret::AllocId,
989-
) -> Option<&'tcx interpret::Allocation> {
990-
self.inner.borrow().alloc_by_id.get(&id).cloned()
991-
}
992-
993-
pub fn cache_static(
994-
&self,
995-
static_id: DefId,
996-
) -> interpret::AllocId {
997-
if let Some(alloc_id) = self.inner.borrow().static_cache.get(&static_id).cloned() {
998-
return alloc_id;
999-
}
1000-
let alloc_id = self.reserve();
1001-
let mut inner = self.inner.borrow_mut();
1002-
inner.static_cache.insert(static_id, alloc_id);
1003-
inner.statics.insert(alloc_id, static_id);
1004-
alloc_id
1005-
}
1006-
1007-
pub fn get_static(
1008-
&self,
1009-
ptr: interpret::AllocId,
1010-
) -> Option<DefId> {
1011-
self.inner.borrow().statics.get(&ptr).cloned()
1012-
}
1013-
1014-
pub fn intern_at_reserved(
1015-
&self,
1016-
id: interpret::AllocId,
1017-
alloc: &'tcx interpret::Allocation,
1018-
) {
1019-
if let Some(old) = self.inner.borrow_mut().alloc_by_id.insert(id, alloc) {
1020-
bug!("tried to intern allocation at {}, but was already existing as {:#?}", id, old);
1021-
}
1022-
}
1023-
1024-
/// obtains a new allocation ID that can be referenced but does not
1025-
/// yet have an allocation backing it.
1026-
pub fn reserve(
1027-
&self,
1028-
) -> interpret::AllocId {
1029-
let mut inner = self.inner.borrow_mut();
1030-
let next = inner.next_id;
1031-
inner.next_id.0 = inner.next_id.0
1032-
.checked_add(1)
1033-
.expect("You overflowed a u64 by incrementing by 1... \
1034-
You've just earned yourself a free drink if we ever meet. \
1035-
Seriously, how did you do that?!");
1036-
next
1037-
}
1038-
}
1039-
1040935
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
1041936
/// Get the global TyCtxt.
1042937
#[inline]
@@ -1124,11 +1019,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
11241019
// create an allocation that just contains these bytes
11251020
let alloc = interpret::Allocation::from_byte_aligned_bytes(bytes);
11261021
let alloc = self.intern_const_alloc(alloc);
1127-
1128-
// the next unique id
1129-
let id = self.interpret_interner.reserve();
1130-
self.interpret_interner.intern_at_reserved(id, alloc);
1131-
id
1022+
self.alloc_map.lock().allocate(alloc)
11321023
}
11331024

11341025
pub fn intern_stability(self, stab: attr::Stability) -> &'gcx attr::Stability {
@@ -1279,7 +1170,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12791170
layout_interner: Lock::new(FxHashSet()),
12801171
stability_interner: Lock::new(FxHashSet()),
12811172
allocation_interner: Lock::new(FxHashSet()),
1282-
interpret_interner: Default::default(),
1173+
alloc_map: Lock::new(interpret::AllocMap::new()),
12831174
tx_to_llvm_workers: Lock::new(tx),
12841175
output_filenames: Arc::new(output_filenames.clone()),
12851176
};

‎src/librustc/ty/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ pub use self::binding::BindingMode;
7878
pub use self::binding::BindingMode::*;
7979

8080
pub use self::context::{TyCtxt, GlobalArenas, AllArenas, tls, keep_local};
81-
pub use self::context::{Lift, TypeckTables, InterpretInterner};
81+
pub use self::context::{Lift, TypeckTables};
8282

8383
pub use self::instance::{Instance, InstanceDef};
8484

‎src/librustc_codegen_llvm/mir/constant.rs

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_mir::interpret::{read_target_uint, const_val_field};
1414
use rustc::hir::def_id::DefId;
1515
use rustc::mir;
1616
use rustc_data_structures::indexed_vec::Idx;
17-
use rustc::mir::interpret::{GlobalId, MemoryPointer, PrimVal, Allocation, ConstValue};
17+
use rustc::mir::interpret::{GlobalId, MemoryPointer, PrimVal, Allocation, ConstValue, AllocType};
1818
use rustc::ty::{self, Ty};
1919
use rustc::ty::layout::{self, HasDataLayout, LayoutOf, Scalar, Size};
2020
use builder::Builder;
@@ -44,38 +44,34 @@ pub fn primval_to_llvm(cx: &CodegenCx,
4444
}
4545
},
4646
PrimVal::Ptr(ptr) => {
47-
if let Some(fn_instance) = cx.tcx.interpret_interner.get_fn(ptr.alloc_id) {
48-
callee::get_fn(cx, fn_instance)
49-
} else {
50-
let static_ = cx
51-
.tcx
52-
.interpret_interner
53-
.get_static(ptr.alloc_id);
54-
let base_addr = if let Some(def_id) = static_ {
55-
assert!(cx.tcx.is_static(def_id).is_some());
56-
consts::get_static(cx, def_id)
57-
} else if let Some(alloc) = cx.tcx.interpret_interner
58-
.get_alloc(ptr.alloc_id) {
47+
let alloc_type = cx.tcx.alloc_map.lock().get(ptr.alloc_id);
48+
let base_addr = match alloc_type {
49+
Some(AllocType::Memory(alloc)) => {
5950
let init = const_alloc_to_llvm(cx, alloc);
6051
if alloc.runtime_mutability == Mutability::Mutable {
6152
consts::addr_of_mut(cx, init, alloc.align, "byte_str")
6253
} else {
6354
consts::addr_of(cx, init, alloc.align, "byte_str")
6455
}
65-
} else {
66-
bug!("missing allocation {:?}", ptr.alloc_id);
67-
};
68-
69-
let llval = unsafe { llvm::LLVMConstInBoundsGEP(
70-
consts::bitcast(base_addr, Type::i8p(cx)),
71-
&C_usize(cx, ptr.offset.bytes()),
72-
1,
73-
) };
74-
if scalar.value != layout::Pointer {
75-
unsafe { llvm::LLVMConstPtrToInt(llval, llty.to_ref()) }
76-
} else {
77-
consts::bitcast(llval, llty)
7856
}
57+
Some(AllocType::Function(fn_instance)) => {
58+
callee::get_fn(cx, fn_instance)
59+
}
60+
Some(AllocType::Static(def_id)) => {
61+
assert!(cx.tcx.is_static(def_id).is_some());
62+
consts::get_static(cx, def_id)
63+
}
64+
None => bug!("missing allocation {:?}", ptr.alloc_id),
65+
};
66+
let llval = unsafe { llvm::LLVMConstInBoundsGEP(
67+
consts::bitcast(base_addr, Type::i8p(cx)),
68+
&C_usize(cx, ptr.offset.bytes()),
69+
1,
70+
) };
71+
if scalar.value != layout::Pointer {
72+
unsafe { llvm::LLVMConstPtrToInt(llval, llty.to_ref()) }
73+
} else {
74+
consts::bitcast(llval, llty)
7975
}
8076
}
8177
}

‎src/librustc_mir/hair/pattern/_match.rs

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,7 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
187187
.and_then(|t| t.ty.builtin_index())
188188
.map_or(false, |t| t == tcx.types.u8);
189189
assert!(is_array_ptr);
190-
let alloc = tcx
191-
.interpret_interner
192-
.get_alloc(ptr.alloc_id)
193-
.unwrap();
190+
let alloc = tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id);
194191
assert_eq!(ptr.offset.bytes(), 0);
195192
// FIXME: check length
196193
alloc.bytes.iter().map(|b| {
@@ -558,10 +555,7 @@ fn max_slice_length<'p, 'a: 'p, 'tcx: 'a, I>(
558555
.and_then(|t| t.ty.builtin_index())
559556
.map_or(false, |t| t == cx.tcx.types.u8);
560557
if is_array_ptr {
561-
let alloc = cx.tcx
562-
.interpret_interner
563-
.get_alloc(ptr.alloc_id)
564-
.unwrap();
558+
let alloc = cx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id);
565559
max_fixed_len = cmp::max(max_fixed_len, alloc.bytes.len() as u64);
566560
}
567561
}
@@ -945,12 +939,7 @@ fn slice_pat_covered_by_constructor<'tcx>(
945939
.and_then(|t| t.ty.builtin_index())
946940
.map_or(false, |t| t == tcx.types.u8);
947941
assert!(is_array_ptr);
948-
tcx
949-
.interpret_interner
950-
.get_alloc(ptr.alloc_id)
951-
.unwrap()
952-
.bytes
953-
.as_ref()
942+
tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id).bytes.as_ref()
954943
} else {
955944
bug!()
956945
}
@@ -1088,9 +1077,9 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
10881077
.map_or(false, |t| t == cx.tcx.types.u8);
10891078
assert!(is_array_ptr);
10901079
let data_len = cx.tcx
1091-
.interpret_interner
1092-
.get_alloc(ptr.alloc_id)
1093-
.unwrap()
1080+
.alloc_map
1081+
.lock()
1082+
.unwrap_memory(ptr.alloc_id)
10941083
.bytes
10951084
.len();
10961085
if wild_patterns.len() == data_len {

‎src/librustc_mir/interpret/const_eval.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,9 @@ impl<'mir, 'tcx> super::Machine<'mir, 'tcx> for CompileTimeEvaluator {
377377
) -> EvalResult<'tcx, AllocId> {
378378
Ok(ecx
379379
.tcx
380-
.interpret_interner
381-
.cache_static(cid.instance.def_id()))
380+
.alloc_map
381+
.lock()
382+
.intern_static(cid.instance.def_id()))
382383
}
383384

384385
fn box_alloc<'a>(

‎src/librustc_mir/interpret/eval_context.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,8 +1015,9 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
10151015
if self.tcx.is_static(gid.instance.def_id()).is_some() {
10161016
let alloc_id = self
10171017
.tcx
1018-
.interpret_interner
1019-
.cache_static(gid.instance.def_id());
1018+
.alloc_map
1019+
.lock()
1020+
.intern_static(gid.instance.def_id());
10201021
let layout = self.layout_of(ty)?;
10211022
let ptr = MemoryPointer::new(alloc_id, Size::from_bytes(0));
10221023
return Ok(Value::ByRef(ptr.into(), layout.align))

‎src/librustc_mir/interpret/memory.rs

Lines changed: 45 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc::middle::const_val::{ConstVal, ErrKind};
1111

1212
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
1313
use rustc::mir::interpret::{MemoryPointer, AllocId, Allocation, AccessKind, Value, Pointer,
14-
EvalResult, PrimVal, EvalErrorKind, GlobalId};
14+
EvalResult, PrimVal, EvalErrorKind, GlobalId, AllocType};
1515
pub use rustc::mir::interpret::{write_target_uint, write_target_int, read_target_uint};
1616

1717
use super::{EvalContext, Machine};
@@ -72,7 +72,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
7272
}
7373

7474
pub fn create_fn_alloc(&mut self, instance: Instance<'tcx>) -> MemoryPointer {
75-
let id = self.tcx.interpret_interner.create_fn_alloc(instance);
75+
let id = self.tcx.alloc_map.lock().create_fn_alloc(instance);
7676
MemoryPointer::new(id, Size::from_bytes(0))
7777
}
7878

@@ -87,7 +87,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
8787
alloc: Allocation,
8888
kind: Option<MemoryKind<M::MemoryKinds>>,
8989
) -> EvalResult<'tcx, AllocId> {
90-
let id = self.tcx.interpret_interner.reserve();
90+
let id = self.tcx.alloc_map.lock().reserve();
9191
M::add_lock(self, id);
9292
match kind {
9393
Some(kind @ MemoryKind::Stack) |
@@ -177,19 +177,20 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
177177
"uninitializedstatic".to_string(),
178178
format!("{:?}", kind),
179179
))
180-
} else if self.tcx.interpret_interner.get_fn(ptr.alloc_id).is_some() {
181-
return err!(DeallocatedWrongMemoryKind(
182-
"function".to_string(),
183-
format!("{:?}", kind),
184-
))
185-
} else if self.tcx.interpret_interner.get_alloc(ptr.alloc_id).is_some() {
186-
return err!(DeallocatedWrongMemoryKind(
187-
"static".to_string(),
188-
format!("{:?}", kind),
189-
))
190180
} else {
191-
return err!(DoubleFree)
192-
},
181+
return match self.tcx.alloc_map.lock().get(ptr.alloc_id) {
182+
Some(AllocType::Function(..)) => err!(DeallocatedWrongMemoryKind(
183+
"function".to_string(),
184+
format!("{:?}", kind),
185+
)),
186+
Some(AllocType::Static(..)) |
187+
Some(AllocType::Memory(..)) => err!(DeallocatedWrongMemoryKind(
188+
"static".to_string(),
189+
format!("{:?}", kind),
190+
)),
191+
None => err!(DoubleFree)
192+
}
193+
}
193194
};
194195

195196
let alloc_kind = self.alloc_kind.remove(&ptr.alloc_id).expect("alloc_map out of sync with alloc_kind");
@@ -312,19 +313,16 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
312313
Some(alloc) => Ok(alloc),
313314
None => {
314315
// static alloc?
315-
if let Some(a) = self.tcx.interpret_interner.get_alloc(id) {
316-
return Ok(a);
316+
match self.tcx.alloc_map.lock().get(id) {
317+
Some(AllocType::Memory(mem)) => Ok(mem),
318+
Some(AllocType::Function(..)) => {
319+
Err(EvalErrorKind::DerefFunctionPointer.into())
320+
}
321+
Some(AllocType::Static(did)) => {
322+
self.const_eval_static(did)
323+
}
324+
None => Err(EvalErrorKind::DanglingPointerDeref.into()),
317325
}
318-
// static variable?
319-
if let Some(did) = self.tcx.interpret_interner.get_static(id) {
320-
return self.const_eval_static(did);
321-
}
322-
// otherwise return an error
323-
Err(if self.tcx.interpret_interner.get_fn(id).is_some() {
324-
EvalErrorKind::DerefFunctionPointer.into()
325-
} else {
326-
EvalErrorKind::DanglingPointerDeref.into()
327-
})
328326
},
329327
},
330328
}
@@ -342,12 +340,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
342340
Some(alloc) => Ok(alloc),
343341
None => {
344342
// no alloc or immutable alloc? produce an error
345-
if self.tcx.interpret_interner.get_alloc(id).is_some() {
346-
err!(ModifiedConstantMemory)
347-
} else if self.tcx.interpret_interner.get_fn(id).is_some() {
348-
err!(DerefFunctionPointer)
349-
} else {
350-
err!(DanglingPointerDeref)
343+
match self.tcx.alloc_map.lock().get(id) {
344+
Some(AllocType::Memory(..)) |
345+
Some(AllocType::Static(..)) => err!(ModifiedConstantMemory),
346+
Some(AllocType::Function(..)) => err!(DerefFunctionPointer),
347+
None => err!(DanglingPointerDeref),
351348
}
352349
},
353350
},
@@ -359,10 +356,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
359356
return err!(InvalidFunctionPointer);
360357
}
361358
debug!("reading fn ptr: {}", ptr.alloc_id);
362-
self.tcx
363-
.interpret_interner
364-
.get_fn(ptr.alloc_id)
365-
.ok_or(EvalErrorKind::ExecuteMemory.into())
359+
match self.tcx.alloc_map.lock().get(ptr.alloc_id) {
360+
Some(AllocType::Function(instance)) => Ok(instance),
361+
_ => Err(EvalErrorKind::ExecuteMemory.into()),
362+
}
366363
}
367364

368365
pub fn get_alloc_kind(&self, id: AllocId) -> Option<MemoryKind<M::MemoryKinds>> {
@@ -405,15 +402,20 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
405402
Some(a) => (a, " (static in the process of initialization)".to_owned()),
406403
None => {
407404
// static alloc?
408-
match self.tcx.interpret_interner.get_alloc(id) {
409-
Some(a) => (a, "(immutable)".to_owned()),
410-
None => if let Some(func) = self.tcx.interpret_interner.get_fn(id) {
405+
match self.tcx.alloc_map.lock().get(id) {
406+
Some(AllocType::Memory(a)) => (a, "(immutable)".to_owned()),
407+
Some(AllocType::Function(func)) => {
411408
trace!("{} {}", msg, func);
412409
continue;
413-
} else {
410+
}
411+
Some(AllocType::Static(did)) => {
412+
trace!("{} {:?}", msg, did);
413+
continue;
414+
}
415+
None => {
414416
trace!("{} (deallocated)", msg);
415417
continue;
416-
},
418+
}
417419
}
418420
},
419421
},
@@ -579,7 +581,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
579581
// ensure llvm knows not to put this into immutable memroy
580582
alloc.runtime_mutability = mutability;
581583
let alloc = self.tcx.intern_const_alloc(alloc);
582-
self.tcx.interpret_interner.intern_at_reserved(alloc_id, alloc);
584+
self.tcx.alloc_map.lock().set_id_memory(alloc_id, alloc);
583585
// recurse into inner allocations
584586
for &alloc in alloc.relocations.values() {
585587
self.mark_inner_allocation_initialized(alloc, mutability)?;

‎src/librustc_mir/monomorphize/collector.rs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ use rustc::session::config;
203203
use rustc::mir::{self, Location, Promoted};
204204
use rustc::mir::visit::Visitor as MirVisitor;
205205
use rustc::mir::mono::MonoItem;
206-
use rustc::mir::interpret::{PrimVal, GlobalId};
206+
use rustc::mir::interpret::{PrimVal, GlobalId, AllocType};
207207

208208
use monomorphize::{self, Instance};
209209
use rustc::util::nodemap::{FxHashSet, FxHashMap, DefIdMap};
@@ -1146,24 +1146,28 @@ fn collect_miri<'a, 'tcx>(
11461146
alloc_id: AllocId,
11471147
output: &mut Vec<MonoItem<'tcx>>,
11481148
) {
1149-
if let Some(did) = tcx.interpret_interner.get_static(alloc_id) {
1150-
let instance = Instance::mono(tcx, did);
1151-
if should_monomorphize_locally(tcx, &instance) {
1152-
trace!("collecting static {:?}", did);
1153-
output.push(MonoItem::Static(did));
1154-
}
1155-
} else if let Some(alloc) = tcx.interpret_interner.get_alloc(alloc_id) {
1156-
trace!("collecting {:?} with {:#?}", alloc_id, alloc);
1157-
for &inner in alloc.relocations.values() {
1158-
collect_miri(tcx, inner, output);
1149+
let alloc_type = tcx.alloc_map.lock().get(alloc_id);
1150+
match alloc_type {
1151+
Some(AllocType::Static(did)) => {
1152+
let instance = Instance::mono(tcx, did);
1153+
if should_monomorphize_locally(tcx, &instance) {
1154+
trace!("collecting static {:?}", did);
1155+
output.push(MonoItem::Static(did));
1156+
}
11591157
}
1160-
} else if let Some(fn_instance) = tcx.interpret_interner.get_fn(alloc_id) {
1161-
if should_monomorphize_locally(tcx, &fn_instance) {
1162-
trace!("collecting {:?} with {:#?}", alloc_id, fn_instance);
1163-
output.push(create_fn_mono_item(fn_instance));
1158+
Some(AllocType::Memory(alloc)) => {
1159+
trace!("collecting {:?} with {:#?}", alloc_id, alloc);
1160+
for &inner in alloc.relocations.values() {
1161+
collect_miri(tcx, inner, output);
1162+
}
1163+
},
1164+
Some(AllocType::Function(fn_instance)) => {
1165+
if should_monomorphize_locally(tcx, &fn_instance) {
1166+
trace!("collecting {:?} with {:#?}", alloc_id, fn_instance);
1167+
output.push(create_fn_mono_item(fn_instance));
1168+
}
11641169
}
1165-
} else {
1166-
bug!("alloc id without corresponding allocation: {}", alloc_id);
1170+
None => bug!("alloc id without corresponding allocation: {}", alloc_id),
11671171
}
11681172
}
11691173

0 commit comments

Comments
 (0)
Please sign in to comment.