@@ -210,13 +210,11 @@ impl<Prov> Allocation<Prov> {
210
210
let slice: Cow < ' a , [ u8 ] > = slice. into ( ) ;
211
211
let size = Size :: from_bytes ( slice. len ( ) ) ;
212
212
let align_usize: usize = align. bytes ( ) . try_into ( ) . unwrap ( ) ;
213
- let count_align = ( ( slice. len ( ) / align_usize) + 1 ) * align_usize;
214
-
215
- let mut vec_align: Vec < u8 > = Vec :: with_capacity ( count_align) ;
216
- vec_align. resize ( count_align, 0 ) ;
217
- // TODO avoid excess initialization
218
- let ( buf, _len, _capacity) = vec_align. into_raw_parts ( ) ;
219
- vec_align = unsafe { Vec :: from_raw_parts ( buf as * mut u8 , size. bytes_usize ( ) , size. bytes_usize ( ) ) } ;
213
+ let layout = std:: alloc:: Layout :: from_size_align ( slice. len ( ) , align_usize) . unwrap ( ) ;
214
+ let vec_align = unsafe {
215
+ let buf = std:: alloc:: alloc ( layout) ;
216
+ Vec :: from_raw_parts ( buf as * mut u8 , size. bytes_usize ( ) , size. bytes_usize ( ) )
217
+ } ;
220
218
221
219
let mut bytes = vec_align. into_boxed_slice ( ) ;
222
220
assert ! ( bytes. as_ptr( ) as u64 % align. bytes( ) == 0 ) ;
@@ -242,29 +240,28 @@ impl<Prov> Allocation<Prov> {
242
240
/// If `panic_on_fail` is true, this will never return `Err`.
243
241
pub fn uninit < ' tcx > ( size : Size , align : Align , panic_on_fail : bool ) -> InterpResult < ' tcx , Self > {
244
242
let align_usize: usize = align. bytes ( ) . try_into ( ) . unwrap ( ) ;
245
- let count_align = ( ( size. bytes_usize ( ) / align_usize) + 1 ) * align_usize;
246
-
247
- // TODO this one is supposed to handle allocation failure, so do so.
248
- let mut vec_align: Vec < u8 > = Vec :: with_capacity ( count_align) ;
249
- vec_align. resize ( count_align, 0 ) ;
250
- let ( buf, _len, _capacity) = vec_align. into_raw_parts ( ) ;
251
- vec_align = unsafe { Vec :: from_raw_parts ( buf as * mut u8 , size. bytes_usize ( ) , size. bytes_usize ( ) ) } ;
243
+ let layout = std:: alloc:: Layout :: from_size_align ( size. bytes_usize ( ) , align_usize) . unwrap ( ) ;
244
+ let vec_align = unsafe {
245
+ // https://doc.rust-lang.org/nightly/std/alloc/trait.GlobalAlloc.html#tymethod.alloc
246
+ // std::alloc::alloc returns null to indicate an allocation failure:
247
+ // "Returning a null pointer indicates that either memory is exhausted
248
+ // or layout does not meet this allocator’s size or alignment constraints."
249
+ let buf = std:: alloc:: alloc ( layout) ;
250
+ // Handle allocation failure.
251
+ if buf. is_null ( ) {
252
+ if panic_on_fail {
253
+ panic ! ( "Allocation::uninit called with panic_on_fail had allocation failure" )
254
+ }
255
+ ty:: tls:: with ( |tcx| {
256
+ tcx. sess . delay_span_bug ( DUMMY_SP , "exhausted memory during interpretation" )
257
+ } ) ;
258
+ Err ( InterpError :: ResourceExhaustion ( ResourceExhaustionInfo :: MemoryExhausted ) ) ?
259
+ }
260
+ Vec :: from_raw_parts ( buf as * mut u8 , size. bytes_usize ( ) , size. bytes_usize ( ) )
261
+ } ;
252
262
253
263
let bytes = vec_align. into_boxed_slice ( ) ;
254
- Ok ( ( ) ) . map_err ( |_: ( ) | {
255
- // This results in an error that can happen non-deterministically, since the memory
256
- // available to the compiler can change between runs. Normally queries are always
257
- // deterministic. However, we can be non-deterministic here because all uses of const
258
- // evaluation (including ConstProp!) will make compilation fail (via hard error
259
- // or ICE) upon encountering a `MemoryExhausted` error.
260
- if panic_on_fail {
261
- panic ! ( "Allocation::uninit called with panic_on_fail had allocation failure" )
262
- }
263
- ty:: tls:: with ( |tcx| {
264
- tcx. sess . delay_span_bug ( DUMMY_SP , "exhausted memory during interpretation" )
265
- } ) ;
266
- InterpError :: ResourceExhaustion ( ResourceExhaustionInfo :: MemoryExhausted )
267
- } ) ?;
264
+ assert ! ( bytes. as_ptr( ) as u64 % align. bytes( ) == 0 ) ;
268
265
Ok ( Allocation {
269
266
bytes,
270
267
relocations : Relocations :: new ( ) ,
@@ -292,7 +289,7 @@ impl Allocation {
292
289
293
290
let mut vec_align: Vec < u8 > = Vec :: with_capacity ( count_align) ;
294
291
vec_align. resize ( count_align, 0 ) ;
295
- assert ! ( vec_align. as_ptr( ) as u64 % self . align . bytes ( ) == 0 ) ;
292
+ assert ! ( vec_align. as_ptr( ) as usize % align_usize == 0 ) ;
296
293
297
294
vec_align[ ..self . bytes . len ( ) ] . copy_from_slice ( & self . bytes ) ;
298
295
let mut bytes = vec_align. into_boxed_slice ( ) ;
0 commit comments