Skip to content

Commit ac39466

Browse files
authored
Merge pull request #2357 from squeek502/heap-shrink-large-align
DirectAllocator: reduce the amount of redundant memcpy calls on Windows
2 parents efc5122 + afc33f0 commit ac39466

File tree

1 file changed

+14
-26
lines changed

1 file changed

+14
-26
lines changed

std/heap.zig

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,7 @@ pub const DirectAllocator = struct {
139139
return shrink(allocator, old_mem, old_align, new_size, new_align);
140140
}
141141
const result = try alloc(allocator, new_size, new_align);
142-
if (result.len >= old_mem.len) {
143-
mem.copy(u8, result, old_mem);
144-
} else {
145-
@memcpy(result.ptr, old_mem.ptr, new_size);
146-
}
142+
@memcpy(result.ptr, old_mem.ptr, std.math.min(old_mem.len, result.len));
147143
_ = os.posix.munmap(@ptrToInt(old_mem.ptr), old_mem.len);
148144
return result;
149145
},
@@ -170,16 +166,20 @@ pub const DirectAllocator = struct {
170166
) orelse return error.OutOfMemory;
171167
const offset = old_adjusted_addr - root_addr;
172168
const new_root_addr = @ptrToInt(new_ptr);
173-
const adjusted_addr = new_root_addr + offset;
174-
const new_adjusted_addr = mem.alignForward(new_root_addr, new_align);
175-
// If HeapReAlloc didn't happen to move the memory to the new alignment
176-
// then we need to copy it
177-
if (new_adjusted_addr != adjusted_addr) {
169+
var new_adjusted_addr = new_root_addr + offset;
170+
const offset_is_valid = new_adjusted_addr + new_size + @sizeOf(usize) <= new_root_addr + amt;
171+
const offset_is_aligned = new_adjusted_addr % new_align == 0;
172+
if (!offset_is_valid or !offset_is_aligned) {
173+
// If HeapReAlloc didn't happen to move the memory to the new alignment,
174+
// or the memory starting at the old offset would be outside of the new allocation,
175+
// then we need to copy the memory to a valid aligned address and use that
176+
const new_aligned_addr = mem.alignForward(new_root_addr, new_align);
178177
@memcpy(
178+
@intToPtr([*]u8, new_aligned_addr),
179179
@intToPtr([*]u8, new_adjusted_addr),
180-
@intToPtr([*]u8, adjusted_addr),
181180
std.math.min(old_mem.len, new_size),
182181
);
182+
new_adjusted_addr = new_aligned_addr;
183183
}
184184
const new_record_addr = new_adjusted_addr + new_size;
185185
@intToPtr(*align(1) usize, new_record_addr).* = new_root_addr;
@@ -270,11 +270,7 @@ pub const ArenaAllocator = struct {
270270
return error.OutOfMemory;
271271
} else {
272272
const result = try alloc(allocator, new_size, new_align);
273-
if (result.len >= old_mem.len) {
274-
mem.copy(u8, result, old_mem);
275-
} else {
276-
@memcpy(result.ptr, old_mem.ptr, new_size);
277-
}
273+
@memcpy(result.ptr, old_mem.ptr, std.math.min(old_mem.len, result.len));
278274
return result;
279275
}
280276
}
@@ -332,11 +328,7 @@ pub const FixedBufferAllocator = struct {
332328
return error.OutOfMemory;
333329
} else {
334330
const result = try alloc(allocator, new_size, new_align);
335-
if (result.len >= old_mem.len) {
336-
mem.copy(u8, result, old_mem);
337-
} else {
338-
@memcpy(result.ptr, old_mem.ptr, new_size);
339-
}
331+
@memcpy(result.ptr, old_mem.ptr, std.math.min(old_mem.len, result.len));
340332
return result;
341333
}
342334
}
@@ -479,11 +471,7 @@ pub const ThreadSafeFixedBufferAllocator = blk: {
479471
return error.OutOfMemory;
480472
} else {
481473
const result = try alloc(allocator, new_size, new_align);
482-
if (result.len >= old_mem.len) {
483-
mem.copy(u8, result, old_mem);
484-
} else {
485-
@memcpy(result.ptr, old_mem.ptr, new_size);
486-
}
474+
@memcpy(result.ptr, old_mem.ptr, std.math.min(old_mem.len, result.len));
487475
return result;
488476
}
489477
}

0 commit comments

Comments
 (0)