Rollup merge of #73458 - tmiasko:arena-layout, r=matthewjasper
Use alloc::Layout in DroplessArena API
This commit is contained in:
commit
fd1c7835a3
@ -22,6 +22,7 @@
|
||||
use rustc_data_structures::cold_path;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use std::alloc::Layout;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::cmp;
|
||||
use std::intrinsics;
|
||||
@ -363,13 +364,15 @@ fn grow(&self, additional: usize) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Allocates a byte slice with specified size and alignment from the
|
||||
/// current memory chunk. Returns `None` if there is no free space left to
|
||||
/// satisfy the request.
|
||||
/// Allocates a byte slice with specified layout from the current memory
|
||||
/// chunk. Returns `None` if there is no free space left to satisfy the
|
||||
/// request.
|
||||
#[inline]
|
||||
fn alloc_raw_without_grow(&self, bytes: usize, align: usize) -> Option<*mut u8> {
|
||||
fn alloc_raw_without_grow(&self, layout: Layout) -> Option<*mut u8> {
|
||||
let ptr = self.ptr.get() as usize;
|
||||
let end = self.end.get() as usize;
|
||||
let align = layout.align();
|
||||
let bytes = layout.size();
|
||||
// The allocation request fits into the current chunk iff:
|
||||
//
|
||||
// let aligned = align_to(ptr, align);
|
||||
@ -390,15 +393,15 @@ fn alloc_raw_without_grow(&self, bytes: usize, align: usize) -> Option<*mut u8>
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn alloc_raw(&self, bytes: usize, align: usize) -> *mut u8 {
|
||||
assert!(bytes != 0);
|
||||
pub fn alloc_raw(&self, layout: Layout) -> *mut u8 {
|
||||
assert!(layout.size() != 0);
|
||||
loop {
|
||||
if let Some(a) = self.alloc_raw_without_grow(bytes, align) {
|
||||
if let Some(a) = self.alloc_raw_without_grow(layout) {
|
||||
break a;
|
||||
}
|
||||
// No free space left. Allocate a new chunk to satisfy the request.
|
||||
// On failure the grow will panic or abort.
|
||||
self.grow(bytes);
|
||||
self.grow(layout.size());
|
||||
}
|
||||
}
|
||||
|
||||
@ -406,7 +409,7 @@ pub fn alloc_raw(&self, bytes: usize, align: usize) -> *mut u8 {
|
||||
pub fn alloc<T>(&self, object: T) -> &mut T {
|
||||
assert!(!mem::needs_drop::<T>());
|
||||
|
||||
let mem = self.alloc_raw(mem::size_of::<T>(), mem::align_of::<T>()) as *mut T;
|
||||
let mem = self.alloc_raw(Layout::for_value::<T>(&object)) as *mut T;
|
||||
|
||||
unsafe {
|
||||
// Write into uninitialized memory.
|
||||
@ -431,7 +434,7 @@ pub fn alloc_slice<T>(&self, slice: &[T]) -> &mut [T]
|
||||
assert!(mem::size_of::<T>() != 0);
|
||||
assert!(!slice.is_empty());
|
||||
|
||||
let mem = self.alloc_raw(slice.len() * mem::size_of::<T>(), mem::align_of::<T>()) as *mut T;
|
||||
let mem = self.alloc_raw(Layout::for_value::<[T]>(slice)) as *mut T;
|
||||
|
||||
unsafe {
|
||||
mem.copy_from_nonoverlapping(slice.as_ptr(), slice.len());
|
||||
@ -477,8 +480,8 @@ pub fn alloc_from_iter<T, I: IntoIterator<Item = T>>(&self, iter: I) -> &mut [T]
|
||||
if len == 0 {
|
||||
return &mut [];
|
||||
}
|
||||
let size = len.checked_mul(mem::size_of::<T>()).unwrap();
|
||||
let mem = self.alloc_raw(size, mem::align_of::<T>()) as *mut T;
|
||||
|
||||
let mem = self.alloc_raw(Layout::array::<T>(len).unwrap()) as *mut T;
|
||||
unsafe { self.write_from_iter(iter, len, mem) }
|
||||
}
|
||||
(_, _) => {
|
||||
@ -491,9 +494,8 @@ pub fn alloc_from_iter<T, I: IntoIterator<Item = T>>(&self, iter: I) -> &mut [T]
|
||||
// the content of the SmallVec
|
||||
unsafe {
|
||||
let len = vec.len();
|
||||
let start_ptr = self
|
||||
.alloc_raw(len * mem::size_of::<T>(), mem::align_of::<T>())
|
||||
as *mut T;
|
||||
let start_ptr =
|
||||
self.alloc_raw(Layout::for_value::<[T]>(vec.as_slice())) as *mut T;
|
||||
vec.as_ptr().copy_to_nonoverlapping(start_ptr, len);
|
||||
vec.set_len(0);
|
||||
slice::from_raw_parts_mut(start_ptr, len)
|
||||
@ -537,7 +539,7 @@ pub struct DropArena {
|
||||
impl DropArena {
|
||||
#[inline]
|
||||
pub unsafe fn alloc<T>(&self, object: T) -> &mut T {
|
||||
let mem = self.arena.alloc_raw(mem::size_of::<T>(), mem::align_of::<T>()) as *mut T;
|
||||
let mem = self.arena.alloc_raw(Layout::new::<T>()) as *mut T;
|
||||
// Write into uninitialized memory.
|
||||
ptr::write(mem, object);
|
||||
let result = &mut *mem;
|
||||
@ -557,10 +559,7 @@ pub unsafe fn alloc_from_iter<T, I: IntoIterator<Item = T>>(&self, iter: I) -> &
|
||||
}
|
||||
let len = vec.len();
|
||||
|
||||
let start_ptr = self
|
||||
.arena
|
||||
.alloc_raw(len.checked_mul(mem::size_of::<T>()).unwrap(), mem::align_of::<T>())
|
||||
as *mut T;
|
||||
let start_ptr = self.arena.alloc_raw(Layout::array::<T>(len).unwrap()) as *mut T;
|
||||
|
||||
let mut destructors = self.destructors.borrow_mut();
|
||||
// Reserve space for the destructors so we can't panic while adding them
|
||||
|
@ -2,7 +2,8 @@
|
||||
|
||||
use rustc_serialize::{Encodable, Encoder};
|
||||
|
||||
use std::cmp::{self, Ordering};
|
||||
use std::alloc::Layout;
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::iter;
|
||||
@ -43,17 +44,9 @@ pub(super) fn from_arena<'tcx>(arena: &'tcx Arena<'tcx>, slice: &[T]) -> &'tcx L
|
||||
assert!(mem::size_of::<T>() != 0);
|
||||
assert!(!slice.is_empty());
|
||||
|
||||
// Align up the size of the len (usize) field
|
||||
let align = mem::align_of::<T>();
|
||||
let align_mask = align - 1;
|
||||
let offset = mem::size_of::<usize>();
|
||||
let offset = (offset + align_mask) & !align_mask;
|
||||
|
||||
let size = offset + slice.len() * mem::size_of::<T>();
|
||||
|
||||
let mem = arena
|
||||
.dropless
|
||||
.alloc_raw(size, cmp::max(mem::align_of::<T>(), mem::align_of::<usize>()));
|
||||
let (layout, _offset) =
|
||||
Layout::new::<usize>().extend(Layout::for_value::<[T]>(slice)).unwrap();
|
||||
let mem = arena.dropless.alloc_raw(layout);
|
||||
unsafe {
|
||||
let result = &mut *(mem as *mut List<T>);
|
||||
// Write the length
|
||||
|
Loading…
Reference in New Issue
Block a user