Rollup merge of #71508 - oli-obk:alloc_map_unlock, r=RalfJung

Simplify the `tcx.alloc_map` API

This PR changes all functions that require manually locking the `alloc_map` to functions on `TyCtxt` that lock the map internally. In the same step we make the `TyCtxt::alloc_map` field private.

r? @RalfJung
This commit is contained in:
Ralf Jung 2020-05-09 13:36:37 +02:00 committed by GitHub
commit 8c0310d18c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 115 additions and 107 deletions

View File

@ -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(

View File

@ -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(

View File

@ -136,8 +136,7 @@ impl<'a> HashStable<StableHashingContext<'a>> 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);
});
}
}

View File

@ -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)]

View File

@ -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<AllocId, GlobalAlloc<'tcx>>,
@ -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<GlobalAlloc<'tcx>> {
self.alloc_map.get(&id).cloned()
pub fn get_global_alloc(&self, id: AllocId) -> Option<GlobalAlloc<'tcx>> {
self.alloc_map.lock().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),
}
}
/// 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));
}
}

View File

@ -2404,13 +2404,9 @@ pub struct Constant<'tcx> {
impl Constant<'tcx> {
pub fn check_static_ptr(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
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,
}

View File

@ -979,7 +979,7 @@ pub struct GlobalCtxt<'tcx> {
allocation_interner: ShardedHashMap<&'tcx Allocation, ()>,
/// Stores memory for globals (statics/consts).
pub alloc_map: Lock<interpret::AllocMap<'tcx>>,
pub(crate) alloc_map: Lock<interpret::AllocMap<'tcx>>,
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 {

View File

@ -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),

View File

@ -549,9 +549,8 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
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 {

View File

@ -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 {

View File

@ -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);

View File

@ -153,10 +153,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
fn_val: FnVal<'tcx, M::ExtraFnVal>,
) -> Pointer<M::PointerTag> {
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<M::MemoryKind>,
) -> Pointer<M::PointerTag> {
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<M::PointerTag, M::AllocExtra>>> {
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);

View File

@ -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(

View File

@ -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))

View File

@ -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.

View File

@ -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<MonoItem<'tcx>>) {
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<Mon
});
}
}
Some(GlobalAlloc::Function(fn_instance)) => {
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),
}
}

View File

@ -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)")?,

View File

@ -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 {

View File

@ -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(),
}