Commit 57f545eed8

Ryan Liptak <squeek502@hotmail.com>
2019-04-25 22:35:45
std.heap.DirectAllocator: reduce the amount of redundant memcpy calls on Windows
Previously the memory would be copied to a different aligned address in some cases where the old offset could have been used. This fixes it so that it will always try to use the old offset when possible, and only uses a different offset if the old one is truly invalid (not aligned or not enough space to store the alloc at the old offset).
1 parent 8ce130d
Changed files (1)
std/heap.zig
@@ -170,16 +170,20 @@ pub const DirectAllocator = struct {
                 ) orelse return error.OutOfMemory;
                 const offset = old_adjusted_addr - root_addr;
                 const new_root_addr = @ptrToInt(new_ptr);
-                const adjusted_addr = new_root_addr + offset;
-                const new_adjusted_addr = mem.alignForward(new_root_addr, new_align);
-                // If HeapReAlloc didn't happen to move the memory to the new alignment
-                // then we need to copy it
-                if (new_adjusted_addr != adjusted_addr) {
+                var new_adjusted_addr = new_root_addr + offset;
+                const offset_is_valid = new_adjusted_addr + new_size + @sizeOf(usize) <= new_root_addr + amt;
+                const offset_is_aligned = new_adjusted_addr % new_align == 0;
+                if (!offset_is_valid or !offset_is_aligned) {
+                    // If HeapReAlloc didn't happen to move the memory to the new alignment,
+                    // or the memory starting at the old offset would be outside of the new allocation,
+                    // then we need to copy the memory to a valid aligned address and use that
+                    const new_aligned_addr = mem.alignForward(new_root_addr, new_align);
                     @memcpy(
+                        @intToPtr([*]u8, new_aligned_addr),
                         @intToPtr([*]u8, new_adjusted_addr),
-                        @intToPtr([*]u8, adjusted_addr),
                         std.math.min(old_mem.len, new_size),
                     );
+                    new_adjusted_addr = new_aligned_addr;
                 }
                 const new_record_addr = new_adjusted_addr + new_size;
                 @intToPtr(*align(1) usize, new_record_addr).* = new_root_addr;