@@ -102,8 +102,8 @@ pub inline fn rawFree(self: Allocator, buf: []u8, log2_buf_align: u8, ret_addr:
102
102
/// Call `destroy` with the result to free the memory.
103
103
pub fn create (self : Allocator , comptime T : type ) Error ! * T {
104
104
if (@sizeOf (T ) == 0 ) return @as (* T , @ptrFromInt (math .maxInt (usize )));
105
- const slice = try self .allocAdvancedWithRetAddr ( T , null , 1 , @returnAddress ());
106
- return & slice [ 0 ] ;
105
+ const ptr : * T = @ptrCast ( try self .allocBytesWithAlignment ( @alignOf ( T ), @sizeOf ( T ), @returnAddress () ));
106
+ return ptr ;
107
107
}
108
108
109
109
/// `ptr` should be the return value of `create`, or otherwise
@@ -113,7 +113,7 @@ pub fn destroy(self: Allocator, ptr: anytype) void {
113
113
const T = info .child ;
114
114
if (@sizeOf (T ) == 0 ) return ;
115
115
const non_const_ptr = @as ([* ]u8 , @ptrCast (@constCast (ptr )));
116
- self .rawFree (non_const_ptr [0.. @sizeOf (T )], math . log2 (info .alignment ), @returnAddress ());
116
+ self .rawFree (non_const_ptr [0.. @sizeOf (T )], log2a (info .alignment ), @returnAddress ());
117
117
}
118
118
119
119
/// Allocates an array of `n` items of type `T` and sets all the
@@ -192,7 +192,7 @@ pub fn alignedAlloc(
192
192
return self .allocAdvancedWithRetAddr (T , alignment , n , @returnAddress ());
193
193
}
194
194
195
- pub fn allocAdvancedWithRetAddr (
195
+ pub inline fn allocAdvancedWithRetAddr (
196
196
self : Allocator ,
197
197
comptime T : type ,
198
198
/// null means naturally aligned
@@ -201,23 +201,30 @@ pub fn allocAdvancedWithRetAddr(
201
201
return_address : usize ,
202
202
) Error ! []align (alignment orelse @alignOf (T )) T {
203
203
const a = alignment orelse @alignOf (T );
204
+ const ptr : [* ]align (a ) T = @ptrCast (try self .allocWithSizeAndAlignment (@sizeOf (T ), a , n , return_address ));
205
+ return ptr [0.. n ];
206
+ }
207
+
208
+ fn allocWithSizeAndAlignment (self : Allocator , comptime size : usize , comptime alignment : u29 , n : usize , return_address : usize ) Error ! [* ]align (alignment ) u8 {
209
+ const byte_count = math .mul (usize , size , n ) catch return Error .OutOfMemory ;
210
+ return self .allocBytesWithAlignment (alignment , byte_count , return_address );
211
+ }
204
212
213
+ fn allocBytesWithAlignment (self : Allocator , comptime alignment : u29 , byte_count : usize , return_address : usize ) Error ! [* ]align (alignment ) u8 {
205
214
// The Zig Allocator interface is not intended to solve alignments beyond
206
215
// the minimum OS page size. For these use cases, the caller must use OS
207
216
// APIs directly.
208
- comptime assert (a <= mem .page_size );
217
+ comptime assert (alignment <= mem .page_size );
209
218
210
- if (n == 0 ) {
211
- const ptr = comptime std .mem .alignBackward (usize , math .maxInt (usize ), a );
212
- return @as ([* ]align (a ) T , @ptrFromInt (ptr ))[0 .. 0] ;
219
+ if (byte_count == 0 ) {
220
+ const ptr = comptime std .mem .alignBackward (usize , math .maxInt (usize ), alignment );
221
+ return @as ([* ]align (alignment ) u8 , @ptrFromInt (ptr ));
213
222
}
214
223
215
- const byte_count = math .mul (usize , @sizeOf (T ), n ) catch return Error .OutOfMemory ;
216
- const byte_ptr = self .rawAlloc (byte_count , log2a (a ), return_address ) orelse return Error .OutOfMemory ;
224
+ const byte_ptr = self .rawAlloc (byte_count , log2a (alignment ), return_address ) orelse return Error .OutOfMemory ;
217
225
// TODO: https://github.com/ziglang/zig/issues/4298
218
226
@memset (byte_ptr [0.. byte_count ], undefined );
219
- const byte_slice : []align (a ) u8 = @alignCast (byte_ptr [0.. byte_count ]);
220
- return mem .bytesAsSlice (T , byte_slice );
227
+ return @as ([* ]align (alignment ) u8 , @alignCast (byte_ptr ));
221
228
}
222
229
223
230
/// Requests to modify the size of an allocation. It is guaranteed to not move
0 commit comments