Skip to content

Commit fbb9276

Browse files
committed
Auto merge of #42331 - retep998:standard-relocation-coupon, r=alexcrichton
Improve reallocation in alloc_system on Windows Fixes #42025
2 parents 6165203 + 42ac311 commit fbb9276

File tree

3 files changed

+37
-17
lines changed

3 files changed

+37
-17
lines changed

src/liballoc_system/lib.rs

+20-17
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ mod imp {
171171
#[cfg(windows)]
172172
#[allow(bad_style)]
173173
mod imp {
174+
use core::cmp::min;
175+
use core::ptr::copy_nonoverlapping;
174176
use MIN_ALIGN;
175177

176178
type LPVOID = *mut u8;
@@ -225,19 +227,16 @@ mod imp {
225227
allocate_with_flags(size, align, HEAP_ZERO_MEMORY)
226228
}
227229

228-
pub unsafe fn reallocate(ptr: *mut u8, _old_size: usize, size: usize, align: usize) -> *mut u8 {
230+
pub unsafe fn reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8 {
229231
if align <= MIN_ALIGN {
230232
HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, size as SIZE_T) as *mut u8
231233
} else {
232-
let header = get_header(ptr);
233-
let new = HeapReAlloc(GetProcessHeap(),
234-
0,
235-
header.0 as LPVOID,
236-
(size + align) as SIZE_T) as *mut u8;
237-
if new.is_null() {
238-
return new;
234+
let new = allocate(size, align);
235+
if !new.is_null() {
236+
copy_nonoverlapping(ptr, new, min(size, old_size));
237+
deallocate(ptr, old_size, align);
239238
}
240-
align_ptr(new, align)
239+
new
241240
}
242241
}
243242

@@ -246,15 +245,19 @@ mod imp {
246245
size: usize,
247246
align: usize)
248247
-> usize {
249-
if align <= MIN_ALIGN {
250-
let new = HeapReAlloc(GetProcessHeap(),
251-
HEAP_REALLOC_IN_PLACE_ONLY,
252-
ptr as LPVOID,
253-
size as SIZE_T) as *mut u8;
254-
if new.is_null() { old_size } else { size }
248+
let new = if align <= MIN_ALIGN {
249+
HeapReAlloc(GetProcessHeap(),
250+
HEAP_REALLOC_IN_PLACE_ONLY,
251+
ptr as LPVOID,
252+
size as SIZE_T) as *mut u8
255253
} else {
256-
old_size
257-
}
254+
let header = get_header(ptr);
255+
HeapReAlloc(GetProcessHeap(),
256+
HEAP_REALLOC_IN_PLACE_ONLY,
257+
header.0 as LPVOID,
258+
size + align as SIZE_T) as *mut u8
259+
};
260+
if new.is_null() { old_size } else { size }
258261
}
259262

260263
pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, align: usize) {

src/libcollections/tests/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#![deny(warnings)]
1212

13+
#![feature(attr_literals)]
1314
#![feature(box_syntax)]
1415
#![feature(inclusive_range_syntax)]
1516
#![feature(collection_placement)]
@@ -20,6 +21,7 @@
2021
#![feature(pattern)]
2122
#![feature(placement_in_syntax)]
2223
#![feature(rand)]
24+
#![feature(repr_align)]
2325
#![feature(slice_rotate)]
2426
#![feature(splice)]
2527
#![feature(str_escape)]

src/libcollections/tests/vec.rs

+15
Original file line numberDiff line numberDiff line change
@@ -781,3 +781,18 @@ fn from_into_inner() {
781781
assert_eq!(vec, [2, 3]);
782782
assert!(ptr != vec.as_ptr());
783783
}
784+
785+
#[test]
786+
fn overaligned_allocations() {
787+
#[repr(align(256))]
788+
struct Foo(usize);
789+
let mut v = vec![Foo(273)];
790+
for i in 0..0x1000 {
791+
v.reserve_exact(i);
792+
assert!(v[0].0 == 273);
793+
assert!(v.as_ptr() as usize & 0xff == 0);
794+
v.shrink_to_fit();
795+
assert!(v[0].0 == 273);
796+
assert!(v.as_ptr() as usize & 0xff == 0);
797+
}
798+
}

0 commit comments

Comments
 (0)