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:
parent
c28084ac16
commit
41c36fabef
9 changed files with 81 additions and 68 deletions
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue