@@ -27,12 +27,20 @@ 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
+ /// Used for giving extra metadata on creation. Miri uses this to allow
31
+ /// machine memory to be allocated separately from other allocations.
32
+ type AllocParams ;
33
+
30
34
/// Create an `AllocBytes` from a slice of `u8`.
31
- fn from_bytes < ' a > ( slice : impl Into < Cow < ' a , [ u8 ] > > , _align : Align ) -> Self ;
35
+ fn from_bytes < ' a > (
36
+ slice : impl Into < Cow < ' a , [ u8 ] > > ,
37
+ _align : Align ,
38
+ _params : Self :: AllocParams ,
39
+ ) -> Self ;
32
40
33
41
/// Create a zeroed `AllocBytes` of the specified size and alignment.
34
42
/// Returns `None` if we ran out of memory on the host.
35
- fn zeroed ( size : Size , _align : Align ) -> Option < Self > ;
43
+ fn zeroed ( size : Size , _align : Align , _params : Self :: AllocParams ) -> Option < Self > ;
36
44
37
45
/// Gives direct access to the raw underlying storage.
38
46
///
@@ -51,11 +59,13 @@ pub trait AllocBytes: Clone + fmt::Debug + Deref<Target = [u8]> + DerefMut<Targe
51
59
52
60
/// Default `bytes` for `Allocation` is a `Box<u8>`.
53
61
impl AllocBytes for Box < [ u8 ] > {
54
- fn from_bytes < ' a > ( slice : impl Into < Cow < ' a , [ u8 ] > > , _align : Align ) -> Self {
62
+ type AllocParams = ( ) ;
63
+
64
+ fn from_bytes < ' a > ( slice : impl Into < Cow < ' a , [ u8 ] > > , _align : Align , _params : ( ) ) -> Self {
55
65
Box :: < [ u8 ] > :: from ( slice. into ( ) )
56
66
}
57
67
58
- fn zeroed ( size : Size , _align : Align ) -> Option < Self > {
68
+ fn zeroed ( size : Size , _align : Align , _params : ( ) ) -> Option < Self > {
59
69
let bytes = Box :: < [ u8 ] > :: try_new_zeroed_slice ( size. bytes ( ) . try_into ( ) . ok ( ) ?) . ok ( ) ?;
60
70
// SAFETY: the box was zero-allocated, which is a valid initial value for Box<[u8]>
61
71
let bytes = unsafe { bytes. assume_init ( ) } ;
@@ -172,9 +182,8 @@ fn all_zero(buf: &[u8]) -> bool {
172
182
}
173
183
174
184
/// 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 >
185
+ impl < Prov : Provenance , Extra , E : Encoder > Encodable < E > for Allocation < Prov , Extra , Box < [ u8 ] > >
176
186
where
177
- Bytes : AllocBytes ,
178
187
ProvenanceMap < Prov > : Encodable < E > ,
179
188
Extra : Encodable < E > ,
180
189
{
@@ -192,9 +201,8 @@ where
192
201
}
193
202
}
194
203
195
- impl < Prov : Provenance , Extra , Bytes , D : Decoder > Decodable < D > for Allocation < Prov , Extra , Bytes >
204
+ impl < Prov : Provenance , Extra , D : Decoder > Decodable < D > for Allocation < Prov , Extra , Box < [ u8 ] > >
196
205
where
197
- Bytes : AllocBytes ,
198
206
ProvenanceMap < Prov > : Decodable < D > ,
199
207
Extra : Decodable < D > ,
200
208
{
@@ -203,7 +211,7 @@ where
203
211
204
212
let len = decoder. read_usize ( ) ;
205
213
let bytes = if all_zero { vec ! [ 0u8 ; len] } else { decoder. read_raw_bytes ( len) . to_vec ( ) } ;
206
- let bytes = Bytes :: from_bytes ( bytes, align) ;
214
+ let bytes = < Box < [ u8 ] > as AllocBytes > :: from_bytes ( bytes, align, ( ) ) ;
207
215
208
216
let provenance = Decodable :: decode ( decoder) ;
209
217
let init_mask = Decodable :: decode ( decoder) ;
@@ -395,8 +403,9 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
395
403
slice : impl Into < Cow < ' a , [ u8 ] > > ,
396
404
align : Align ,
397
405
mutability : Mutability ,
406
+ params : <Bytes as AllocBytes >:: AllocParams ,
398
407
) -> Self {
399
- let bytes = Bytes :: from_bytes ( slice, align) ;
408
+ let bytes = Bytes :: from_bytes ( slice, align, params ) ;
400
409
let size = Size :: from_bytes ( bytes. len ( ) ) ;
401
410
Self {
402
411
bytes,
@@ -408,14 +417,18 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
408
417
}
409
418
}
410
419
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 )
420
+ pub fn from_bytes_byte_aligned_immutable < ' a > (
421
+ slice : impl Into < Cow < ' a , [ u8 ] > > ,
422
+ params : <Bytes as AllocBytes >:: AllocParams ,
423
+ ) -> Self {
424
+ Allocation :: from_bytes ( slice, Align :: ONE , Mutability :: Not , params)
413
425
}
414
426
415
427
fn new_inner < R > (
416
428
size : Size ,
417
429
align : Align ,
418
430
init : AllocInit ,
431
+ params : <Bytes as AllocBytes >:: AllocParams ,
419
432
fail : impl FnOnce ( ) -> R ,
420
433
) -> Result < Self , R > {
421
434
// We raise an error if we cannot create the allocation on the host.
@@ -424,7 +437,7 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
424
437
// deterministic. However, we can be non-deterministic here because all uses of const
425
438
// evaluation (including ConstProp!) will make compilation fail (via hard error
426
439
// or ICE) upon encountering a `MemoryExhausted` error.
427
- let bytes = Bytes :: zeroed ( size, align) . ok_or_else ( fail) ?;
440
+ let bytes = Bytes :: zeroed ( size, align, params ) . ok_or_else ( fail) ?;
428
441
429
442
Ok ( Allocation {
430
443
bytes,
@@ -444,8 +457,13 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
444
457
445
458
/// Try to create an Allocation of `size` bytes, failing if there is not enough memory
446
459
/// 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, || {
460
+ pub fn try_new < ' tcx > (
461
+ size : Size ,
462
+ align : Align ,
463
+ init : AllocInit ,
464
+ params : <Bytes as AllocBytes >:: AllocParams ,
465
+ ) -> InterpResult < ' tcx , Self > {
466
+ Self :: new_inner ( size, align, init, params, || {
449
467
ty:: tls:: with ( |tcx| tcx. dcx ( ) . delayed_bug ( "exhausted memory during interpretation" ) ) ;
450
468
InterpErrorKind :: ResourceExhaustion ( ResourceExhaustionInfo :: MemoryExhausted )
451
469
} )
@@ -457,8 +475,13 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
457
475
///
458
476
/// Example use case: To obtain an Allocation filled with specific data,
459
477
/// 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, || {
478
+ pub fn new (
479
+ size : Size ,
480
+ align : Align ,
481
+ init : AllocInit ,
482
+ params : <Bytes as AllocBytes >:: AllocParams ,
483
+ ) -> Self {
484
+ match Self :: new_inner ( size, align, init, params, || {
462
485
panic ! (
463
486
"interpreter ran out of memory: cannot create allocation of {} bytes" ,
464
487
size. bytes( )
0 commit comments