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).
This commit is contained in:
Ryan Liptak 2019-04-25 13:35:45 -07:00
parent 8ce130de3c
commit 57f545eed8

View File

@ -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;