Skip to content

Commit fd1c783

Browse files
authoredJun 20, 2020
Rollup merge of #73458 - tmiasko:arena-layout, r=matthewjasper
Use alloc::Layout in DroplessArena API
2 parents 61f8c3e + f488dfc commit fd1c783

File tree

2 files changed

+24
-32
lines changed

2 files changed

+24
-32
lines changed
 

‎src/librustc_arena/lib.rs

+19-20
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ extern crate alloc;
2222
use rustc_data_structures::cold_path;
2323
use smallvec::SmallVec;
2424

25+
use std::alloc::Layout;
2526
use std::cell::{Cell, RefCell};
2627
use std::cmp;
2728
use std::intrinsics;
@@ -363,13 +364,15 @@ impl DroplessArena {
363364
}
364365
}
365366

366-
/// Allocates a byte slice with specified size and alignment from the
367-
/// current memory chunk. Returns `None` if there is no free space left to
368-
/// satisfy the request.
367+
/// Allocates a byte slice with specified layout from the current memory
368+
/// chunk. Returns `None` if there is no free space left to satisfy the
369+
/// request.
369370
#[inline]
370-
fn alloc_raw_without_grow(&self, bytes: usize, align: usize) -> Option<*mut u8> {
371+
fn alloc_raw_without_grow(&self, layout: Layout) -> Option<*mut u8> {
371372
let ptr = self.ptr.get() as usize;
372373
let end = self.end.get() as usize;
374+
let align = layout.align();
375+
let bytes = layout.size();
373376
// The allocation request fits into the current chunk iff:
374377
//
375378
// let aligned = align_to(ptr, align);
@@ -390,23 +393,23 @@ impl DroplessArena {
390393
}
391394

392395
#[inline]
393-
pub fn alloc_raw(&self, bytes: usize, align: usize) -> *mut u8 {
394-
assert!(bytes != 0);
396+
pub fn alloc_raw(&self, layout: Layout) -> *mut u8 {
397+
assert!(layout.size() != 0);
395398
loop {
396-
if let Some(a) = self.alloc_raw_without_grow(bytes, align) {
399+
if let Some(a) = self.alloc_raw_without_grow(layout) {
397400
break a;
398401
}
399402
// No free space left. Allocate a new chunk to satisfy the request.
400403
// On failure the grow will panic or abort.
401-
self.grow(bytes);
404+
self.grow(layout.size());
402405
}
403406
}
404407

405408
#[inline]
406409
pub fn alloc<T>(&self, object: T) -> &mut T {
407410
assert!(!mem::needs_drop::<T>());
408411

409-
let mem = self.alloc_raw(mem::size_of::<T>(), mem::align_of::<T>()) as *mut T;
412+
let mem = self.alloc_raw(Layout::for_value::<T>(&object)) as *mut T;
410413

411414
unsafe {
412415
// Write into uninitialized memory.
@@ -431,7 +434,7 @@ impl DroplessArena {
431434
assert!(mem::size_of::<T>() != 0);
432435
assert!(!slice.is_empty());
433436

434-
let mem = self.alloc_raw(slice.len() * mem::size_of::<T>(), mem::align_of::<T>()) as *mut T;
437+
let mem = self.alloc_raw(Layout::for_value::<[T]>(slice)) as *mut T;
435438

436439
unsafe {
437440
mem.copy_from_nonoverlapping(slice.as_ptr(), slice.len());
@@ -477,8 +480,8 @@ impl DroplessArena {
477480
if len == 0 {
478481
return &mut [];
479482
}
480-
let size = len.checked_mul(mem::size_of::<T>()).unwrap();
481-
let mem = self.alloc_raw(size, mem::align_of::<T>()) as *mut T;
483+
484+
let mem = self.alloc_raw(Layout::array::<T>(len).unwrap()) as *mut T;
482485
unsafe { self.write_from_iter(iter, len, mem) }
483486
}
484487
(_, _) => {
@@ -491,9 +494,8 @@ impl DroplessArena {
491494
// the content of the SmallVec
492495
unsafe {
493496
let len = vec.len();
494-
let start_ptr = self
495-
.alloc_raw(len * mem::size_of::<T>(), mem::align_of::<T>())
496-
as *mut T;
497+
let start_ptr =
498+
self.alloc_raw(Layout::for_value::<[T]>(vec.as_slice())) as *mut T;
497499
vec.as_ptr().copy_to_nonoverlapping(start_ptr, len);
498500
vec.set_len(0);
499501
slice::from_raw_parts_mut(start_ptr, len)
@@ -537,7 +539,7 @@ pub struct DropArena {
537539
impl DropArena {
538540
#[inline]
539541
pub unsafe fn alloc<T>(&self, object: T) -> &mut T {
540-
let mem = self.arena.alloc_raw(mem::size_of::<T>(), mem::align_of::<T>()) as *mut T;
542+
let mem = self.arena.alloc_raw(Layout::new::<T>()) as *mut T;
541543
// Write into uninitialized memory.
542544
ptr::write(mem, object);
543545
let result = &mut *mem;
@@ -557,10 +559,7 @@ impl DropArena {
557559
}
558560
let len = vec.len();
559561

560-
let start_ptr = self
561-
.arena
562-
.alloc_raw(len.checked_mul(mem::size_of::<T>()).unwrap(), mem::align_of::<T>())
563-
as *mut T;
562+
let start_ptr = self.arena.alloc_raw(Layout::array::<T>(len).unwrap()) as *mut T;
564563

565564
let mut destructors = self.destructors.borrow_mut();
566565
// Reserve space for the destructors so we can't panic while adding them

‎src/librustc_middle/ty/list.rs

+5-12
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use crate::arena::Arena;
22

33
use rustc_serialize::{Encodable, Encoder};
44

5-
use std::cmp::{self, Ordering};
5+
use std::alloc::Layout;
6+
use std::cmp::Ordering;
67
use std::fmt;
78
use std::hash::{Hash, Hasher};
89
use std::iter;
@@ -43,17 +44,9 @@ impl<T: Copy> List<T> {
4344
assert!(mem::size_of::<T>() != 0);
4445
assert!(!slice.is_empty());
4546

46-
// Align up the size of the len (usize) field
47-
let align = mem::align_of::<T>();
48-
let align_mask = align - 1;
49-
let offset = mem::size_of::<usize>();
50-
let offset = (offset + align_mask) & !align_mask;
51-
52-
let size = offset + slice.len() * mem::size_of::<T>();
53-
54-
let mem = arena
55-
.dropless
56-
.alloc_raw(size, cmp::max(mem::align_of::<T>(), mem::align_of::<usize>()));
47+
let (layout, _offset) =
48+
Layout::new::<usize>().extend(Layout::for_value::<[T]>(slice)).unwrap();
49+
let mem = arena.dropless.alloc_raw(layout);
5750
unsafe {
5851
let result = &mut *(mem as *mut List<T>);
5952
// Write the length

0 commit comments

Comments
 (0)
Please sign in to comment.