Auto merge of #42331 - retep998:standard-relocation-coupon, r=alexcrichton

Improve reallocation in alloc_system on Windows

Fixes https://github.com/rust-lang/rust/issues/42025
This commit is contained in:
bors 2017-06-03 08:32:58 +00:00
commit fbb9276780
3 changed files with 37 additions and 17 deletions

View File

@ -171,6 +171,8 @@ mod imp {
#[cfg(windows)] #[cfg(windows)]
#[allow(bad_style)] #[allow(bad_style)]
mod imp { mod imp {
use core::cmp::min;
use core::ptr::copy_nonoverlapping;
use MIN_ALIGN; use MIN_ALIGN;
type LPVOID = *mut u8; type LPVOID = *mut u8;
@ -225,19 +227,16 @@ mod imp {
allocate_with_flags(size, align, HEAP_ZERO_MEMORY) allocate_with_flags(size, align, HEAP_ZERO_MEMORY)
} }
pub unsafe fn reallocate(ptr: *mut u8, _old_size: usize, size: usize, align: usize) -> *mut u8 { pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8 {
if align <= MIN_ALIGN { if align <= MIN_ALIGN {
HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, size as SIZE_T) as *mut u8 HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, size as SIZE_T) as *mut u8
} else { } else {
let header = get_header(ptr); let new = allocate(size, align);
let new = HeapReAlloc(GetProcessHeap(), if !new.is_null() {
0, copy_nonoverlapping(ptr, new, min(size, old_size));
header.0 as LPVOID, deallocate(ptr, old_size, align);
(size + align) as SIZE_T) as *mut u8;
if new.is_null() {
return new;
} }
align_ptr(new, align) new
} }
} }
@ -246,15 +245,19 @@ mod imp {
size: usize, size: usize,
align: usize) align: usize)
-> usize { -> usize {
if align <= MIN_ALIGN { let new = if align <= MIN_ALIGN {
let new = HeapReAlloc(GetProcessHeap(), HeapReAlloc(GetProcessHeap(),
HEAP_REALLOC_IN_PLACE_ONLY, HEAP_REALLOC_IN_PLACE_ONLY,
ptr as LPVOID, ptr as LPVOID,
size as SIZE_T) as *mut u8; size as SIZE_T) as *mut u8
if new.is_null() { old_size } else { size }
} else { } else {
old_size let header = get_header(ptr);
} HeapReAlloc(GetProcessHeap(),
HEAP_REALLOC_IN_PLACE_ONLY,
header.0 as LPVOID,
size + align as SIZE_T) as *mut u8
};
if new.is_null() { old_size } else { size }
} }
pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, align: usize) { pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, align: usize) {

View File

@ -10,6 +10,7 @@
#![deny(warnings)] #![deny(warnings)]
#![feature(attr_literals)]
#![feature(box_syntax)] #![feature(box_syntax)]
#![feature(inclusive_range_syntax)] #![feature(inclusive_range_syntax)]
#![feature(collection_placement)] #![feature(collection_placement)]
@ -20,6 +21,7 @@
#![feature(pattern)] #![feature(pattern)]
#![feature(placement_in_syntax)] #![feature(placement_in_syntax)]
#![feature(rand)] #![feature(rand)]
#![feature(repr_align)]
#![feature(slice_rotate)] #![feature(slice_rotate)]
#![feature(splice)] #![feature(splice)]
#![feature(str_escape)] #![feature(str_escape)]

View File

@ -781,3 +781,18 @@ fn from_into_inner() {
assert_eq!(vec, [2, 3]); assert_eq!(vec, [2, 3]);
assert!(ptr != vec.as_ptr()); assert!(ptr != vec.as_ptr());
} }
#[test]
fn overaligned_allocations() {
#[repr(align(256))]
struct Foo(usize);
let mut v = vec![Foo(273)];
for i in 0..0x1000 {
v.reserve_exact(i);
assert!(v[0].0 == 273);
assert!(v.as_ptr() as usize & 0xff == 0);
v.shrink_to_fit();
assert!(v[0].0 == 273);
assert!(v.as_ptr() as usize & 0xff == 0);
}
}