authorgravatar for alichraghi@proton.meAli Chraghi <alichraghi@proton.me> 2022-07-13 17:30:51+04:30
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-09-14 20:05:15-04:00
log8c9f468fddbba41e49c932e015d49725ca62338e
treed35a1b9a53e3818d478e406713a449b01f42e93c
parent78cd7b57ef7a3c8c645aab5c30b3fbf3834e6970

std.ArrayList.ensureTotalCapacity: optimize and fix integer overflow

Fixes #12099

1 files changed, 9 insertions(+), 8 deletions(-)

lib/std/array_list.zig+9-8
...@@ -3,6 +3,7 @@ const debug = std.debug;...@@ -3,6 +3,7 @@ const debug = std.debug;
3const assert = debug.assert;3const assert = debug.assert;
4const testing = std.testing;4const testing = std.testing;
5const mem = std.mem;5const mem = std.mem;
6const math = std.math;
6const Allocator = mem.Allocator;7const Allocator = mem.Allocator;
78
8/// A contiguous, growable list of items in memory.9/// A contiguous, growable list of items in memory.
...@@ -330,17 +331,17 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {...@@ -330,17 +331,17 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
330 /// Invalidates pointers if additional memory is needed.331 /// Invalidates pointers if additional memory is needed.
331 pub fn ensureTotalCapacity(self: *Self, new_capacity: usize) Allocator.Error!void {332 pub fn ensureTotalCapacity(self: *Self, new_capacity: usize) Allocator.Error!void {
332 if (@sizeOf(T) > 0) {333 if (@sizeOf(T) > 0) {
333 var better_capacity = self.capacity;334 if (self.capacity >= new_capacity) return;
334 if (better_capacity >= new_capacity) return;
335335
336 var better_capacity = self.capacity;
336 while (true) {337 while (true) {
337 better_capacity += better_capacity / 2 + 8;338 better_capacity +|= better_capacity / 2 + 8;
338 if (better_capacity >= new_capacity) break;339 if (better_capacity >= new_capacity) break;
339 }340 }
340341
341 return self.ensureTotalCapacityPrecise(better_capacity);342 return self.ensureTotalCapacityPrecise(better_capacity);
342 } else {343 } else {
343 self.capacity = std.math.maxInt(usize);344 self.capacity = math.maxInt(usize);
344 }345 }
345 }346 }
346347
...@@ -357,7 +358,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {...@@ -357,7 +358,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
357 self.items.ptr = new_memory.ptr;358 self.items.ptr = new_memory.ptr;
358 self.capacity = new_memory.len;359 self.capacity = new_memory.len;
359 } else {360 } else {
360 self.capacity = std.math.maxInt(usize);361 self.capacity = math.maxInt(usize);
361 }362 }
362 }363 }
363364
...@@ -725,11 +726,11 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ...@@ -725,11 +726,11 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
725 /// Modify the array so that it can hold at least `new_capacity` items.726 /// Modify the array so that it can hold at least `new_capacity` items.
726 /// Invalidates pointers if additional memory is needed.727 /// Invalidates pointers if additional memory is needed.
727 pub fn ensureTotalCapacity(self: *Self, allocator: Allocator, new_capacity: usize) Allocator.Error!void {728 pub fn ensureTotalCapacity(self: *Self, allocator: Allocator, new_capacity: usize) Allocator.Error!void {
728 var better_capacity = self.capacity;729 if (self.capacity >= new_capacity) return;
729 if (better_capacity >= new_capacity) return;
730730
731 var better_capacity = self.capacity;
731 while (true) {732 while (true) {
732 better_capacity += better_capacity / 2 + 8;733 better_capacity +|= better_capacity / 2 + 8;
733 if (better_capacity >= new_capacity) break;734 if (better_capacity >= new_capacity) break;
734 }735 }
735736