authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-08-05 15:11:22-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-08-05 15:11:22-07:00
log009604d690aeaac6957d4646a815bc8762e84757
tree5ad64b2ed3195eb57244618744844ee7738c5ef1
parent1e5d24a009ffef49f0888b3d6ea46aec8a82d40b

Allocator: simplify; avoid unnecessary recursion


1 files changed, 19 insertions(+), 27 deletions(-)

lib/std/mem/Allocator.zig+19-27
......@@ -316,18 +316,15 @@ pub fn allocBytesAligned(
316316///
317317/// `new_len` may be zero, in which case the allocation is freed.
318318pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool {
319 const slice_info = @typeInfo(@TypeOf(allocation)).pointer;
320 if (slice_info.size != .slice) {
321 const slice: Slice(@TypeOf(allocation)) = allocation; // coerce *[len]T to []T
322 return resize(self, slice, new_len);
323 }
324 comptime assert(slice_info.size == .slice);
319 const SliceType = Slice(@TypeOf(allocation));
320 const slice: SliceType = allocation; // coerce *[len]T to []T
321 const slice_info = @typeInfo(SliceType).pointer;
325322 const T = slice_info.child;
326323 if (new_len == 0) {
327 self.free(allocation);
324 self.free(slice);
328325 return true;
329326 }
330 if (allocation.len == 0) {
327 if (slice.len == 0) {
331328 return false;
332329 }
333330 const old_memory: []u8 = @ptrCast(@constCast(mem.absorbSentinel(allocation)));
......@@ -360,27 +357,24 @@ pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool {
360357///
361358/// If the allocation's elements' type is zero bytes sized, `allocation.len` is set to `new_len`.
362359pub fn remap(self: Allocator, allocation: anytype, new_len: usize) ?Slice(@TypeOf(allocation)) {
363 const slice_info = @typeInfo(@TypeOf(allocation)).pointer;
364 if (slice_info.size != .slice) {
365 const slice: Slice(@TypeOf(allocation)) = allocation; // coerce *[len]T to []T
366 return remap(self, slice, new_len);
367 }
368 comptime assert(slice_info.size == .slice);
360 const SliceType = Slice(@TypeOf(allocation));
361 const slice: SliceType = allocation; // coerce *[len]T to []T
362 const slice_info = @typeInfo(SliceType).pointer;
369363 const T = slice_info.child;
370364
371365 if (new_len == 0) {
372 self.free(allocation);
373 return allocation[0..0];
366 self.free(slice);
367 return slice[0..0];
374368 }
375 if (allocation.len == 0) {
369 if (slice.len == 0) {
376370 return null;
377371 }
378372 if (@sizeOf(T) == 0) {
379 var new_memory = allocation;
373 var new_memory = slice;
380374 new_memory.len = new_len;
381375 return new_memory;
382376 }
383 const old_memory: []u8 = @ptrCast(@constCast(mem.absorbSentinel(allocation)));
377 const old_memory: []u8 = @ptrCast(@constCast(mem.absorbSentinel(slice)));
384378 // I would like to use saturating multiplication here, but LLVM cannot lower it
385379 // on WebAssembly: https://github.com/ziglang/zig/issues/9660
386380 //const new_len_bytes = new_len *| @sizeOf(T);
......@@ -418,25 +412,23 @@ pub fn reallocAdvanced(
418412 new_n: usize,
419413 return_address: usize,
420414) Error!Slice(@TypeOf(old_mem)) {
421 const slice_info = @typeInfo(@TypeOf(old_mem)).pointer;
422 if (slice_info.size != .slice) {
423 const slice: Slice(@TypeOf(old_mem)) = old_mem; // coerce *[len]T to []T
424 return reallocAdvanced(self, slice, new_n, return_address);
425 }
415 const SliceType = Slice(@TypeOf(old_mem));
416 const slice: SliceType = old_mem; // coerce *[len]T to []T
417 const slice_info = @typeInfo(SliceType).pointer;
426418 comptime assert(slice_info.size == .slice);
427419 const T = slice_info.child;
428 if (old_mem.len == 0) {
420 if (slice.len == 0) {
429421 return self.allocAdvancedWithRetAddr(T, .fromByteUnitsOptional(slice_info.attrs.@"align"), new_n, return_address);
430422 }
431423 if (new_n == 0) {
432 self.free(old_mem);
424 self.free(slice);
433425 const alignment = slice_info.attrs.@"align" orelse @alignOf(T);
434426 const addr = comptime std.mem.alignBackward(usize, math.maxInt(usize), alignment);
435427 const ptr: *align(alignment) [0]T = @ptrFromInt(addr);
436428 return ptr;
437429 }
438430
439 const old_byte_slice: []u8 = @ptrCast(@constCast(mem.absorbSentinel(old_mem)));
431 const old_byte_slice: []u8 = @ptrCast(@constCast(mem.absorbSentinel(slice)));
440432 const byte_count = math.mul(usize, @sizeOf(T), new_n) catch return error.OutOfMemory;
441433 // Note: can't set shrunk memory to undefined as memory shouldn't be modified on realloc failure
442434 if (self.rawRemap(old_byte_slice, .fromByteUnits(slice_info.attrs.@"align" orelse @alignOf(T)), byte_count, return_address)) |p| {