Skip to content

Commit

Permalink
realloc with a new size only, not a full new layout.
Browse files Browse the repository at this point in the history
Changing the alignment with realloc is not supported.
  • Loading branch information
SimonSapin committed Apr 12, 2018
1 parent b017742 commit c957e99
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 102 deletions.
22 changes: 9 additions & 13 deletions src/liballoc/alloc.rs
Expand Up @@ -91,21 +91,17 @@ unsafe impl Alloc for Global {
unsafe fn realloc(&mut self,
ptr: *mut u8,
layout: Layout,
new_layout: Layout)
new_size: usize)
-> Result<*mut u8, AllocErr>
{
if layout.align() == new_layout.align() {
#[cfg(not(stage0))]
let ptr = __rust_realloc(ptr, layout.size(), layout.align(), new_layout.size());
#[cfg(stage0)]
let ptr = __rust_realloc(ptr, layout.size(), layout.align(),
new_layout.size(), new_layout.align(), &mut 0);

if !ptr.is_null() {
Ok(ptr)
} else {
Err(AllocErr)
}
#[cfg(not(stage0))]
let ptr = __rust_realloc(ptr, layout.size(), layout.align(), new_size);
#[cfg(stage0)]
let ptr = __rust_realloc(ptr, layout.size(), layout.align(),
new_size, layout.align(), &mut 0);

if !ptr.is_null() {
Ok(ptr)
} else {
Err(AllocErr)
}
Expand Down
8 changes: 4 additions & 4 deletions src/liballoc/heap.rs
Expand Up @@ -64,7 +64,7 @@ unsafe impl<T> Alloc for T where T: CoreAlloc {
ptr: *mut u8,
layout: Layout,
new_layout: Layout) -> Result<*mut u8, AllocErr> {
CoreAlloc::realloc(self, ptr, layout, new_layout)
CoreAlloc::realloc(self, ptr, layout, new_layout.size())
}

unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
Expand All @@ -79,20 +79,20 @@ unsafe impl<T> Alloc for T where T: CoreAlloc {
ptr: *mut u8,
layout: Layout,
new_layout: Layout) -> Result<Excess, AllocErr> {
CoreAlloc::realloc_excess(self, ptr, layout, new_layout)
CoreAlloc::realloc_excess(self, ptr, layout, new_layout.size())
}

unsafe fn grow_in_place(&mut self,
ptr: *mut u8,
layout: Layout,
new_layout: Layout) -> Result<(), CannotReallocInPlace> {
CoreAlloc::grow_in_place(self, ptr, layout, new_layout)
CoreAlloc::grow_in_place(self, ptr, layout, new_layout.size())
}

unsafe fn shrink_in_place(&mut self,
ptr: *mut u8,
layout: Layout,
new_layout: Layout) -> Result<(), CannotReallocInPlace> {
CoreAlloc::shrink_in_place(self, ptr, layout, new_layout)
CoreAlloc::shrink_in_place(self, ptr, layout, new_layout.size())
}
}
17 changes: 8 additions & 9 deletions src/liballoc/raw_vec.rs
Expand Up @@ -309,11 +309,10 @@ impl<T, A: Alloc> RawVec<T, A> {
// `from_size_align_unchecked`.
let new_cap = 2 * self.cap;
let new_size = new_cap * elem_size;
let new_layout = Layout::from_size_align_unchecked(new_size, cur.align());
alloc_guard(new_size).expect("capacity overflow");
let ptr_res = self.a.realloc(self.ptr.as_ptr() as *mut u8,
cur,
new_layout);
new_size);
match ptr_res {
Ok(ptr) => (new_cap, Unique::new_unchecked(ptr as *mut T)),
Err(_) => self.a.oom(),
Expand Down Expand Up @@ -371,8 +370,7 @@ impl<T, A: Alloc> RawVec<T, A> {
let new_size = new_cap * elem_size;
alloc_guard(new_size).expect("capacity overflow");
let ptr = self.ptr() as *mut _;
let new_layout = Layout::from_size_align_unchecked(new_size, old_layout.align());
match self.a.grow_in_place(ptr, old_layout, new_layout) {
match self.a.grow_in_place(ptr, old_layout, new_size) {
Ok(_) => {
// We can't directly divide `size`.
self.cap = new_cap;
Expand Down Expand Up @@ -428,8 +426,9 @@ impl<T, A: Alloc> RawVec<T, A> {

let res = match self.current_layout() {
Some(layout) => {
debug_assert!(new_layout.align() == layout.align());
let old_ptr = self.ptr.as_ptr() as *mut u8;
self.a.realloc(old_ptr, layout, new_layout)
self.a.realloc(old_ptr, layout, new_layout.size())
}
None => self.a.alloc(new_layout),
};
Expand Down Expand Up @@ -537,8 +536,9 @@ impl<T, A: Alloc> RawVec<T, A> {

let res = match self.current_layout() {
Some(layout) => {
debug_assert!(new_layout.align() == layout.align());
let old_ptr = self.ptr.as_ptr() as *mut u8;
self.a.realloc(old_ptr, layout, new_layout)
self.a.realloc(old_ptr, layout, new_layout.size())
}
None => self.a.alloc(new_layout),
};
Expand Down Expand Up @@ -604,7 +604,7 @@ impl<T, A: Alloc> RawVec<T, A> {
let new_layout = Layout::new::<T>().repeat(new_cap).unwrap().0;
// FIXME: may crash and burn on over-reserve
alloc_guard(new_layout.size()).expect("capacity overflow");
match self.a.grow_in_place(ptr, old_layout, new_layout) {
match self.a.grow_in_place(ptr, old_layout, new_layout.size()) {
Ok(_) => {
self.cap = new_cap;
true
Expand Down Expand Up @@ -664,10 +664,9 @@ impl<T, A: Alloc> RawVec<T, A> {
let new_size = elem_size * amount;
let align = mem::align_of::<T>();
let old_layout = Layout::from_size_align_unchecked(old_size, align);
let new_layout = Layout::from_size_align_unchecked(new_size, align);
match self.a.realloc(self.ptr.as_ptr() as *mut u8,
old_layout,
new_layout) {
new_size) {
Ok(p) => self.ptr = Unique::new_unchecked(p as *mut T),
Err(_) => self.a.oom(),
}
Expand Down
42 changes: 17 additions & 25 deletions src/liballoc_system/lib.rs
Expand Up @@ -69,8 +69,8 @@ unsafe impl Alloc for System {
unsafe fn realloc(&mut self,
ptr: *mut u8,
old_layout: Layout,
new_layout: Layout) -> Result<*mut u8, AllocErr> {
Alloc::realloc(&mut &*self, ptr, old_layout, new_layout)
new_size: usize) -> Result<*mut u8, AllocErr> {
Alloc::realloc(&mut &*self, ptr, old_layout, new_size)
}

fn oom(&mut self) -> ! {
Expand All @@ -91,24 +91,24 @@ unsafe impl Alloc for System {
unsafe fn realloc_excess(&mut self,
ptr: *mut u8,
layout: Layout,
new_layout: Layout) -> Result<Excess, AllocErr> {
Alloc::realloc_excess(&mut &*self, ptr, layout, new_layout)
new_size: usize) -> Result<Excess, AllocErr> {
Alloc::realloc_excess(&mut &*self, ptr, layout, new_size)
}

#[inline]
unsafe fn grow_in_place(&mut self,
ptr: *mut u8,
layout: Layout,
new_layout: Layout) -> Result<(), CannotReallocInPlace> {
Alloc::grow_in_place(&mut &*self, ptr, layout, new_layout)
new_size: usize) -> Result<(), CannotReallocInPlace> {
Alloc::grow_in_place(&mut &*self, ptr, layout, new_size)
}

#[inline]
unsafe fn shrink_in_place(&mut self,
ptr: *mut u8,
layout: Layout,
new_layout: Layout) -> Result<(), CannotReallocInPlace> {
Alloc::shrink_in_place(&mut &*self, ptr, layout, new_layout)
new_size: usize) -> Result<(), CannotReallocInPlace> {
Alloc::shrink_in_place(&mut &*self, ptr, layout, new_size)
}
}

Expand Down Expand Up @@ -166,12 +166,8 @@ macro_rules! alloc_methods_based_on_global_alloc {
unsafe fn realloc(&mut self,
ptr: *mut u8,
old_layout: Layout,
new_layout: Layout) -> Result<*mut u8, AllocErr> {
if old_layout.align() != new_layout.align() {
return Err(AllocErr)
}

let ptr = GlobalAlloc::realloc(*self, ptr as *mut Void, old_layout, new_layout.size());
new_size: usize) -> Result<*mut u8, AllocErr> {
let ptr = GlobalAlloc::realloc(*self, ptr as *mut Void, old_layout, new_size);
if !ptr.is_null() {
Ok(ptr as *mut u8)
} else {
Expand Down Expand Up @@ -428,30 +424,26 @@ mod platform {
unsafe fn grow_in_place(&mut self,
ptr: *mut u8,
layout: Layout,
new_layout: Layout) -> Result<(), CannotReallocInPlace> {
self.shrink_in_place(ptr, layout, new_layout)
new_size: usize) -> Result<(), CannotReallocInPlace> {
self.shrink_in_place(ptr, layout, new_size)
}

#[inline]
unsafe fn shrink_in_place(&mut self,
ptr: *mut u8,
old_layout: Layout,
new_layout: Layout) -> Result<(), CannotReallocInPlace> {
if old_layout.align() != new_layout.align() {
return Err(CannotReallocInPlace)
}

let new = if new_layout.align() <= MIN_ALIGN {
layout: Layout,
new_size: usize) -> Result<(), CannotReallocInPlace> {
let new = if layout.align() <= MIN_ALIGN {
HeapReAlloc(GetProcessHeap(),
HEAP_REALLOC_IN_PLACE_ONLY,
ptr as LPVOID,
new_layout.size())
new_size)
} else {
let header = get_header(ptr);
HeapReAlloc(GetProcessHeap(),
HEAP_REALLOC_IN_PLACE_ONLY,
header.0 as LPVOID,
new_layout.size() + new_layout.align())
new_size + layout.align())
};
if new.is_null() {
Err(CannotReallocInPlace)
Expand Down

0 comments on commit c957e99

Please sign in to comment.