@@ -356,16 +356,27 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
356356
357357 // This returns some prepared `MiriAllocBytes`, either because `addr_from_alloc_id` reserved
358358 // memory space in the past, or by doing the pre-allocation right upon being called.
359- fn take_prepared_alloc_bytes ( & self , id : AllocId , kind : MemoryKind ) -> InterpResult < ' tcx , MiriAllocBytes > {
359+ fn get_global_alloc_bytes ( & self , id : AllocId , kind : MemoryKind , bytes : & [ u8 ] , align : Align ) -> InterpResult < ' tcx , MiriAllocBytes > {
360360 let ecx = self . eval_context_ref ( ) ;
361- // This additional call ensures that some `MiriAllocBytes` are prepared.
362- ecx. addr_from_alloc_id ( id, kind) ?;
363- let mut global_state = ecx. machine . alloc_addresses . borrow_mut ( ) ;
364- let prepared_alloc_bytes = global_state
365- . prepared_alloc_bytes
366- . remove ( & id)
367- . unwrap_or_else ( || panic ! ( "alloc bytes for {id:?} has not been prepared" ) ) ;
368- Ok ( prepared_alloc_bytes)
361+ Ok ( if ecx. machine . native_lib . is_some ( ) {
362+ // This additional call ensures that some `MiriAllocBytes` are always prepared.
363+ ecx. addr_from_alloc_id ( id, kind) ?;
364+ let mut global_state = ecx. machine . alloc_addresses . borrow_mut ( ) ;
365+ // The memory we need here will have already been allocated during an earlier call to
366+ // `global_root_pointer` for this allocation. So don't create a new `MiriAllocBytes` here, instead
367+ // fetch the previously prepared bytes from `prepared_alloc_bytes`.
368+ let mut prepared_alloc_bytes = global_state
369+ . prepared_alloc_bytes
370+ . remove ( & id)
371+ . unwrap_or_else ( || panic ! ( "alloc bytes for {id:?} have not been prepared" ) ) ;
372+ assert ! ( prepared_alloc_bytes. as_ptr( ) . is_aligned_to( align. bytes_usize( ) ) ) ;
373+ assert_eq ! ( prepared_alloc_bytes. len( ) , bytes. len( ) ) ;
374+ // SAFETY: `alloc_bytes` and `bytes` span the same number of bytes.
375+ unsafe { prepared_alloc_bytes. as_mut_ptr ( ) . copy_from ( bytes. as_ptr ( ) , bytes. len ( ) ) } ;
376+ prepared_alloc_bytes
377+ } else {
378+ MiriAllocBytes :: from_bytes ( std:: borrow:: Cow :: Borrowed ( & * bytes) , align)
379+ } )
369380 }
370381
371382 /// When a pointer is used for a memory access, this computes where in which allocation the
0 commit comments