authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2019-04-25 13:35:45-07:00
committergravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2019-04-25 13:35:45-07:00
log57f545eed8e940520855c127245414db9ea29310
tree6249362202402aad3ad4707fc7d237cbbd27f090
parent8ce130de3cf38e09cfbcbd1b22da34ae5b27a040

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 files changed, 10 insertions(+), 6 deletions(-)

std/heap.zig+10-6
...@@ -170,16 +170,20 @@ pub const DirectAllocator = struct {...@@ -170,16 +170,20 @@ pub const DirectAllocator = struct {
170 ) orelse return error.OutOfMemory;170 ) orelse return error.OutOfMemory;
171 const offset = old_adjusted_addr - root_addr;171 const offset = old_adjusted_addr - root_addr;
172 const new_root_addr = @ptrToInt(new_ptr);172 const new_root_addr = @ptrToInt(new_ptr);
173 const adjusted_addr = new_root_addr + offset;173 var new_adjusted_addr = new_root_addr + offset;
174 const new_adjusted_addr = mem.alignForward(new_root_addr, new_align);174 const offset_is_valid = new_adjusted_addr + new_size + @sizeOf(usize) <= new_root_addr + amt;
175 // If HeapReAlloc didn't happen to move the memory to the new alignment175 const offset_is_aligned = new_adjusted_addr % new_align == 0;
176 // then we need to copy it176 if (!offset_is_valid or !offset_is_aligned) {
177 if (new_adjusted_addr != adjusted_addr) {177 // If HeapReAlloc didn't happen to move the memory to the new alignment,
178 // or the memory starting at the old offset would be outside of the new allocation,
179 // then we need to copy the memory to a valid aligned address and use that
180 const new_aligned_addr = mem.alignForward(new_root_addr, new_align);
178 @memcpy(181 @memcpy(
182 @intToPtr([*]u8, new_aligned_addr),
179 @intToPtr([*]u8, new_adjusted_addr),183 @intToPtr([*]u8, new_adjusted_addr),
180 @intToPtr([*]u8, adjusted_addr),
181 std.math.min(old_mem.len, new_size),184 std.math.min(old_mem.len, new_size),
182 );185 );
186 new_adjusted_addr = new_aligned_addr;
183 }187 }
184 const new_record_addr = new_adjusted_addr + new_size;188 const new_record_addr = new_adjusted_addr + new_size;
185 @intToPtr(*align(1) usize, new_record_addr).* = new_root_addr;189 @intToPtr(*align(1) usize, new_record_addr).* = new_root_addr;