diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index 1415fedf11a27..856f989bc10a1 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -244,9 +244,8 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { } } Scalar::Ptr(ptr) => { - let alloc_kind = self.tcx.alloc_map.lock().get(ptr.alloc_id); - let base_addr = match alloc_kind { - Some(GlobalAlloc::Memory(alloc)) => { + let base_addr = match self.tcx.global_alloc(ptr.alloc_id) { + GlobalAlloc::Memory(alloc) => { let init = const_alloc_to_llvm(self, alloc); let value = match alloc.mutability { Mutability::Mut => self.static_addr_of_mut(init, alloc.align, None), @@ -257,12 +256,11 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { } value } - Some(GlobalAlloc::Function(fn_instance)) => self.get_fn_addr(fn_instance), - Some(GlobalAlloc::Static(def_id)) => { + GlobalAlloc::Function(fn_instance) => self.get_fn_addr(fn_instance), + GlobalAlloc::Static(def_id) => { assert!(self.tcx.is_static(def_id)); self.get_static(def_id) } - None => bug!("missing allocation {:?}", ptr.alloc_id), }; let llval = unsafe { llvm::LLVMConstInBoundsGEP( diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index c484867a4e2ad..937c7457c63bb 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -92,7 +92,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { _ => bug!("from_const: invalid ScalarPair layout: {:#?}", layout), }; let a = Scalar::from(Pointer::new( - bx.tcx().alloc_map.lock().create_memory_alloc(data), + bx.tcx().create_memory_alloc(data), Size::from_bytes(start), )); let a_llval = bx.scalar_to_backend( diff --git a/src/librustc_middle/ich/impls_ty.rs b/src/librustc_middle/ich/impls_ty.rs index 226277e440a78..377c8661cbd41 100644 --- a/src/librustc_middle/ich/impls_ty.rs +++ b/src/librustc_middle/ich/impls_ty.rs @@ -136,8 +136,7 @@ impl<'a> HashStable> for mir::interpret::AllocId { ty::tls::with_opt(|tcx| { trace!("hashing {:?}", *self); let tcx = tcx.expect("can't hash AllocIds during hir lowering"); - let alloc_kind = tcx.alloc_map.lock().get(*self); - alloc_kind.hash_stable(hcx, hasher); + tcx.get_global_alloc(*self).hash_stable(hcx, hasher); }); } } diff --git a/src/librustc_middle/lib.rs b/src/librustc_middle/lib.rs index 9b38b43c93ae2..b17a77e0f6fa7 100644 --- a/src/librustc_middle/lib.rs +++ b/src/librustc_middle/lib.rs @@ -42,6 +42,7 @@ #![feature(or_patterns)] #![feature(range_is_empty)] #![feature(specialization)] +#![feature(track_caller)] #![feature(trusted_len)] #![feature(vec_remove_item)] #![feature(stmt_expr_attributes)] diff --git a/src/librustc_middle/mir/interpret/mod.rs b/src/librustc_middle/mir/interpret/mod.rs index 61d7425de7d46..71adb2fa477ad 100644 --- a/src/librustc_middle/mir/interpret/mod.rs +++ b/src/librustc_middle/mir/interpret/mod.rs @@ -197,9 +197,7 @@ pub fn specialized_encode_alloc_id<'tcx, E: Encoder>( tcx: TyCtxt<'tcx>, alloc_id: AllocId, ) -> Result<(), E::Error> { - let alloc: GlobalAlloc<'tcx> = - tcx.alloc_map.lock().get(alloc_id).expect("no value for given alloc ID"); - match alloc { + match tcx.global_alloc(alloc_id) { GlobalAlloc::Memory(alloc) => { trace!("encoding {:?} with {:#?}", alloc_id, alloc); AllocDiscriminant::Alloc.encode(encoder)?; @@ -294,7 +292,7 @@ impl<'s> AllocDecodingSession<'s> { AllocDiscriminant::Alloc => { // If this is an allocation, we need to reserve an // `AllocId` so we can decode cyclic graphs. - let alloc_id = decoder.tcx().alloc_map.lock().reserve(); + let alloc_id = decoder.tcx().reserve_alloc_id(); *entry = State::InProgress(TinyList::new_single(self.session_id), alloc_id); Some(alloc_id) @@ -338,7 +336,7 @@ impl<'s> AllocDecodingSession<'s> { // We already have a reserved `AllocId`. let alloc_id = alloc_id.unwrap(); trace!("decoded alloc {:?}: {:#?}", alloc_id, alloc); - decoder.tcx().alloc_map.lock().set_alloc_id_same_memory(alloc_id, alloc); + decoder.tcx().set_alloc_id_same_memory(alloc_id, alloc); Ok(alloc_id) } AllocDiscriminant::Fn => { @@ -346,7 +344,7 @@ impl<'s> AllocDecodingSession<'s> { trace!("creating fn alloc ID"); let instance = ty::Instance::decode(decoder)?; trace!("decoded fn alloc instance: {:?}", instance); - let alloc_id = decoder.tcx().alloc_map.lock().create_fn_alloc(instance); + let alloc_id = decoder.tcx().create_fn_alloc(instance); Ok(alloc_id) } AllocDiscriminant::Static => { @@ -354,7 +352,7 @@ impl<'s> AllocDecodingSession<'s> { trace!("creating extern static alloc ID"); let did = DefId::decode(decoder)?; trace!("decoded static def-ID: {:?}", did); - let alloc_id = decoder.tcx().alloc_map.lock().create_static_alloc(did); + let alloc_id = decoder.tcx().create_static_alloc(did); Ok(alloc_id) } } @@ -381,7 +379,29 @@ pub enum GlobalAlloc<'tcx> { Memory(&'tcx Allocation), } -pub struct AllocMap<'tcx> { +impl GlobalAlloc<'tcx> { + /// Panics if the `GlobalAlloc` does not refer to an `GlobalAlloc::Memory` + #[track_caller] + #[inline] + pub fn unwrap_memory(&self) -> &'tcx Allocation { + match *self { + GlobalAlloc::Memory(mem) => mem, + _ => bug!("expected memory, got {:?}", self), + } + } + + /// Panics if the `GlobalAlloc` is not `GlobalAlloc::Function` + #[track_caller] + #[inline] + pub fn unwrap_fn(&self) -> Instance<'tcx> { + match *self { + GlobalAlloc::Function(instance) => instance, + _ => bug!("expected function, got {:?}", self), + } + } +} + +crate struct AllocMap<'tcx> { /// Maps `AllocId`s to their corresponding allocations. alloc_map: FxHashMap>, @@ -397,16 +417,10 @@ pub struct AllocMap<'tcx> { } impl<'tcx> AllocMap<'tcx> { - pub fn new() -> Self { + crate fn new() -> Self { AllocMap { alloc_map: Default::default(), dedup: Default::default(), next_id: AllocId(0) } } - - /// Obtains a new allocation ID that can be referenced but does not - /// yet have an allocation backing it. - /// - /// Make sure to call `set_alloc_id_memory` or `set_alloc_id_same_memory` before returning such - /// an `AllocId` from a query. - pub fn reserve(&mut self) -> AllocId { + fn reserve(&mut self) -> AllocId { let next = self.next_id; self.next_id.0 = self.next_id.0.checked_add(1).expect( "You overflowed a u64 by incrementing by 1... \ @@ -415,34 +429,46 @@ impl<'tcx> AllocMap<'tcx> { ); next } +} + +impl<'tcx> TyCtxt<'tcx> { + /// Obtains a new allocation ID that can be referenced but does not + /// yet have an allocation backing it. + /// + /// Make sure to call `set_alloc_id_memory` or `set_alloc_id_same_memory` before returning such + /// an `AllocId` from a query. + pub fn reserve_alloc_id(&self) -> AllocId { + self.alloc_map.lock().reserve() + } /// Reserves a new ID *if* this allocation has not been dedup-reserved before. /// Should only be used for function pointers and statics, we don't want /// to dedup IDs for "real" memory! - fn reserve_and_set_dedup(&mut self, alloc: GlobalAlloc<'tcx>) -> AllocId { + fn reserve_and_set_dedup(&self, alloc: GlobalAlloc<'tcx>) -> AllocId { + let mut alloc_map = self.alloc_map.lock(); match alloc { GlobalAlloc::Function(..) | GlobalAlloc::Static(..) => {} GlobalAlloc::Memory(..) => bug!("Trying to dedup-reserve memory with real data!"), } - if let Some(&alloc_id) = self.dedup.get(&alloc) { + if let Some(&alloc_id) = alloc_map.dedup.get(&alloc) { return alloc_id; } - let id = self.reserve(); + let id = alloc_map.reserve(); debug!("creating alloc {:?} with id {}", alloc, id); - self.alloc_map.insert(id, alloc.clone()); - self.dedup.insert(alloc, id); + alloc_map.alloc_map.insert(id, alloc.clone()); + alloc_map.dedup.insert(alloc, id); id } /// Generates an `AllocId` for a static or return a cached one in case this function has been /// called on the same static before. - pub fn create_static_alloc(&mut self, static_id: DefId) -> AllocId { + pub fn create_static_alloc(&self, static_id: DefId) -> AllocId { self.reserve_and_set_dedup(GlobalAlloc::Static(static_id)) } /// Generates an `AllocId` for a function. Depending on the function type, /// this might get deduplicated or assigned a new ID each time. - pub fn create_fn_alloc(&mut self, instance: Instance<'tcx>) -> AllocId { + pub fn create_fn_alloc(&self, instance: Instance<'tcx>) -> AllocId { // Functions cannot be identified by pointers, as asm-equal functions can get deduplicated // by the linker (we set the "unnamed_addr" attribute for LLVM) and functions can be // duplicated across crates. @@ -456,8 +482,9 @@ impl<'tcx> AllocMap<'tcx> { }); if is_generic { // Get a fresh ID. - let id = self.reserve(); - self.alloc_map.insert(id, GlobalAlloc::Function(instance)); + let mut alloc_map = self.alloc_map.lock(); + let id = alloc_map.reserve(); + alloc_map.alloc_map.insert(id, GlobalAlloc::Function(instance)); id } else { // Deduplicate. @@ -470,8 +497,8 @@ impl<'tcx> AllocMap<'tcx> { /// Statics with identical content will still point to the same `Allocation`, i.e., /// their data will be deduplicated through `Allocation` interning -- but they /// are different places in memory and as such need different IDs. - pub fn create_memory_alloc(&mut self, mem: &'tcx Allocation) -> AllocId { - let id = self.reserve(); + pub fn create_memory_alloc(&self, mem: &'tcx Allocation) -> AllocId { + let id = self.reserve_alloc_id(); self.set_alloc_id_memory(id, mem); id } @@ -482,38 +509,35 @@ impl<'tcx> AllocMap<'tcx> { /// This function exists to allow const eval to detect the difference between evaluation- /// local dangling pointers and allocations in constants/statics. #[inline] - pub fn get(&self, id: AllocId) -> Option> { - self.alloc_map.get(&id).cloned() - } - - /// Panics if the `AllocId` does not refer to an `Allocation` - pub fn unwrap_memory(&self, id: AllocId) -> &'tcx Allocation { - match self.get(id) { - Some(GlobalAlloc::Memory(mem)) => mem, - _ => bug!("expected allocation ID {} to point to memory", id), - } + pub fn get_global_alloc(&self, id: AllocId) -> Option> { + self.alloc_map.lock().alloc_map.get(&id).cloned() } - /// Panics if the `AllocId` does not refer to a function - pub fn unwrap_fn(&self, id: AllocId) -> Instance<'tcx> { - match self.get(id) { - Some(GlobalAlloc::Function(instance)) => instance, - _ => bug!("expected allocation ID {} to point to a function", id), + #[inline] + #[track_caller] + /// Panics in case the `AllocId` is dangling. Since that is impossible for `AllocId`s in + /// constants (as all constants must pass interning and validation that check for dangling + /// ids), this function is frequently used throughout rustc, but should not be used within + /// the miri engine. + pub fn global_alloc(&self, id: AllocId) -> GlobalAlloc<'tcx> { + match self.get_global_alloc(id) { + Some(alloc) => alloc, + None => bug!("could not find allocation for {}", id), } } /// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. Trying to /// call this function twice, even with the same `Allocation` will ICE the compiler. - pub fn set_alloc_id_memory(&mut self, id: AllocId, mem: &'tcx Allocation) { - if let Some(old) = self.alloc_map.insert(id, GlobalAlloc::Memory(mem)) { + pub fn set_alloc_id_memory(&self, id: AllocId, mem: &'tcx Allocation) { + if let Some(old) = self.alloc_map.lock().alloc_map.insert(id, GlobalAlloc::Memory(mem)) { bug!("tried to set allocation ID {}, but it was already existing as {:#?}", id, old); } } /// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. May be called /// twice for the same `(AllocId, Allocation)` pair. - fn set_alloc_id_same_memory(&mut self, id: AllocId, mem: &'tcx Allocation) { - self.alloc_map.insert_same(id, GlobalAlloc::Memory(mem)); + fn set_alloc_id_same_memory(&self, id: AllocId, mem: &'tcx Allocation) { + self.alloc_map.lock().alloc_map.insert_same(id, GlobalAlloc::Memory(mem)); } } diff --git a/src/librustc_middle/mir/mod.rs b/src/librustc_middle/mir/mod.rs index 1586266051226..8eac436394169 100644 --- a/src/librustc_middle/mir/mod.rs +++ b/src/librustc_middle/mir/mod.rs @@ -2404,13 +2404,9 @@ pub struct Constant<'tcx> { impl Constant<'tcx> { pub fn check_static_ptr(&self, tcx: TyCtxt<'_>) -> Option { match self.literal.val.try_to_scalar() { - Some(Scalar::Ptr(ptr)) => match tcx.alloc_map.lock().get(ptr.alloc_id) { - Some(GlobalAlloc::Static(def_id)) => Some(def_id), - Some(_) => None, - None => { - tcx.sess.delay_span_bug(DUMMY_SP, "MIR cannot contain dangling const pointers"); - None - } + Some(Scalar::Ptr(ptr)) => match tcx.global_alloc(ptr.alloc_id) { + GlobalAlloc::Static(def_id) => Some(def_id), + _ => None, }, _ => None, } diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs index fc68a347dfde5..d2267bdfc13d2 100644 --- a/src/librustc_middle/ty/context.rs +++ b/src/librustc_middle/ty/context.rs @@ -979,7 +979,7 @@ pub struct GlobalCtxt<'tcx> { allocation_interner: ShardedHashMap<&'tcx Allocation, ()>, /// Stores memory for globals (statics/consts). - pub alloc_map: Lock>, + pub(crate) alloc_map: Lock>, layout_interner: ShardedHashMap<&'tcx Layout, ()>, @@ -1017,7 +1017,7 @@ impl<'tcx> TyCtxt<'tcx> { // Create an allocation that just contains these bytes. let alloc = interpret::Allocation::from_byte_aligned_bytes(bytes); let alloc = self.intern_const_alloc(alloc); - self.alloc_map.lock().create_memory_alloc(alloc) + self.create_memory_alloc(alloc) } pub fn intern_stability(self, stab: attr::Stability) -> &'tcx attr::Stability { diff --git a/src/librustc_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs index 2d2704fc2bd89..94384230a7860 100644 --- a/src/librustc_middle/ty/print/pretty.rs +++ b/src/librustc_middle/ty/print/pretty.rs @@ -956,9 +956,8 @@ pub trait PrettyPrinter<'tcx>: ) => { let byte_str = self .tcx() - .alloc_map - .lock() - .unwrap_memory(ptr.alloc_id) + .global_alloc(ptr.alloc_id) + .unwrap_memory() .get_bytes(&self.tcx(), ptr, Size::from_bytes(*data)) .unwrap(); p!(pretty_print_byte_str(byte_str)); @@ -1021,10 +1020,7 @@ pub trait PrettyPrinter<'tcx>: )?; } (Scalar::Ptr(ptr), ty::FnPtr(_)) => { - let instance = { - let alloc_map = self.tcx().alloc_map.lock(); - alloc_map.unwrap_fn(ptr.alloc_id) - }; + let instance = self.tcx().global_alloc(ptr.alloc_id).unwrap_fn(); self = self.typed_value( |this| this.print_value_path(instance.def_id(), instance.substs), |this| this.print_type(ty), diff --git a/src/librustc_middle/ty/relate.rs b/src/librustc_middle/ty/relate.rs index faa74f81e818b..9c198dd556ac3 100644 --- a/src/librustc_middle/ty/relate.rs +++ b/src/librustc_middle/ty/relate.rs @@ -549,9 +549,8 @@ pub fn super_relate_consts>( if a_val == b_val { Ok(ConstValue::Scalar(a_val)) } else if let ty::FnPtr(_) = a.ty.kind { - let alloc_map = tcx.alloc_map.lock(); - let a_instance = alloc_map.unwrap_fn(a_val.assert_ptr().alloc_id); - let b_instance = alloc_map.unwrap_fn(b_val.assert_ptr().alloc_id); + let a_instance = tcx.global_alloc(a_val.assert_ptr().alloc_id).unwrap_fn(); + let b_instance = tcx.global_alloc(b_val.assert_ptr().alloc_id).unwrap_fn(); if a_instance == b_instance { Ok(ConstValue::Scalar(a_val)) } else { diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs index 2f635b4a1c171..b6c635fb22ab5 100644 --- a/src/librustc_mir/const_eval/eval_queries.rs +++ b/src/librustc_mir/const_eval/eval_queries.rs @@ -130,7 +130,7 @@ pub(super) fn op_to_const<'tcx>( let to_const_value = |mplace: MPlaceTy<'_>| match mplace.ptr { Scalar::Ptr(ptr) => { - let alloc = ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id); + let alloc = ecx.tcx.global_alloc(ptr.alloc_id).unwrap_memory(); ConstValue::ByRef { alloc, offset: ptr.offset } } Scalar::Raw { data, .. } => { @@ -155,7 +155,7 @@ pub(super) fn op_to_const<'tcx>( Immediate::ScalarPair(a, b) => { let (data, start) = match a.not_undef().unwrap() { Scalar::Ptr(ptr) => { - (ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id), ptr.offset.bytes()) + (ecx.tcx.global_alloc(ptr.alloc_id).unwrap_memory(), ptr.offset.bytes()) } Scalar::Raw { .. } => ( ecx.tcx @@ -203,7 +203,7 @@ fn validate_and_turn_into_const<'tcx>( if is_static || cid.promoted.is_some() { let ptr = mplace.ptr.assert_ptr(); Ok(ConstValue::ByRef { - alloc: ecx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id), + alloc: ecx.tcx.global_alloc(ptr.alloc_id).unwrap_memory(), offset: ptr.offset, }) } else { diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 8bc0e2ee6a4c6..1c44101595d4f 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -91,7 +91,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>>( // If the pointer is dangling (neither in local nor global memory), we leave it // to validation to error. The `delay_span_bug` ensures that we don't forget such // a check in validation. - if tcx.alloc_map.lock().get(alloc_id).is_none() { + if tcx.get_global_alloc(alloc_id).is_none() { tcx.sess.delay_span_bug(ecx.tcx.span, "tried to intern dangling pointer"); } // treat dangling pointers like other statics @@ -134,7 +134,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>>( // link the alloc id to the actual allocation let alloc = tcx.intern_const_alloc(alloc); leftover_allocations.extend(alloc.relocations().iter().map(|&(_, ((), reloc))| reloc)); - tcx.alloc_map.lock().set_alloc_id_memory(alloc_id, alloc); + tcx.set_alloc_id_memory(alloc_id, alloc); Ok(None) } @@ -389,7 +389,7 @@ where } } let alloc = tcx.intern_const_alloc(alloc); - tcx.alloc_map.lock().set_alloc_id_memory(alloc_id, alloc); + tcx.set_alloc_id_memory(alloc_id, alloc); for &(_, ((), reloc)) in alloc.relocations().iter() { if leftover_allocations.insert(reloc) { todo.push(reloc); @@ -398,7 +398,7 @@ where } else if ecx.memory.dead_alloc_map.contains_key(&alloc_id) { // dangling pointer throw_ub_format!("encountered dangling pointer in final constant") - } else if ecx.tcx.alloc_map.lock().get(alloc_id).is_none() { + } else if ecx.tcx.get_global_alloc(alloc_id).is_none() { // We have hit an `AllocId` that is neither in local or global memory and isn't marked // as dangling by local memory. span_bug!(ecx.tcx.span, "encountered unknown alloc id {:?}", alloc_id); diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 39e428cee1d7b..61c365644c7f2 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -153,10 +153,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { fn_val: FnVal<'tcx, M::ExtraFnVal>, ) -> Pointer { let id = match fn_val { - FnVal::Instance(instance) => self.tcx.alloc_map.lock().create_fn_alloc(instance), + FnVal::Instance(instance) => self.tcx.create_fn_alloc(instance), FnVal::Other(extra) => { // FIXME(RalfJung): Should we have a cache here? - let id = self.tcx.alloc_map.lock().reserve(); + let id = self.tcx.reserve_alloc_id(); let old = self.extra_fn_ptr_map.insert(id, extra); assert!(old.is_none()); id @@ -189,7 +189,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { alloc: Allocation, kind: MemoryKind, ) -> Pointer { - let id = self.tcx.alloc_map.lock().reserve(); + let id = self.tcx.reserve_alloc_id(); debug_assert_ne!( Some(kind), M::GLOBAL_KIND.map(MemoryKind::Machine), @@ -260,7 +260,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Some(alloc) => alloc, None => { // Deallocating global memory -- always an error - return Err(match self.tcx.alloc_map.lock().get(ptr.alloc_id) { + return Err(match self.tcx.get_global_alloc(ptr.alloc_id) { Some(GlobalAlloc::Function(..)) => err_ub_format!("deallocating a function"), Some(GlobalAlloc::Static(..) | GlobalAlloc::Memory(..)) => { err_ub_format!("deallocating static memory") @@ -429,8 +429,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { id: AllocId, is_write: bool, ) -> InterpResult<'tcx, Cow<'tcx, Allocation>> { - let alloc = tcx.alloc_map.lock().get(id); - let (alloc, def_id) = match alloc { + let (alloc, def_id) = match tcx.get_global_alloc(id) { Some(GlobalAlloc::Memory(mem)) => { // Memory of a constant or promoted or anonymous memory referenced by a static. (mem, None) @@ -468,7 +467,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { })?; // Make sure we use the ID of the resolved memory, not the lazy one! let id = raw_const.alloc_id; - let allocation = tcx.alloc_map.lock().unwrap_memory(id); + let allocation = tcx.global_alloc(id).unwrap_memory(); (allocation, Some(def_id)) } @@ -591,8 +590,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // # Statics // Can't do this in the match argument, we may get cycle errors since the lock would // be held throughout the match. - let alloc = self.tcx.alloc_map.lock().get(id); - match alloc { + match self.tcx.get_global_alloc(id) { Some(GlobalAlloc::Static(did)) => { // Use size and align of the type. let ty = self.tcx.type_of(did); @@ -627,7 +625,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { if let Some(extra) = self.extra_fn_ptr_map.get(&id) { Some(FnVal::Other(*extra)) } else { - match self.tcx.alloc_map.lock().get(id) { + match self.tcx.get_global_alloc(id) { Some(GlobalAlloc::Function(instance)) => Some(FnVal::Instance(instance)), _ => None, } @@ -695,7 +693,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } None => { // global alloc - match self.tcx.alloc_map.lock().get(id) { + match self.tcx.get_global_alloc(id) { Some(GlobalAlloc::Memory(alloc)) => { eprint!(" (unchanged global, "); write_allocation_track_relocs(self.tcx, &mut allocs_to_print, alloc); diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 81009fd7b98f7..a3caa2048a1e7 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -549,7 +549,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let layout = from_known_layout(self.tcx, layout, || self.layout_of(val.ty))?; let op = match val_val { ConstValue::ByRef { alloc, offset } => { - let id = self.tcx.alloc_map.lock().create_memory_alloc(alloc); + let id = self.tcx.create_memory_alloc(alloc); // We rely on mutability being set correctly in that allocation to prevent writes // where none should happen. let ptr = self.tag_global_base_pointer(Pointer::new(id, offset)); @@ -560,7 +560,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // We rely on mutability being set correctly in `data` to prevent writes // where none should happen. let ptr = Pointer::new( - self.tcx.alloc_map.lock().create_memory_alloc(data), + self.tcx.create_memory_alloc(data), Size::from_bytes(start), // offset: `start` ); Operand::Immediate(Immediate::new_slice( diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 2e8b1e64aedc3..6dadb8e4c67f4 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -1101,7 +1101,7 @@ where raw: RawConst<'tcx>, ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { // This must be an allocation in `tcx` - assert!(self.tcx.alloc_map.lock().get(raw.alloc_id).is_some()); + let _ = self.tcx.global_alloc(raw.alloc_id); let ptr = self.tag_global_base_pointer(Pointer::from(raw.alloc_id)); let layout = self.layout_of(raw.ty)?; Ok(MPlaceTy::from_aligned_ptr(ptr, layout)) diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index e563cf78f8adc..4f90f83b735d1 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -416,7 +416,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' if let Some(ptr) = ptr { // not a ZST // Skip validation entirely for some external statics - let alloc_kind = self.ecx.tcx.alloc_map.lock().get(ptr.alloc_id); + let alloc_kind = self.ecx.tcx.get_global_alloc(ptr.alloc_id); if let Some(GlobalAlloc::Static(did)) = alloc_kind { // See const_eval::machine::MemoryExtra::can_access_statics for why // this check is so important. diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 3d79825473588..4648100e3b701 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -1136,16 +1136,15 @@ fn create_mono_items_for_default_impls<'tcx>( /// Scans the miri alloc in order to find function calls, closures, and drop-glue. fn collect_miri<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut Vec>) { - let alloc_kind = tcx.alloc_map.lock().get(alloc_id); - match alloc_kind { - Some(GlobalAlloc::Static(def_id)) => { + match tcx.global_alloc(alloc_id) { + GlobalAlloc::Static(def_id) => { let instance = Instance::mono(tcx, def_id); if should_monomorphize_locally(tcx, &instance) { trace!("collecting static {:?}", def_id); output.push(MonoItem::Static(def_id)); } } - Some(GlobalAlloc::Memory(alloc)) => { + GlobalAlloc::Memory(alloc) => { trace!("collecting {:?} with {:#?}", alloc_id, alloc); for &((), inner) in alloc.relocations().values() { rustc_data_structures::stack::ensure_sufficient_stack(|| { @@ -1153,13 +1152,12 @@ fn collect_miri<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut Vec { + GlobalAlloc::Function(fn_instance) => { if should_monomorphize_locally(tcx, &fn_instance) { trace!("collecting {:?} with {:#?}", alloc_id, fn_instance); output.push(create_fn_mono_item(fn_instance)); } } - None => bug!("alloc id without corresponding allocation: {}", alloc_id), } } diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index f3f45c0037d97..ff386cb218304 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -588,8 +588,7 @@ pub fn write_allocations<'tcx>( write_allocation(tcx, alloc, w) }; write!(w, "\n{}", id)?; - let alloc = tcx.alloc_map.lock().get(id); - match alloc { + match tcx.get_global_alloc(id) { // This can't really happen unless there are bugs, but it doesn't cost us anything to // gracefully handle it and allow buggy rustc to be debugged via allocation printing. None => write!(w, " (deallocated)")?, diff --git a/src/librustc_mir_build/hair/cx/expr.rs b/src/librustc_mir_build/hair/cx/expr.rs index 0ef6d24d07b48..8d572465d62c1 100644 --- a/src/librustc_mir_build/hair/cx/expr.rs +++ b/src/librustc_mir_build/hair/cx/expr.rs @@ -740,7 +740,7 @@ fn convert_path_expr<'a, 'tcx>( // a constant reference (or constant raw pointer for `static mut`) in MIR Res::Def(DefKind::Static, id) => { let ty = cx.tcx.static_ptr_ty(id); - let ptr = cx.tcx.alloc_map.lock().create_static_alloc(id); + let ptr = cx.tcx.create_static_alloc(id); let temp_lifetime = cx.region_scope_tree.temporary_scope(expr.hir_id.local_id); ExprKind::Deref { arg: Expr { diff --git a/src/librustc_mir_build/hair/pattern/_match.rs b/src/librustc_mir_build/hair/pattern/_match.rs index cdafb63f1ebc1..f6941d3293b5c 100644 --- a/src/librustc_mir_build/hair/pattern/_match.rs +++ b/src/librustc_mir_build/hair/pattern/_match.rs @@ -286,7 +286,7 @@ impl<'tcx> LiteralExpander<'tcx> { (ConstValue::Scalar(p), x, y) if x == y => { match p { Scalar::Ptr(p) => { - let alloc = self.tcx.alloc_map.lock().unwrap_memory(p.alloc_id); + let alloc = self.tcx.global_alloc(p.alloc_id).unwrap_memory(); ConstValue::ByRef { alloc, offset: p.offset } } Scalar::Raw { .. } => { @@ -305,7 +305,7 @@ impl<'tcx> LiteralExpander<'tcx> { (ConstValue::Scalar(Scalar::Ptr(p)), ty::Array(t, n), ty::Slice(u)) => { assert_eq!(t, u); ConstValue::Slice { - data: self.tcx.alloc_map.lock().unwrap_memory(p.alloc_id), + data: self.tcx.global_alloc(p.alloc_id).unwrap_memory(), start: p.offset.bytes().try_into().unwrap(), end: n.eval_usize(self.tcx, ty::ParamEnv::empty()).try_into().unwrap(), }