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(...@@ -316,18 +316,15 @@ pub fn allocBytesAligned(
316///316///
317/// `new_len` may be zero, in which case the allocation is freed.317/// `new_len` may be zero, in which case the allocation is freed.
318pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool {318pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool {
319 const slice_info = @typeInfo(@TypeOf(allocation)).pointer;319 const SliceType = Slice(@TypeOf(allocation));
320 if (slice_info.size != .slice) {320 const slice: SliceType = allocation; // coerce *[len]T to []T
321 const slice: Slice(@TypeOf(allocation)) = allocation; // coerce *[len]T to []T321 const slice_info = @typeInfo(SliceType).pointer;
322 return resize(self, slice, new_len);
323 }
324 comptime assert(slice_info.size == .slice);
325 const T = slice_info.child;322 const T = slice_info.child;
326 if (new_len == 0) {323 if (new_len == 0) {
327 self.free(allocation);324 self.free(slice);
328 return true;325 return true;
329 }326 }
330 if (allocation.len == 0) {327 if (slice.len == 0) {
331 return false;328 return false;
332 }329 }
333 const old_memory: []u8 = @ptrCast(@constCast(mem.absorbSentinel(allocation)));330 const old_memory: []u8 = @ptrCast(@constCast(mem.absorbSentinel(allocation)));
...@@ -360,27 +357,24 @@ pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool {...@@ -360,27 +357,24 @@ pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool {
360///357///
361/// If the allocation's elements' type is zero bytes sized, `allocation.len` is set to `new_len`.358/// If the allocation's elements' type is zero bytes sized, `allocation.len` is set to `new_len`.
362pub fn remap(self: Allocator, allocation: anytype, new_len: usize) ?Slice(@TypeOf(allocation)) {359pub fn remap(self: Allocator, allocation: anytype, new_len: usize) ?Slice(@TypeOf(allocation)) {
363 const slice_info = @typeInfo(@TypeOf(allocation)).pointer;360 const SliceType = Slice(@TypeOf(allocation));
364 if (slice_info.size != .slice) {361 const slice: SliceType = allocation; // coerce *[len]T to []T
365 const slice: Slice(@TypeOf(allocation)) = allocation; // coerce *[len]T to []T362 const slice_info = @typeInfo(SliceType).pointer;
366 return remap(self, slice, new_len);
367 }
368 comptime assert(slice_info.size == .slice);
369 const T = slice_info.child;363 const T = slice_info.child;
370364
371 if (new_len == 0) {365 if (new_len == 0) {
372 self.free(allocation);366 self.free(slice);
373 return allocation[0..0];367 return slice[0..0];
374 }368 }
375 if (allocation.len == 0) {369 if (slice.len == 0) {
376 return null;370 return null;
377 }371 }
378 if (@sizeOf(T) == 0) {372 if (@sizeOf(T) == 0) {
379 var new_memory = allocation;373 var new_memory = slice;
380 new_memory.len = new_len;374 new_memory.len = new_len;
381 return new_memory;375 return new_memory;
382 }376 }
383 const old_memory: []u8 = @ptrCast(@constCast(mem.absorbSentinel(allocation)));377 const old_memory: []u8 = @ptrCast(@constCast(mem.absorbSentinel(slice)));
384 // I would like to use saturating multiplication here, but LLVM cannot lower it378 // I would like to use saturating multiplication here, but LLVM cannot lower it
385 // on WebAssembly: https://github.com/ziglang/zig/issues/9660379 // on WebAssembly: https://github.com/ziglang/zig/issues/9660
386 //const new_len_bytes = new_len *| @sizeOf(T);380 //const new_len_bytes = new_len *| @sizeOf(T);
...@@ -418,25 +412,23 @@ pub fn reallocAdvanced(...@@ -418,25 +412,23 @@ pub fn reallocAdvanced(
418 new_n: usize,412 new_n: usize,
419 return_address: usize,413 return_address: usize,
420) Error!Slice(@TypeOf(old_mem)) {414) Error!Slice(@TypeOf(old_mem)) {
421 const slice_info = @typeInfo(@TypeOf(old_mem)).pointer;415 const SliceType = Slice(@TypeOf(old_mem));
422 if (slice_info.size != .slice) {416 const slice: SliceType = old_mem; // coerce *[len]T to []T
423 const slice: Slice(@TypeOf(old_mem)) = old_mem; // coerce *[len]T to []T417 const slice_info = @typeInfo(SliceType).pointer;
424 return reallocAdvanced(self, slice, new_n, return_address);
425 }
426 comptime assert(slice_info.size == .slice);418 comptime assert(slice_info.size == .slice);
427 const T = slice_info.child;419 const T = slice_info.child;
428 if (old_mem.len == 0) {420 if (slice.len == 0) {
429 return self.allocAdvancedWithRetAddr(T, .fromByteUnitsOptional(slice_info.attrs.@"align"), new_n, return_address);421 return self.allocAdvancedWithRetAddr(T, .fromByteUnitsOptional(slice_info.attrs.@"align"), new_n, return_address);
430 }422 }
431 if (new_n == 0) {423 if (new_n == 0) {
432 self.free(old_mem);424 self.free(slice);
433 const alignment = slice_info.attrs.@"align" orelse @alignOf(T);425 const alignment = slice_info.attrs.@"align" orelse @alignOf(T);
434 const addr = comptime std.mem.alignBackward(usize, math.maxInt(usize), alignment);426 const addr = comptime std.mem.alignBackward(usize, math.maxInt(usize), alignment);
435 const ptr: *align(alignment) [0]T = @ptrFromInt(addr);427 const ptr: *align(alignment) [0]T = @ptrFromInt(addr);
436 return ptr;428 return ptr;
437 }429 }
438430
439 const old_byte_slice: []u8 = @ptrCast(@constCast(mem.absorbSentinel(old_mem)));431 const old_byte_slice: []u8 = @ptrCast(@constCast(mem.absorbSentinel(slice)));
440 const byte_count = math.mul(usize, @sizeOf(T), new_n) catch return error.OutOfMemory;432 const byte_count = math.mul(usize, @sizeOf(T), new_n) catch return error.OutOfMemory;
441 // Note: can't set shrunk memory to undefined as memory shouldn't be modified on realloc failure433 // Note: can't set shrunk memory to undefined as memory shouldn't be modified on realloc failure
442 if (self.rawRemap(old_byte_slice, .fromByteUnits(slice_info.attrs.@"align" orelse @alignOf(T)), byte_count, return_address)) |p| {434 if (self.rawRemap(old_byte_slice, .fromByteUnits(slice_info.attrs.@"align" orelse @alignOf(T)), byte_count, return_address)) |p| {