authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-04-26 19:34:24-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2019-04-26 19:34:24-04:00
logac3946620cebfc706255a86103a14c6cb08cff97
tree0a8078aec02f537da9c6d657b99023ae39aadcdc
parentefc5122fb61aab0d6f2c2700b5dcee1b5fc5d2d2
parentafc33f00ee65bfefa173200e4ec8c0f329172d3f
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #2357 from squeek502/heap-shrink-large-align

DirectAllocator: reduce the amount of redundant memcpy calls on Windows

1 files changed, 14 insertions(+), 26 deletions(-)

std/heap.zig+14-26
......@@ -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 }