about summary refs log tree commit diff
path: root/src/liballoc_system
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-06-03 08:32:58 +0000
committerbors <bors@rust-lang.org>2017-06-03 08:32:58 +0000
commitfbb92767801cd289ab0c62c81db172ce104b023e (patch)
treee7a02b6b23307253d91a75166421991494ddd6db /src/liballoc_system
parent6165203c48420c6f77ea22113eb4ff66931410c3 (diff)
parent42ac31182bab6735cfe9ad77d8f4292fad51bfa8 (diff)
downloadrust-fbb92767801cd289ab0c62c81db172ce104b023e.tar.gz
rust-fbb92767801cd289ab0c62c81db172ce104b023e.zip
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
Diffstat (limited to 'src/liballoc_system')
-rw-r--r--src/liballoc_system/lib.rs37
1 files changed, 20 insertions, 17 deletions
diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs
index 6d47c2ff28f..1f36bc4fbce 100644
--- a/src/liballoc_system/lib.rs
+++ b/src/liballoc_system/lib.rs
@@ -171,6 +171,8 @@ mod imp {
 #[cfg(windows)]
 #[allow(bad_style)]
 mod imp {
+    use core::cmp::min;
+    use core::ptr::copy_nonoverlapping;
     use MIN_ALIGN;
 
     type LPVOID = *mut u8;
@@ -225,19 +227,16 @@ mod imp {
         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 {
             HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, size as SIZE_T) as *mut u8
         } else {
-            let header = get_header(ptr);
-            let new = HeapReAlloc(GetProcessHeap(),
-                                  0,
-                                  header.0 as LPVOID,
-                                  (size + align) as SIZE_T) as *mut u8;
-            if new.is_null() {
-                return new;
+            let new = allocate(size, align);
+            if !new.is_null() {
+                copy_nonoverlapping(ptr, new, min(size, old_size));
+                deallocate(ptr, old_size, align);
             }
-            align_ptr(new, align)
+            new
         }
     }
 
@@ -246,15 +245,19 @@ mod imp {
                                      size: usize,
                                      align: usize)
                                      -> usize {
-        if align <= MIN_ALIGN {
-            let new = HeapReAlloc(GetProcessHeap(),
-                                  HEAP_REALLOC_IN_PLACE_ONLY,
-                                  ptr as LPVOID,
-                                  size as SIZE_T) as *mut u8;
-            if new.is_null() { old_size } else { size }
+        let new = if align <= MIN_ALIGN {
+            HeapReAlloc(GetProcessHeap(),
+                        HEAP_REALLOC_IN_PLACE_ONLY,
+                        ptr as LPVOID,
+                        size as SIZE_T) as *mut u8
         } 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) {