Skip to content

Commit

Permalink
Rollup merge of rust-lang#133861 - shamb0:refactor_InterpCx_allocate_…
Browse files Browse the repository at this point in the history
…str, r=RalfJung

Add allocate_bytes and refactor allocate_str in InterpCx for raw byte…

Fixes rust-lang/miri#4025

This PR introduces a new `allocate_bytes` function in InterpCx and refactors `allocate_str` to use it internally. This change improves memory allocation handling in the interpreter by:

1. Adding `allocate_bytes`:
   - Direct byte slice allocation support
   - Handles both mutable and immutable allocations
   - Maintains proper memory alignment and deduplication

2. Refactoring `allocate_str`:
   - Now uses `allocate_bytes` internally
   - Adds string-specific metadata handling
   - Preserves existing string allocation behavior

This is part 1 of the planned changes to improve timezone string handling in Miri. A follow-up PR will update Miri's timezone logic to use this new allocation mechanism.

Related: rust-lang/miri#4069
  • Loading branch information
matthiaskrgr authored Dec 8, 2024
2 parents a369714 + 9b07e75 commit 0d26662
Showing 1 changed file with 32 additions and 13 deletions.
45 changes: 32 additions & 13 deletions compiler/rustc_const_eval/src/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1018,29 +1018,48 @@ where
self.allocate_dyn(layout, kind, MemPlaceMeta::None)
}

/// 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(
/// Allocates a sequence of bytes in the interpreter's memory.
/// For immutable allocations, uses deduplication to reuse existing memory.
/// For mutable allocations, creates a new unique allocation.
pub fn allocate_bytes(
&mut self,
str: &str,
bytes: &[u8],
align: Align,
kind: MemoryKind<M::MemoryKind>,
mutbl: Mutability,
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
let tcx = self.tcx.tcx;

) -> InterpResult<'tcx, Pointer<M::Provenance>> {
// Use cache for immutable strings.
let ptr = if mutbl.is_not() {
if mutbl.is_not() {
// Use dedup'd allocation function.
let salt = M::get_global_alloc_salt(self, None);
let id = tcx.allocate_bytes_dedup(str.as_bytes(), salt);
let id = self.tcx.allocate_bytes_dedup(bytes, salt);

// 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))?
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);
// Allocate new memory for mutable data.
self.allocate_bytes_ptr(bytes, align, kind, mutbl)
}
}

/// Allocates a string in the interpreter's memory with metadata for length.
/// Uses `allocate_bytes` internally but adds string-specific metadata handling.
pub fn allocate_str(
&mut self,
str: &str,
kind: MemoryKind<M::MemoryKind>,
mutbl: Mutability,
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
let bytes = str.as_bytes();
let ptr = self.allocate_bytes(bytes, Align::ONE, kind, mutbl)?;

// Create length metadata for the string.
let meta = Scalar::from_target_usize(u64::try_from(bytes.len()).unwrap(), self);

// Get layout for Rust's str type.
let layout = self.layout_of(self.tcx.types.str_).unwrap();

// Combine pointer and metadata into a wide pointer.
interp_ok(self.ptr_with_meta_to_mplace(
ptr.into(),
MemPlaceMeta::Meta(meta),
Expand Down

0 comments on commit 0d26662

Please sign in to comment.