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 {...@@ -139,11 +139,7 @@ pub const DirectAllocator = struct {
139 return shrink(allocator, old_mem, old_align, new_size, new_align);139 return shrink(allocator, old_mem, old_align, new_size, new_align);
140 }140 }
141 const result = try alloc(allocator, new_size, new_align);141 const result = try alloc(allocator, new_size, new_align);
142 if (result.len >= old_mem.len) {142 @memcpy(result.ptr, old_mem.ptr, std.math.min(old_mem.len, result.len));
143 mem.copy(u8, result, old_mem);
144 } else {
145 @memcpy(result.ptr, old_mem.ptr, new_size);
146 }
147 _ = os.posix.munmap(@ptrToInt(old_mem.ptr), old_mem.len);143 _ = os.posix.munmap(@ptrToInt(old_mem.ptr), old_mem.len);
148 return result;144 return result;
149 },145 },
...@@ -170,16 +166,20 @@ pub const DirectAllocator = struct {...@@ -170,16 +166,20 @@ pub const DirectAllocator = struct {
170 ) orelse return error.OutOfMemory;166 ) orelse return error.OutOfMemory;
171 const offset = old_adjusted_addr - root_addr;167 const offset = old_adjusted_addr - root_addr;
172 const new_root_addr = @ptrToInt(new_ptr);168 const new_root_addr = @ptrToInt(new_ptr);
173 const adjusted_addr = new_root_addr + offset;169 var new_adjusted_addr = new_root_addr + offset;
174 const new_adjusted_addr = mem.alignForward(new_root_addr, new_align);170 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 alignment171 const offset_is_aligned = new_adjusted_addr % new_align == 0;
176 // then we need to copy it172 if (!offset_is_valid or !offset_is_aligned) {
177 if (new_adjusted_addr != adjusted_addr) {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);
178 @memcpy(177 @memcpy(
178 @intToPtr([*]u8, new_aligned_addr),
179 @intToPtr([*]u8, new_adjusted_addr),179 @intToPtr([*]u8, new_adjusted_addr),
180 @intToPtr([*]u8, adjusted_addr),
181 std.math.min(old_mem.len, new_size),180 std.math.min(old_mem.len, new_size),
182 );181 );
182 new_adjusted_addr = new_aligned_addr;
183 }183 }
184 const new_record_addr = new_adjusted_addr + new_size;184 const new_record_addr = new_adjusted_addr + new_size;
185 @intToPtr(*align(1) usize, new_record_addr).* = new_root_addr;185 @intToPtr(*align(1) usize, new_record_addr).* = new_root_addr;
...@@ -270,11 +270,7 @@ pub const ArenaAllocator = struct {...@@ -270,11 +270,7 @@ pub const ArenaAllocator = struct {
270 return error.OutOfMemory;270 return error.OutOfMemory;
271 } else {271 } else {
272 const result = try alloc(allocator, new_size, new_align);272 const result = try alloc(allocator, new_size, new_align);
273 if (result.len >= old_mem.len) {273 @memcpy(result.ptr, old_mem.ptr, std.math.min(old_mem.len, result.len));
274 mem.copy(u8, result, old_mem);
275 } else {
276 @memcpy(result.ptr, old_mem.ptr, new_size);
277 }
278 return result;274 return result;
279 }275 }
280 }276 }
...@@ -332,11 +328,7 @@ pub const FixedBufferAllocator = struct {...@@ -332,11 +328,7 @@ pub const FixedBufferAllocator = struct {
332 return error.OutOfMemory;328 return error.OutOfMemory;
333 } else {329 } else {
334 const result = try alloc(allocator, new_size, new_align);330 const result = try alloc(allocator, new_size, new_align);
335 if (result.len >= old_mem.len) {331 @memcpy(result.ptr, old_mem.ptr, std.math.min(old_mem.len, result.len));
336 mem.copy(u8, result, old_mem);
337 } else {
338 @memcpy(result.ptr, old_mem.ptr, new_size);
339 }
340 return result;332 return result;
341 }333 }
342 }334 }
...@@ -479,11 +471,7 @@ pub const ThreadSafeFixedBufferAllocator = blk: {...@@ -479,11 +471,7 @@ pub const ThreadSafeFixedBufferAllocator = blk: {
479 return error.OutOfMemory;471 return error.OutOfMemory;
480 } else {472 } else {
481 const result = try alloc(allocator, new_size, new_align);473 const result = try alloc(allocator, new_size, new_align);
482 if (result.len >= old_mem.len) {474 @memcpy(result.ptr, old_mem.ptr, std.math.min(old_mem.len, result.len));
483 mem.copy(u8, result, old_mem);
484 } else {
485 @memcpy(result.ptr, old_mem.ptr, new_size);
486 }
487 return result;475 return result;
488 }476 }
489 }477 }