about summary refs log tree commit diff
path: root/compiler/rustc_const_eval
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-07-16 02:41:07 +0000
committerbors <bors@rust-lang.org>2024-07-16 02:41:07 +0000
commit5c8488605624d67b272953bc21d41db60dbd5654 (patch)
treeee0a6bc11c65685c8d8b8ff82e172dfa199afab5 /compiler/rustc_const_eval
parentcae4a84146c88cf917fa102c97ad9427591f6040 (diff)
parente595f3d13f0491186577d7b6e0290f31791f5059 (diff)
downloadrust-5c8488605624d67b272953bc21d41db60dbd5654.tar.gz
rust-5c8488605624d67b272953bc21d41db60dbd5654.zip
Auto merge of #127638 - adwinwhite:cache_string, r=oli-obk
Add cache for `allocate_str`

Best effort cache for string allocation in const eval.

Fixes [rust-lang/miri#3470](https://github.com/rust-lang/miri/issues/3470).
Diffstat (limited to 'compiler/rustc_const_eval')
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs14
1 files changed, 13 insertions, 1 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index baaee67e787..33c25b746cc 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -995,13 +995,25 @@ where
     }
 
     /// Returns a wide MPlace of type `str` to a new 1-aligned allocation.
+    /// Immutable strings are deduplicated and stored in global memory.
     pub fn allocate_str(
         &mut self,
         str: &str,
         kind: MemoryKind<M::MemoryKind>,
         mutbl: Mutability,
     ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
-        let ptr = self.allocate_bytes_ptr(str.as_bytes(), Align::ONE, kind, mutbl)?;
+        let tcx = self.tcx.tcx;
+
+        // Use cache for immutable strings.
+        let ptr = if mutbl.is_not() {
+            // Use dedup'd allocation function.
+            let id = tcx.allocate_bytes_dedup(str.as_bytes());
+
+            // Turn untagged "global" pointers (obtained via `tcx`) into the machine pointer to the allocation.
+            M::adjust_alloc_root_pointer(&self, Pointer::from(id), Some(kind))?
+        } else {
+            self.allocate_bytes_ptr(str.as_bytes(), Align::ONE, kind, mutbl)?
+        };
         let meta = Scalar::from_target_usize(u64::try_from(str.len()).unwrap(), self);
         let layout = self.layout_of(self.tcx.types.str_).unwrap();
         Ok(self.ptr_with_meta_to_mplace(ptr.into(), MemPlaceMeta::Meta(meta), layout))