@@ -27,12 +27,21 @@ use crate::ty;
2727
2828/// Functionality required for the bytes of an `Allocation`.
2929pub trait AllocBytes : Clone + fmt:: Debug + Deref < Target = [ u8 ] > + DerefMut < Target = [ u8 ] > {
30+ /// The type of extra parameters passed in when creating an allocation.
31+ /// Can be used by `interpret::Machine` instances to make runtime-configuration-dependent
32+ /// decisions about the allocation strategy.
33+ type AllocParams ;
34+
3035 /// Create an `AllocBytes` from a slice of `u8`.
31- fn from_bytes < ' a > ( slice : impl Into < Cow < ' a , [ u8 ] > > , _align : Align ) -> Self ;
36+ fn from_bytes < ' a > (
37+ slice : impl Into < Cow < ' a , [ u8 ] > > ,
38+ _align : Align ,
39+ _params : Self :: AllocParams ,
40+ ) -> Self ;
3241
3342 /// Create a zeroed `AllocBytes` of the specified size and alignment.
3443 /// Returns `None` if we ran out of memory on the host.
35- fn zeroed ( size : Size , _align : Align ) -> Option < Self > ;
44+ fn zeroed ( size : Size , _align : Align , _params : Self :: AllocParams ) -> Option < Self > ;
3645
3746 /// Gives direct access to the raw underlying storage.
3847 ///
@@ -51,11 +60,13 @@ pub trait AllocBytes: Clone + fmt::Debug + Deref<Target = [u8]> + DerefMut<Targe
5160
5261/// Default `bytes` for `Allocation` is a `Box<u8>`.
5362impl AllocBytes for Box < [ u8 ] > {
54- fn from_bytes < ' a > ( slice : impl Into < Cow < ' a , [ u8 ] > > , _align : Align ) -> Self {
63+ type AllocParams = ( ) ;
64+
65+ fn from_bytes < ' a > ( slice : impl Into < Cow < ' a , [ u8 ] > > , _align : Align , _params : ( ) ) -> Self {
5566 Box :: < [ u8 ] > :: from ( slice. into ( ) )
5667 }
5768
58- fn zeroed ( size : Size , _align : Align ) -> Option < Self > {
69+ fn zeroed ( size : Size , _align : Align , _params : ( ) ) -> Option < Self > {
5970 let bytes = Box :: < [ u8 ] > :: try_new_zeroed_slice ( size. bytes ( ) . try_into ( ) . ok ( ) ?) . ok ( ) ?;
6071 // SAFETY: the box was zero-allocated, which is a valid initial value for Box<[u8]>
6172 let bytes = unsafe { bytes. assume_init ( ) } ;
@@ -172,9 +183,8 @@ fn all_zero(buf: &[u8]) -> bool {
172183}
173184
174185/// Custom encoder for [`Allocation`] to more efficiently represent the case where all bytes are 0.
175- impl < Prov : Provenance , Extra , Bytes , E : Encoder > Encodable < E > for Allocation < Prov , Extra , Bytes >
186+ impl < Prov : Provenance , Extra , E : Encoder > Encodable < E > for Allocation < Prov , Extra , Box < [ u8 ] > >
176187where
177- Bytes : AllocBytes ,
178188 ProvenanceMap < Prov > : Encodable < E > ,
179189 Extra : Encodable < E > ,
180190{
@@ -192,9 +202,8 @@ where
192202 }
193203}
194204
195- impl < Prov : Provenance , Extra , Bytes , D : Decoder > Decodable < D > for Allocation < Prov , Extra , Bytes >
205+ impl < Prov : Provenance , Extra , D : Decoder > Decodable < D > for Allocation < Prov , Extra , Box < [ u8 ] > >
196206where
197- Bytes : AllocBytes ,
198207 ProvenanceMap < Prov > : Decodable < D > ,
199208 Extra : Decodable < D > ,
200209{
@@ -203,7 +212,7 @@ where
203212
204213 let len = decoder. read_usize ( ) ;
205214 let bytes = if all_zero { vec ! [ 0u8 ; len] } else { decoder. read_raw_bytes ( len) . to_vec ( ) } ;
206- let bytes = Bytes :: from_bytes ( bytes, align) ;
215+ let bytes = < Box < [ u8 ] > as AllocBytes > :: from_bytes ( bytes, align, ( ) ) ;
207216
208217 let provenance = Decodable :: decode ( decoder) ;
209218 let init_mask = Decodable :: decode ( decoder) ;
@@ -395,8 +404,9 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
395404 slice : impl Into < Cow < ' a , [ u8 ] > > ,
396405 align : Align ,
397406 mutability : Mutability ,
407+ params : <Bytes as AllocBytes >:: AllocParams ,
398408 ) -> Self {
399- let bytes = Bytes :: from_bytes ( slice, align) ;
409+ let bytes = Bytes :: from_bytes ( slice, align, params ) ;
400410 let size = Size :: from_bytes ( bytes. len ( ) ) ;
401411 Self {
402412 bytes,
@@ -408,14 +418,18 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
408418 }
409419 }
410420
411- pub fn from_bytes_byte_aligned_immutable < ' a > ( slice : impl Into < Cow < ' a , [ u8 ] > > ) -> Self {
412- Allocation :: from_bytes ( slice, Align :: ONE , Mutability :: Not )
421+ pub fn from_bytes_byte_aligned_immutable < ' a > (
422+ slice : impl Into < Cow < ' a , [ u8 ] > > ,
423+ params : <Bytes as AllocBytes >:: AllocParams ,
424+ ) -> Self {
425+ Allocation :: from_bytes ( slice, Align :: ONE , Mutability :: Not , params)
413426 }
414427
415428 fn new_inner < R > (
416429 size : Size ,
417430 align : Align ,
418431 init : AllocInit ,
432+ params : <Bytes as AllocBytes >:: AllocParams ,
419433 fail : impl FnOnce ( ) -> R ,
420434 ) -> Result < Self , R > {
421435 // We raise an error if we cannot create the allocation on the host.
@@ -424,7 +438,7 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
424438 // deterministic. However, we can be non-deterministic here because all uses of const
425439 // evaluation (including ConstProp!) will make compilation fail (via hard error
426440 // or ICE) upon encountering a `MemoryExhausted` error.
427- let bytes = Bytes :: zeroed ( size, align) . ok_or_else ( fail) ?;
441+ let bytes = Bytes :: zeroed ( size, align, params ) . ok_or_else ( fail) ?;
428442
429443 Ok ( Allocation {
430444 bytes,
@@ -444,8 +458,13 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
444458
445459 /// Try to create an Allocation of `size` bytes, failing if there is not enough memory
446460 /// available to the compiler to do so.
447- pub fn try_new < ' tcx > ( size : Size , align : Align , init : AllocInit ) -> InterpResult < ' tcx , Self > {
448- Self :: new_inner ( size, align, init, || {
461+ pub fn try_new < ' tcx > (
462+ size : Size ,
463+ align : Align ,
464+ init : AllocInit ,
465+ params : <Bytes as AllocBytes >:: AllocParams ,
466+ ) -> InterpResult < ' tcx , Self > {
467+ Self :: new_inner ( size, align, init, params, || {
449468 ty:: tls:: with ( |tcx| tcx. dcx ( ) . delayed_bug ( "exhausted memory during interpretation" ) ) ;
450469 InterpErrorKind :: ResourceExhaustion ( ResourceExhaustionInfo :: MemoryExhausted )
451470 } )
@@ -457,8 +476,13 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
457476 ///
458477 /// Example use case: To obtain an Allocation filled with specific data,
459478 /// first call this function and then call write_scalar to fill in the right data.
460- pub fn new ( size : Size , align : Align , init : AllocInit ) -> Self {
461- match Self :: new_inner ( size, align, init, || {
479+ pub fn new (
480+ size : Size ,
481+ align : Align ,
482+ init : AllocInit ,
483+ params : <Bytes as AllocBytes >:: AllocParams ,
484+ ) -> Self {
485+ match Self :: new_inner ( size, align, init, params, || {
462486 panic ! (
463487 "interpreter ran out of memory: cannot create allocation of {} bytes" ,
464488 size. bytes( )
0 commit comments