@@ -210,13 +210,11 @@ impl<Prov> Allocation<Prov> {
210210 let slice: Cow < ' a , [ u8 ] > = slice. into ( ) ;
211211 let size = Size :: from_bytes ( slice. len ( ) ) ;
212212 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+ } ;
220218
221219 let mut bytes = vec_align. into_boxed_slice ( ) ;
222220 assert ! ( bytes. as_ptr( ) as u64 % align. bytes( ) == 0 ) ;
@@ -242,29 +240,28 @@ impl<Prov> Allocation<Prov> {
242240 /// If `panic_on_fail` is true, this will never return `Err`.
243241 pub fn uninit < ' tcx > ( size : Size , align : Align , panic_on_fail : bool ) -> InterpResult < ' tcx , Self > {
244242 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+ } ;
252262
253263 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 ) ;
268265 Ok ( Allocation {
269266 bytes,
270267 relocations : Relocations :: new ( ) ,
@@ -292,7 +289,7 @@ impl Allocation {
292289
293290 let mut vec_align: Vec < u8 > = Vec :: with_capacity ( count_align) ;
294291 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 ) ;
296293
297294 vec_align[ ..self . bytes . len ( ) ] . copy_from_slice ( & self . bytes ) ;
298295 let mut bytes = vec_align. into_boxed_slice ( ) ;
0 commit comments