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;
33const assert = debug.assert;
44const testing = std.testing;
55const mem = std.mem;
6const math = std.math;
67const Allocator = mem.Allocator;
78
89/// A contiguous, growable list of items in memory.
......@@ -330,17 +331,17 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
330331 /// Invalidates pointers if additional memory is needed.
331332 pub fn ensureTotalCapacity(self: *Self, new_capacity: usize) Allocator.Error!void {
332333 if (@sizeOf(T) > 0) {
333 var better_capacity = self.capacity;
334 if (better_capacity >= new_capacity) return;
334 if (self.capacity >= new_capacity) return;
335335
336 var better_capacity = self.capacity;
336337 while (true) {
337 better_capacity += better_capacity / 2 + 8;
338 better_capacity +|= better_capacity / 2 + 8;
338339 if (better_capacity >= new_capacity) break;
339340 }
340341
341342 return self.ensureTotalCapacityPrecise(better_capacity);
342343 } else {
343 self.capacity = std.math.maxInt(usize);
344 self.capacity = math.maxInt(usize);
344345 }
345346 }
346347
......@@ -357,7 +358,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
357358 self.items.ptr = new_memory.ptr;
358359 self.capacity = new_memory.len;
359360 } else {
360 self.capacity = std.math.maxInt(usize);
361 self.capacity = math.maxInt(usize);
361362 }
362363 }
363364
......@@ -725,11 +726,11 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
725726 /// Modify the array so that it can hold at least `new_capacity` items.
726727 /// Invalidates pointers if additional memory is needed.
727728 pub fn ensureTotalCapacity(self: *Self, allocator: Allocator, new_capacity: usize) Allocator.Error!void {
728 var better_capacity = self.capacity;
729 if (better_capacity >= new_capacity) return;
729 if (self.capacity >= new_capacity) return;
730730
731 var better_capacity = self.capacity;
731732 while (true) {
732 better_capacity += better_capacity / 2 + 8;
733 better_capacity +|= better_capacity / 2 + 8;
733734 if (better_capacity >= new_capacity) break;
734735 }
735736