1
Fork 0

Add cache for allocate_str

This commit is contained in:
Adwin White 2024-07-12 13:08:05 +08:00
parent 03c2100ded
commit e595f3d13f
4 changed files with 28 additions and 10 deletions

View file

@ -393,7 +393,6 @@ pub(crate) struct AllocMap<'tcx> {
alloc_map: FxHashMap<AllocId, GlobalAlloc<'tcx>>,
/// Used to ensure that statics and functions only get one associated `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>,
@ -433,13 +432,13 @@ impl<'tcx> TyCtxt<'tcx> {
}
/// Reserves a new ID *if* this allocation has not been dedup-reserved before.
/// Should only be used for "symbolic" allocations (function pointers, vtables, statics), we
/// don't want to dedup IDs for "real" memory!
/// Should not be used for mutable memory.
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::VTable(..) => {}
GlobalAlloc::Memory(..) => bug!("Trying to dedup-reserve memory with real data!"),
if let GlobalAlloc::Memory(mem) = alloc {
if mem.inner().mutability.is_mut() {
bug!("trying to dedup-reserve mutable memory");
}
}
if let Some(&alloc_id) = alloc_map.dedup.get(&alloc) {
return alloc_id;
@ -451,6 +450,12 @@ impl<'tcx> TyCtxt<'tcx> {
id
}
/// Generates an `AllocId` for a memory allocation. If the exact same memory has been
/// allocated before, this will return the same `AllocId`.
pub fn reserve_and_set_memory_dedup(self, mem: ConstAllocation<'tcx>) -> AllocId {
self.reserve_and_set_dedup(GlobalAlloc::Memory(mem))
}
/// 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 reserve_and_set_static_alloc(self, static_id: DefId) -> AllocId {

View file

@ -1442,11 +1442,12 @@ impl<'tcx> TyCtxt<'tcx> {
}
/// Allocates a read-only byte or string literal for `mir::interpret`.
pub fn allocate_bytes(self, bytes: &[u8]) -> interpret::AllocId {
/// Returns the same `AllocId` if called again with the same bytes.
pub fn allocate_bytes_dedup(self, bytes: &[u8]) -> interpret::AllocId {
// Create an allocation that just contains these bytes.
let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes);
let alloc = self.mk_const_alloc(alloc);
self.reserve_and_set_memory_alloc(alloc)
self.reserve_and_set_memory_dedup(alloc)
}
/// Returns a range of the start/end indices specified with the