Skip to content

Commit 95b1b58

Browse files
committed
Add cache for allocate_str
1 parent 9387b0b commit 95b1b58

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

compiler/rustc_const_eval/src/interpret/eval_context.rs

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::{fmt, mem};
44
use either::{Either, Left, Right};
55
use tracing::{debug, info, info_span, instrument, trace};
66

7+
use rustc_data_structures::fx::FxHashMap;
78
use rustc_errors::DiagCtxtHandle;
89
use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
910
use rustc_index::IndexVec;
@@ -52,6 +53,9 @@ pub struct InterpCx<'tcx, M: Machine<'tcx>> {
5253

5354
/// The recursion limit (cached from `tcx.recursion_limit(())`)
5455
pub recursion_limit: Limit,
56+
57+
/// The string allocation cache.
58+
pub(super) str_alloc_cache: FxHashMap<Vec<u8>, Pointer<M::Provenance>>,
5559
}
5660

5761
// The Phantomdata exists to prevent this type from being `Send`. If it were sent across a thread
@@ -501,6 +505,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
501505
param_env,
502506
memory: Memory::new(),
503507
recursion_limit: tcx.recursion_limit(),
508+
str_alloc_cache: FxHashMap::default(),
504509
}
505510
}
506511

compiler/rustc_const_eval/src/interpret/place.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -1001,7 +1001,21 @@ 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+
// Check cache to see if we had allocated for this string before.
1005+
let ptr = if mutbl.is_not()
1006+
&& matches!(kind, MemoryKind::CallerLocation | MemoryKind::Machine(_))
1007+
{
1008+
// We can't use entry API of HashMap due to mutable self borrow in `allocate_bytes_ptr`.
1009+
if let Some(cached_ptr) = self.str_alloc_cache.get(str.as_bytes()) {
1010+
*cached_ptr
1011+
} else {
1012+
let alloc_ptr = self.allocate_bytes_ptr(str.as_bytes(), Align::ONE, kind, mutbl)?;
1013+
self.str_alloc_cache.insert(str.as_bytes().to_vec(), alloc_ptr);
1014+
alloc_ptr
1015+
}
1016+
} else {
1017+
self.allocate_bytes_ptr(str.as_bytes(), Align::ONE, kind, mutbl)?.into()
1018+
};
10051019
let meta = Scalar::from_target_usize(u64::try_from(str.len()).unwrap(), self);
10061020
let layout = self.layout_of(self.tcx.types.str_).unwrap();
10071021
Ok(self.ptr_with_meta_to_mplace(ptr.into(), MemPlaceMeta::Meta(meta), layout))

0 commit comments

Comments
 (0)