Skip to content

Commit 5093b2b

Browse files
committed
Add cache for allocate_str
1 parent 9387b0b commit 5093b2b

File tree

3 files changed

+22
-9
lines changed

3 files changed

+22
-9
lines changed

compiler/rustc_const_eval/src/interpret/place.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -1001,7 +1001,20 @@ where
10011001
kind: MemoryKind<M::MemoryKind>,
10021002
mutbl: Mutability,
10031003
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
1004-
let ptr = self.allocate_bytes_ptr(str.as_bytes(), Align::ONE, kind, mutbl)?;
1004+
let tcx = self.tcx.tcx;
1005+
1006+
// Use cache for immutable strings.
1007+
let ptr = if mutbl.is_not()
1008+
&& matches!(kind, MemoryKind::CallerLocation | MemoryKind::Machine(_))
1009+
{
1010+
// Same id for cached allocations.
1011+
let id = tcx.allocate_bytes(str.as_bytes());
1012+
1013+
// Turn untagged "global" pointers (obtained via `tcx`) into the machine pointer to the allocation.
1014+
M::adjust_alloc_root_pointer(&self, Pointer::from(id), Some(kind))?
1015+
} else {
1016+
self.allocate_bytes_ptr(str.as_bytes(), Align::ONE, kind, mutbl)?
1017+
};
10051018
let meta = Scalar::from_target_usize(u64::try_from(str.len()).unwrap(), self);
10061019
let layout = self.layout_of(self.tcx.types.str_).unwrap();
10071020
Ok(self.ptr_with_meta_to_mplace(ptr.into(), MemPlaceMeta::Meta(meta), layout))

compiler/rustc_middle/src/mir/interpret/mod.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,6 @@ pub(crate) struct AllocMap<'tcx> {
381381
alloc_map: FxHashMap<AllocId, GlobalAlloc<'tcx>>,
382382

383383
/// Used to ensure that statics and functions only get one associated `AllocId`.
384-
/// Should never contain a `GlobalAlloc::Memory`!
385384
//
386385
// FIXME: Should we just have two separate dedup maps for statics and functions each?
387386
dedup: FxHashMap<GlobalAlloc<'tcx>, AllocId>,
@@ -421,14 +420,8 @@ impl<'tcx> TyCtxt<'tcx> {
421420
}
422421

423422
/// Reserves a new ID *if* this allocation has not been dedup-reserved before.
424-
/// Should only be used for "symbolic" allocations (function pointers, vtables, statics), we
425-
/// don't want to dedup IDs for "real" memory!
426423
fn reserve_and_set_dedup(self, alloc: GlobalAlloc<'tcx>) -> AllocId {
427424
let mut alloc_map = self.alloc_map.lock();
428-
match alloc {
429-
GlobalAlloc::Function(..) | GlobalAlloc::Static(..) | GlobalAlloc::VTable(..) => {}
430-
GlobalAlloc::Memory(..) => bug!("Trying to dedup-reserve memory with real data!"),
431-
}
432425
if let Some(&alloc_id) = alloc_map.dedup.get(&alloc) {
433426
return alloc_id;
434427
}
@@ -439,6 +432,12 @@ impl<'tcx> TyCtxt<'tcx> {
439432
id
440433
}
441434

435+
/// Generates an `AllocId` for a memory allocation. If the exact same memory has been
436+
/// allocated before, this will return the same `AllocId`.
437+
pub fn reserve_and_set_memory_dedup(self, mem: ConstAllocation<'tcx>) -> AllocId {
438+
self.reserve_and_set_dedup(GlobalAlloc::Memory(mem))
439+
}
440+
442441
/// Generates an `AllocId` for a static or return a cached one in case this function has been
443442
/// called on the same static before.
444443
pub fn reserve_and_set_static_alloc(self, static_id: DefId) -> AllocId {

compiler/rustc_middle/src/ty/context.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1394,11 +1394,12 @@ impl<'tcx> TyCtxt<'tcx> {
13941394
}
13951395

13961396
/// Allocates a read-only byte or string literal for `mir::interpret`.
1397+
/// Returns the same `AllocId` if called again with the same bytes.
13971398
pub fn allocate_bytes(self, bytes: &[u8]) -> interpret::AllocId {
13981399
// Create an allocation that just contains these bytes.
13991400
let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes);
14001401
let alloc = self.mk_const_alloc(alloc);
1401-
self.reserve_and_set_memory_alloc(alloc)
1402+
self.reserve_and_set_memory_dedup(alloc)
14021403
}
14031404

14041405
/// Returns a range of the start/end indices specified with the

0 commit comments

Comments
 (0)