@@ -27,12 +27,21 @@ use crate::ty;
27
27
28
28
/// Functionality required for the bytes of an `Allocation`.
29
29
pub 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
+
30
35
/// 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 ;
32
41
33
42
/// Create a zeroed `AllocBytes` of the specified size and alignment.
34
43
/// 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 > ;
36
45
37
46
/// Gives direct access to the raw underlying storage.
38
47
///
@@ -51,11 +60,13 @@ pub trait AllocBytes: Clone + fmt::Debug + Deref<Target = [u8]> + DerefMut<Targe
51
60
52
61
/// Default `bytes` for `Allocation` is a `Box<u8>`.
53
62
impl 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 {
55
66
Box :: < [ u8 ] > :: from ( slice. into ( ) )
56
67
}
57
68
58
- fn zeroed ( size : Size , _align : Align ) -> Option < Self > {
69
+ fn zeroed ( size : Size , _align : Align , _params : ( ) ) -> Option < Self > {
59
70
let bytes = Box :: < [ u8 ] > :: try_new_zeroed_slice ( size. bytes ( ) . try_into ( ) . ok ( ) ?) . ok ( ) ?;
60
71
// SAFETY: the box was zero-allocated, which is a valid initial value for Box<[u8]>
61
72
let bytes = unsafe { bytes. assume_init ( ) } ;
@@ -172,9 +183,8 @@ fn all_zero(buf: &[u8]) -> bool {
172
183
}
173
184
174
185
/// 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 ] > >
176
187
where
177
- Bytes : AllocBytes ,
178
188
ProvenanceMap < Prov > : Encodable < E > ,
179
189
Extra : Encodable < E > ,
180
190
{
@@ -192,9 +202,8 @@ where
192
202
}
193
203
}
194
204
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 ] > >
196
206
where
197
- Bytes : AllocBytes ,
198
207
ProvenanceMap < Prov > : Decodable < D > ,
199
208
Extra : Decodable < D > ,
200
209
{
@@ -203,7 +212,7 @@ where
203
212
204
213
let len = decoder. read_usize ( ) ;
205
214
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, ( ) ) ;
207
216
208
217
let provenance = Decodable :: decode ( decoder) ;
209
218
let init_mask = Decodable :: decode ( decoder) ;
@@ -395,8 +404,9 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
395
404
slice : impl Into < Cow < ' a , [ u8 ] > > ,
396
405
align : Align ,
397
406
mutability : Mutability ,
407
+ params : <Bytes as AllocBytes >:: AllocParams ,
398
408
) -> Self {
399
- let bytes = Bytes :: from_bytes ( slice, align) ;
409
+ let bytes = Bytes :: from_bytes ( slice, align, params ) ;
400
410
let size = Size :: from_bytes ( bytes. len ( ) ) ;
401
411
Self {
402
412
bytes,
@@ -408,14 +418,18 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
408
418
}
409
419
}
410
420
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)
413
426
}
414
427
415
428
fn new_inner < R > (
416
429
size : Size ,
417
430
align : Align ,
418
431
init : AllocInit ,
432
+ params : <Bytes as AllocBytes >:: AllocParams ,
419
433
fail : impl FnOnce ( ) -> R ,
420
434
) -> Result < Self , R > {
421
435
// 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> {
424
438
// deterministic. However, we can be non-deterministic here because all uses of const
425
439
// evaluation (including ConstProp!) will make compilation fail (via hard error
426
440
// 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) ?;
428
442
429
443
Ok ( Allocation {
430
444
bytes,
@@ -444,8 +458,13 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
444
458
445
459
/// Try to create an Allocation of `size` bytes, failing if there is not enough memory
446
460
/// 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, || {
449
468
ty:: tls:: with ( |tcx| tcx. dcx ( ) . delayed_bug ( "exhausted memory during interpretation" ) ) ;
450
469
InterpErrorKind :: ResourceExhaustion ( ResourceExhaustionInfo :: MemoryExhausted )
451
470
} )
@@ -457,8 +476,13 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
457
476
///
458
477
/// Example use case: To obtain an Allocation filled with specific data,
459
478
/// 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, || {
462
486
panic ! (
463
487
"interpreter ran out of memory: cannot create allocation of {} bytes" ,
464
488
size. bytes( )
0 commit comments