light refactoring of global AllocMap

* rename AllocKind -> GlobalAlloc. This stores the allocation itself, not just its kind.
* rename the methods that allocate stuff to have consistent names.
This commit is contained in:
Ralf Jung 2019-05-30 13:05:05 +02:00
parent c28084ac16
commit 41c36fabef
9 changed files with 81 additions and 68 deletions

View file

@ -72,20 +72,20 @@ pub fn specialized_encode_alloc_id<
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
alloc_id: AllocId, alloc_id: AllocId,
) -> Result<(), E::Error> { ) -> Result<(), E::Error> {
let alloc_kind: AllocKind<'tcx> = let alloc: GlobalAlloc<'tcx> =
tcx.alloc_map.lock().get(alloc_id).expect("no value for AllocId"); tcx.alloc_map.lock().get(alloc_id).expect("no value for AllocId");
match alloc_kind { match alloc {
AllocKind::Memory(alloc) => { GlobalAlloc::Memory(alloc) => {
trace!("encoding {:?} with {:#?}", alloc_id, alloc); trace!("encoding {:?} with {:#?}", alloc_id, alloc);
AllocDiscriminant::Alloc.encode(encoder)?; AllocDiscriminant::Alloc.encode(encoder)?;
alloc.encode(encoder)?; alloc.encode(encoder)?;
} }
AllocKind::Function(fn_instance) => { GlobalAlloc::Function(fn_instance) => {
trace!("encoding {:?} with {:#?}", alloc_id, fn_instance); trace!("encoding {:?} with {:#?}", alloc_id, fn_instance);
AllocDiscriminant::Fn.encode(encoder)?; AllocDiscriminant::Fn.encode(encoder)?;
fn_instance.encode(encoder)?; fn_instance.encode(encoder)?;
} }
AllocKind::Static(did) => { GlobalAlloc::Static(did) => {
// referring to statics doesn't need to know about their allocations, // referring to statics doesn't need to know about their allocations,
// just about its DefId // just about its DefId
AllocDiscriminant::Static.encode(encoder)?; AllocDiscriminant::Static.encode(encoder)?;
@ -239,7 +239,7 @@ impl<'s> AllocDecodingSession<'s> {
assert!(alloc_id.is_none()); assert!(alloc_id.is_none());
trace!("creating extern static alloc id at"); trace!("creating extern static alloc id at");
let did = DefId::decode(decoder)?; let did = DefId::decode(decoder)?;
let alloc_id = decoder.tcx().alloc_map.lock().intern_static(did); let alloc_id = decoder.tcx().alloc_map.lock().create_static_alloc(did);
Ok(alloc_id) Ok(alloc_id)
} }
} }
@ -259,8 +259,10 @@ impl fmt::Display for AllocId {
} }
} }
/// An allocation in the global (tcx-managed) memory can be either a function pointer,
/// a static, or a "real" allocation with some data in it.
#[derive(Debug, Clone, Eq, PartialEq, Hash, RustcDecodable, RustcEncodable, HashStable)] #[derive(Debug, Clone, Eq, PartialEq, Hash, RustcDecodable, RustcEncodable, HashStable)]
pub enum AllocKind<'tcx> { pub enum GlobalAlloc<'tcx> {
/// The alloc ID is used as a function pointer /// The alloc ID is used as a function pointer
Function(Instance<'tcx>), Function(Instance<'tcx>),
/// The alloc ID points to a "lazy" static variable that did not get computed (yet). /// The alloc ID points to a "lazy" static variable that did not get computed (yet).
@ -272,10 +274,12 @@ pub enum AllocKind<'tcx> {
pub struct AllocMap<'tcx> { pub struct AllocMap<'tcx> {
/// Lets you know what an `AllocId` refers to. /// Lets you know what an `AllocId` refers to.
id_to_kind: FxHashMap<AllocId, AllocKind<'tcx>>, alloc_map: FxHashMap<AllocId, GlobalAlloc<'tcx>>,
/// Used to ensure that statics only get one associated `AllocId`. /// Used to ensure that statics and functions only get one associated `AllocId`.
type_interner: FxHashMap<AllocKind<'tcx>, AllocId>, /// Should never contain a `GlobalAlloc::Memory`!
/// FIXME: Should we just have two separate dedup maps for statics and functions each?
dedup: FxHashMap<GlobalAlloc<'tcx>, AllocId>,
/// The `AllocId` to assign to the next requested ID. /// The `AllocId` to assign to the next requested ID.
/// Always incremented, never gets smaller. /// Always incremented, never gets smaller.
@ -285,8 +289,8 @@ pub struct AllocMap<'tcx> {
impl<'tcx> AllocMap<'tcx> { impl<'tcx> AllocMap<'tcx> {
pub fn new() -> Self { pub fn new() -> Self {
AllocMap { AllocMap {
id_to_kind: Default::default(), alloc_map: Default::default(),
type_interner: Default::default(), dedup: Default::default(),
next_id: AllocId(0), next_id: AllocId(0),
} }
} }
@ -308,17 +312,32 @@ impl<'tcx> AllocMap<'tcx> {
next next
} }
fn intern(&mut self, alloc_kind: AllocKind<'tcx>) -> AllocId { /// Reserve a new ID *if* this allocation has not been dedup-reserved before.
if let Some(&alloc_id) = self.type_interner.get(&alloc_kind) { /// 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 {
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) {
return alloc_id; return alloc_id;
} }
let id = self.reserve(); let id = self.reserve();
debug!("creating alloc_kind {:?} with id {}", alloc_kind, id); debug!("creating alloc {:?} with id {}", alloc, id);
self.id_to_kind.insert(id, alloc_kind.clone()); self.alloc_map.insert(id, alloc.clone());
self.type_interner.insert(alloc_kind, id); self.dedup.insert(alloc, id);
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 {
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(&mut self, instance: Instance<'tcx>) -> AllocId {
// Functions cannot be identified by pointers, as asm-equal functions can get deduplicated // 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 // by the linker (we set the "unnamed_addr" attribute for LLVM) and functions can be
@ -336,53 +355,47 @@ impl<'tcx> AllocMap<'tcx> {
if is_generic { if is_generic {
// Get a fresh ID // Get a fresh ID
let id = self.reserve(); let id = self.reserve();
self.id_to_kind.insert(id, AllocKind::Function(instance)); self.alloc_map.insert(id, GlobalAlloc::Function(instance));
id id
} else { } else {
// Deduplicate // Deduplicate
self.intern(AllocKind::Function(instance)) self.reserve_and_set_dedup(GlobalAlloc::Function(instance))
} }
} }
/// Intern the `Allocation` and return a new `AllocId`, even if there's already an identical
/// `Allocation` with a different `AllocId`.
/// 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();
self.set_alloc_id_memory(id, mem);
id
}
/// Returns `None` in case the `AllocId` is dangling. An `InterpretCx` can still have a /// Returns `None` in case the `AllocId` is dangling. An `InterpretCx` can still have a
/// local `Allocation` for that `AllocId`, but having such an `AllocId` in a constant is /// local `Allocation` for that `AllocId`, but having such an `AllocId` in a constant is
/// illegal and will likely ICE. /// illegal and will likely ICE.
/// This function exists to allow const eval to detect the difference between evaluation- /// This function exists to allow const eval to detect the difference between evaluation-
/// local dangling pointers and allocations in constants/statics. /// local dangling pointers and allocations in constants/statics.
#[inline] #[inline]
pub fn get(&self, id: AllocId) -> Option<AllocKind<'tcx>> { pub fn get(&self, id: AllocId) -> Option<GlobalAlloc<'tcx>> {
self.id_to_kind.get(&id).cloned() self.alloc_map.get(&id).cloned()
} }
/// Panics if the `AllocId` does not refer to an `Allocation` /// Panics if the `AllocId` does not refer to an `Allocation`
pub fn unwrap_memory(&self, id: AllocId) -> &'tcx Allocation { pub fn unwrap_memory(&self, id: AllocId) -> &'tcx Allocation {
match self.get(id) { match self.get(id) {
Some(AllocKind::Memory(mem)) => mem, Some(GlobalAlloc::Memory(mem)) => mem,
_ => bug!("expected allocation id {} to point to memory", id), _ => bug!("expected allocation id {} to point to memory", 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 intern_static(&mut self, static_id: DefId) -> AllocId {
self.intern(AllocKind::Static(static_id))
}
/// Intern the `Allocation` and return a new `AllocId`, even if there's already an identical
/// `Allocation` with a different `AllocId`.
// FIXME: is this really necessary? Can we ensure `FOO` and `BAR` being different after codegen
// in `static FOO: u32 = 42; static BAR: u32 = 42;` even if they reuse the same allocation
// inside rustc?
pub fn allocate(&mut self, mem: &'tcx Allocation) -> AllocId {
let id = self.reserve();
self.set_alloc_id_memory(id, mem);
id
}
/// Freeze an `AllocId` created with `reserve` by pointing it at an `Allocation`. Trying to /// Freeze 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. /// 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) { pub fn set_alloc_id_memory(&mut self, id: AllocId, mem: &'tcx Allocation) {
if let Some(old) = self.id_to_kind.insert(id, AllocKind::Memory(mem)) { if let Some(old) = self.alloc_map.insert(id, GlobalAlloc::Memory(mem)) {
bug!("tried to set allocation id {}, but it was already existing as {:#?}", id, old); bug!("tried to set allocation id {}, but it was already existing as {:#?}", id, old);
} }
} }
@ -390,7 +403,7 @@ impl<'tcx> AllocMap<'tcx> {
/// Freeze an `AllocId` created with `reserve` by pointing it at an `Allocation`. May be called /// Freeze an `AllocId` created with `reserve` by pointing it at an `Allocation`. May be called
/// twice for the same `(AllocId, Allocation)` pair. /// twice for the same `(AllocId, Allocation)` pair.
fn set_alloc_id_same_memory(&mut self, id: AllocId, mem: &'tcx Allocation) { fn set_alloc_id_same_memory(&mut self, id: AllocId, mem: &'tcx Allocation) {
self.id_to_kind.insert_same(id, AllocKind::Memory(mem)); self.alloc_map.insert_same(id, GlobalAlloc::Memory(mem));
} }
} }

View file

@ -1191,7 +1191,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
// create an allocation that just contains these bytes // create an allocation that just contains these bytes
let alloc = interpret::Allocation::from_byte_aligned_bytes(bytes, ()); let alloc = interpret::Allocation::from_byte_aligned_bytes(bytes, ());
let alloc = self.intern_const_alloc(alloc); let alloc = self.intern_const_alloc(alloc);
self.alloc_map.lock().allocate(alloc) self.alloc_map.lock().create_memory_alloc(alloc)
} }
pub fn intern_stability(self, stab: attr::Stability) -> &'gcx attr::Stability { pub fn intern_stability(self, stab: attr::Stability) -> &'gcx attr::Stability {

View file

@ -12,7 +12,7 @@ use rustc_codegen_ssa::traits::*;
use crate::consts::const_alloc_to_llvm; use crate::consts::const_alloc_to_llvm;
use rustc::ty::layout::{HasDataLayout, LayoutOf, self, TyLayout, Size}; use rustc::ty::layout::{HasDataLayout, LayoutOf, self, TyLayout, Size};
use rustc::mir::interpret::{Scalar, AllocKind, Allocation}; use rustc::mir::interpret::{Scalar, GlobalAlloc, Allocation};
use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::mir::place::PlaceRef;
use libc::{c_uint, c_char}; use libc::{c_uint, c_char};
@ -310,7 +310,7 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
Scalar::Ptr(ptr) => { Scalar::Ptr(ptr) => {
let alloc_kind = self.tcx.alloc_map.lock().get(ptr.alloc_id); let alloc_kind = self.tcx.alloc_map.lock().get(ptr.alloc_id);
let base_addr = match alloc_kind { let base_addr = match alloc_kind {
Some(AllocKind::Memory(alloc)) => { Some(GlobalAlloc::Memory(alloc)) => {
let init = const_alloc_to_llvm(self, alloc); let init = const_alloc_to_llvm(self, alloc);
if alloc.mutability == Mutability::Mutable { if alloc.mutability == Mutability::Mutable {
self.static_addr_of_mut(init, alloc.align, None) self.static_addr_of_mut(init, alloc.align, None)
@ -318,10 +318,10 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
self.static_addr_of(init, alloc.align, None) self.static_addr_of(init, alloc.align, None)
} }
} }
Some(AllocKind::Function(fn_instance)) => { Some(GlobalAlloc::Function(fn_instance)) => {
self.get_fn(fn_instance) self.get_fn(fn_instance)
} }
Some(AllocKind::Static(def_id)) => { Some(GlobalAlloc::Static(def_id)) => {
assert!(self.tcx.is_static(def_id)); assert!(self.tcx.is_static(def_id));
self.get_static(def_id) self.get_static(def_id)
} }

View file

@ -98,7 +98,7 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandRef<'tcx, V> {
_ => bug!("from_const: invalid ScalarPair layout: {:#?}", layout) _ => bug!("from_const: invalid ScalarPair layout: {:#?}", layout)
}; };
let a = Scalar::from(Pointer::new( let a = Scalar::from(Pointer::new(
bx.tcx().alloc_map.lock().allocate(data), bx.tcx().alloc_map.lock().create_memory_alloc(data),
Size::from_bytes(start as u64), Size::from_bytes(start as u64),
)).into(); )).into();
let a_llval = bx.scalar_to_backend( let a_llval = bx.scalar_to_backend(

View file

@ -18,7 +18,7 @@ use syntax::ast::Mutability;
use super::{ use super::{
Pointer, AllocId, Allocation, GlobalId, AllocationExtra, Pointer, AllocId, Allocation, GlobalId, AllocationExtra,
EvalResult, Scalar, InterpError, AllocKind, PointerArithmetic, EvalResult, Scalar, InterpError, GlobalAlloc, PointerArithmetic,
Machine, AllocMap, MayLeak, ErrorHandled, CheckInAllocMsg, InboundsCheck, Machine, AllocMap, MayLeak, ErrorHandled, CheckInAllocMsg, InboundsCheck,
}; };
@ -193,12 +193,12 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
None => { None => {
// Deallocating static memory -- always an error // Deallocating static memory -- always an error
return match self.tcx.alloc_map.lock().get(ptr.alloc_id) { return match self.tcx.alloc_map.lock().get(ptr.alloc_id) {
Some(AllocKind::Function(..)) => err!(DeallocatedWrongMemoryKind( Some(GlobalAlloc::Function(..)) => err!(DeallocatedWrongMemoryKind(
"function".to_string(), "function".to_string(),
format!("{:?}", kind), format!("{:?}", kind),
)), )),
Some(AllocKind::Static(..)) | Some(GlobalAlloc::Static(..)) |
Some(AllocKind::Memory(..)) => err!(DeallocatedWrongMemoryKind( Some(GlobalAlloc::Memory(..)) => err!(DeallocatedWrongMemoryKind(
"static".to_string(), "static".to_string(),
format!("{:?}", kind), format!("{:?}", kind),
)), )),
@ -313,15 +313,15 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
) -> EvalResult<'tcx, Cow<'tcx, Allocation<M::PointerTag, M::AllocExtra>>> { ) -> EvalResult<'tcx, Cow<'tcx, Allocation<M::PointerTag, M::AllocExtra>>> {
let alloc = tcx.alloc_map.lock().get(id); let alloc = tcx.alloc_map.lock().get(id);
let def_id = match alloc { let def_id = match alloc {
Some(AllocKind::Memory(mem)) => { Some(GlobalAlloc::Memory(mem)) => {
// We got tcx memory. Let the machine figure out whether and how to // We got tcx memory. Let the machine figure out whether and how to
// turn that into memory with the right pointer tag. // turn that into memory with the right pointer tag.
return Ok(M::adjust_static_allocation(mem, memory_extra)) return Ok(M::adjust_static_allocation(mem, memory_extra))
} }
Some(AllocKind::Function(..)) => { Some(GlobalAlloc::Function(..)) => {
return err!(DerefFunctionPointer) return err!(DerefFunctionPointer)
} }
Some(AllocKind::Static(did)) => { Some(GlobalAlloc::Static(did)) => {
did did
} }
None => None =>
@ -429,8 +429,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
} }
// Could also be a fn ptr or extern static // Could also be a fn ptr or extern static
match self.tcx.alloc_map.lock().get(id) { match self.tcx.alloc_map.lock().get(id) {
Some(AllocKind::Function(..)) => Ok((Size::ZERO, Align::from_bytes(1).unwrap())), Some(GlobalAlloc::Function(..)) => Ok((Size::ZERO, Align::from_bytes(1).unwrap())),
Some(AllocKind::Static(did)) => { Some(GlobalAlloc::Static(did)) => {
// The only way `get` couldn't have worked here is if this is an extern static // The only way `get` couldn't have worked here is if this is an extern static
assert!(self.tcx.is_foreign_item(did)); assert!(self.tcx.is_foreign_item(did));
// Use size and align of the type // Use size and align of the type
@ -456,7 +456,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
} }
trace!("reading fn ptr: {}", ptr.alloc_id); trace!("reading fn ptr: {}", ptr.alloc_id);
match self.tcx.alloc_map.lock().get(ptr.alloc_id) { match self.tcx.alloc_map.lock().get(ptr.alloc_id) {
Some(AllocKind::Function(instance)) => Ok(instance), Some(GlobalAlloc::Function(instance)) => Ok(instance),
_ => Err(InterpError::ExecuteMemory.into()), _ => Err(InterpError::ExecuteMemory.into()),
} }
} }
@ -554,16 +554,16 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
Err(()) => { Err(()) => {
// static alloc? // static alloc?
match self.tcx.alloc_map.lock().get(id) { match self.tcx.alloc_map.lock().get(id) {
Some(AllocKind::Memory(alloc)) => { Some(GlobalAlloc::Memory(alloc)) => {
self.dump_alloc_helper( self.dump_alloc_helper(
&mut allocs_seen, &mut allocs_to_print, &mut allocs_seen, &mut allocs_to_print,
msg, alloc, " (immutable)".to_owned() msg, alloc, " (immutable)".to_owned()
); );
} }
Some(AllocKind::Function(func)) => { Some(GlobalAlloc::Function(func)) => {
trace!("{} {}", msg, func); trace!("{} {}", msg, func);
} }
Some(AllocKind::Static(did)) => { Some(GlobalAlloc::Static(did)) => {
trace!("{} {:?}", msg, did); trace!("{} {:?}", msg, did);
} }
None => { None => {

View file

@ -550,7 +550,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
ConstValue::Slice { data, start, end } => ConstValue::Slice { data, start, end } =>
Operand::Immediate(Immediate::ScalarPair( Operand::Immediate(Immediate::ScalarPair(
Scalar::from(Pointer::new( Scalar::from(Pointer::new(
self.tcx.alloc_map.lock().allocate(data), self.tcx.alloc_map.lock().create_memory_alloc(data),
Size::from_bytes(start as u64), Size::from_bytes(start as u64),
)).with_default_tag().into(), )).with_default_tag().into(),
Scalar::from_uint( Scalar::from_uint(

View file

@ -597,7 +597,7 @@ where
// want! This way, computing statics works concistently between codegen // want! This way, computing statics works concistently between codegen
// and miri: They use the same query to eventually obtain a `ty::Const` // and miri: They use the same query to eventually obtain a `ty::Const`
// and use that for further computation. // and use that for further computation.
let alloc = self.tcx.alloc_map.lock().intern_static(cid.instance.def_id()); let alloc = self.tcx.alloc_map.lock().create_static_alloc(cid.instance.def_id());
MPlaceTy::from_aligned_ptr(Pointer::from(alloc).with_default_tag(), layout) MPlaceTy::from_aligned_ptr(Pointer::from(alloc).with_default_tag(), layout)
} }
}) })

View file

@ -8,7 +8,7 @@ use rustc::ty::layout::{self, Size, Align, TyLayout, LayoutOf, VariantIdx};
use rustc::ty; use rustc::ty;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc::mir::interpret::{ use rustc::mir::interpret::{
Scalar, AllocKind, EvalResult, InterpError, CheckInAllocMsg, Scalar, GlobalAlloc, EvalResult, InterpError, CheckInAllocMsg,
}; };
use super::{ use super::{
@ -403,7 +403,7 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>
"integer pointer in non-ZST reference", self.path); "integer pointer in non-ZST reference", self.path);
// Skip validation entirely for some external statics // 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.alloc_map.lock().get(ptr.alloc_id);
if let Some(AllocKind::Static(did)) = alloc_kind { if let Some(GlobalAlloc::Static(did)) = alloc_kind {
// `extern static` cannot be validated as they have no body. // `extern static` cannot be validated as they have no body.
// FIXME: Statics from other crates are also skipped. // FIXME: Statics from other crates are also skipped.
// They might be checked at a different type, but for now we // They might be checked at a different type, but for now we

View file

@ -187,7 +187,7 @@ use rustc::session::config::EntryFnType;
use rustc::mir::{self, Location, Place, PlaceBase, Promoted, Static, StaticKind}; use rustc::mir::{self, Location, Place, PlaceBase, Promoted, Static, StaticKind};
use rustc::mir::visit::Visitor as MirVisitor; use rustc::mir::visit::Visitor as MirVisitor;
use rustc::mir::mono::MonoItem; use rustc::mir::mono::MonoItem;
use rustc::mir::interpret::{Scalar, GlobalId, AllocKind, ErrorHandled}; use rustc::mir::interpret::{Scalar, GlobalId, GlobalAlloc, ErrorHandled};
use crate::monomorphize::{self, Instance}; use crate::monomorphize::{self, Instance};
use rustc::util::nodemap::{FxHashSet, FxHashMap, DefIdMap}; use rustc::util::nodemap::{FxHashSet, FxHashMap, DefIdMap};
@ -1183,20 +1183,20 @@ fn collect_miri<'a, 'tcx>(
) { ) {
let alloc_kind = tcx.alloc_map.lock().get(alloc_id); let alloc_kind = tcx.alloc_map.lock().get(alloc_id);
match alloc_kind { match alloc_kind {
Some(AllocKind::Static(did)) => { Some(GlobalAlloc::Static(did)) => {
let instance = Instance::mono(tcx, did); let instance = Instance::mono(tcx, did);
if should_monomorphize_locally(tcx, &instance) { if should_monomorphize_locally(tcx, &instance) {
trace!("collecting static {:?}", did); trace!("collecting static {:?}", did);
output.push(MonoItem::Static(did)); output.push(MonoItem::Static(did));
} }
} }
Some(AllocKind::Memory(alloc)) => { Some(GlobalAlloc::Memory(alloc)) => {
trace!("collecting {:?} with {:#?}", alloc_id, alloc); trace!("collecting {:?} with {:#?}", alloc_id, alloc);
for &((), inner) in alloc.relocations.values() { for &((), inner) in alloc.relocations.values() {
collect_miri(tcx, inner, output); collect_miri(tcx, inner, output);
} }
}, },
Some(AllocKind::Function(fn_instance)) => { Some(GlobalAlloc::Function(fn_instance)) => {
if should_monomorphize_locally(tcx, &fn_instance) { if should_monomorphize_locally(tcx, &fn_instance) {
trace!("collecting {:?} with {:#?}", alloc_id, fn_instance); trace!("collecting {:?} with {:#?}", alloc_id, fn_instance);
output.push(create_fn_mono_item(fn_instance)); output.push(create_fn_mono_item(fn_instance));