@@ -141,6 +141,9 @@ pub const Allocator = struct {
141
141
const new_mem = try self .callAllocFn (new_len , new_alignment , len_align );
142
142
@memcpy (new_mem .ptr , old_mem .ptr , std .math .min (new_len , old_mem .len ));
143
143
// DISABLED TO AVOID BUGS IN TRANSLATE C
144
+ // use './zig build test-translate-c' to reproduce, some of the symbols in the
145
+ // generated C code will be a sequence of 0xaa (the undefined value), meaning
146
+ // it is printing data that has been freed
144
147
//@memset(old_mem.ptr, undefined, old_mem.len);
145
148
_ = self .shrinkBytes (old_mem , 0 , 0 );
146
149
return new_mem ;
@@ -214,18 +217,19 @@ pub const Allocator = struct {
214
217
return self .allocWithOptions (Elem , n , null , sentinel );
215
218
}
216
219
220
+ /// Deprecated: use `allocAdvanced`
217
221
pub fn alignedAlloc (
218
222
self : * Allocator ,
219
223
comptime T : type ,
220
224
/// null means naturally aligned
221
225
comptime alignment : ? u29 ,
222
226
n : usize ,
223
227
) Error ! []align (alignment orelse @alignOf (T )) T {
224
- return self .alignedAlloc2 (T , alignment , n , .exact );
228
+ return self .allocAdvanced (T , alignment , n , .exact );
225
229
}
226
230
227
- const Exact = enum {exact ,atLeast };
228
- pub fn alignedAlloc2 (
231
+ const Exact = enum {exact ,at_least };
232
+ pub fn allocAdvanced (
229
233
self : * Allocator ,
230
234
comptime T : type ,
231
235
/// null means naturally aligned
@@ -234,7 +238,7 @@ pub const Allocator = struct {
234
238
exact : Exact ,
235
239
) Error ! []align (alignment orelse @alignOf (T )) T {
236
240
const a = if (alignment ) | a | blk : {
237
- if (a == @alignOf (T )) return alignedAlloc2 (self , T , null , n , exact );
241
+ if (a == @alignOf (T )) return allocAdvanced (self , T , null , n , exact );
238
242
break :blk a ;
239
243
} else @alignOf (T );
240
244
@@ -248,7 +252,10 @@ pub const Allocator = struct {
248
252
// functions that heap-allocate their own frame with @Frame(func).
249
253
const sizeOfT = if (alignment == null ) @intCast (u29 , @divExact (byte_count , n )) else @sizeOf (T );
250
254
const byte_slice = try self .callAllocFn (byte_count , a , if (exact == .exact ) @as (u29 , 0 ) else sizeOfT );
251
- assert (if (exact == .exact ) byte_slice .len == byte_count else byte_slice .len >= byte_count );
255
+ switch (exact ) {
256
+ .exact = > assert (byte_slice .len == byte_count ),
257
+ .at_least = > assert (byte_slice .len >= byte_count ),
258
+ }
252
259
@memset (byte_slice .ptr , undefined , byte_slice .len );
253
260
if (alignment == null ) {
254
261
// This if block is a workaround (see comment above)
@@ -273,33 +280,31 @@ pub const Allocator = struct {
273
280
break :t Error ! []align (Slice .alignment ) Slice .child ;
274
281
} {
275
282
const old_alignment = @typeInfo (@TypeOf (old_mem )).Pointer .alignment ;
276
- return self .alignedRealloc2 (old_mem , old_alignment , new_n , .exact );
283
+ return self .reallocAdvanced (old_mem , old_alignment , new_n , .exact );
277
284
}
278
285
279
286
pub fn reallocAtLeast (self : * Allocator , old_mem : var , new_n : usize ) t : {
280
287
const Slice = @typeInfo (@TypeOf (old_mem )).Pointer ;
281
288
break :t Error ! []align (Slice .alignment ) Slice .child ;
282
289
} {
283
290
const old_alignment = @typeInfo (@TypeOf (old_mem )).Pointer .alignment ;
284
- return self .alignedRealloc2 (old_mem , old_alignment , new_n , .atLeast );
291
+ return self .reallocAdvanced (old_mem , old_alignment , new_n , .at_least );
285
292
}
286
293
287
- /// This is the same as `realloc`, except caller may additionally request
288
- /// a new alignment, which can be larger, smaller, or the same as the old
289
- /// allocation.
294
+ // Deprecated: use `reallocAdvanced`
290
295
pub fn alignedRealloc (
291
296
self : * Allocator ,
292
297
old_mem : var ,
293
298
comptime new_alignment : u29 ,
294
299
new_n : usize ,
295
300
) Error ! []align (new_alignment ) @typeInfo (@TypeOf (old_mem )).Pointer.child {
296
- return self .alignedRealloc2 (old_mem , new_alignment , new_n , .exact );
301
+ return self .reallocAdvanced (old_mem , new_alignment , new_n , .exact );
297
302
}
298
303
299
304
/// This is the same as `realloc`, except caller may additionally request
300
305
/// a new alignment, which can be larger, smaller, or the same as the old
301
306
/// allocation.
302
- pub fn alignedRealloc2 (
307
+ pub fn reallocAdvanced (
303
308
self : * Allocator ,
304
309
old_mem : var ,
305
310
comptime new_alignment : u29 ,
@@ -309,7 +314,7 @@ pub const Allocator = struct {
309
314
const Slice = @typeInfo (@TypeOf (old_mem )).Pointer ;
310
315
const T = Slice .child ;
311
316
if (old_mem .len == 0 ) {
312
- return self .alignedAlloc2 (T , new_alignment , new_n , exact );
317
+ return self .allocAdvanced (T , new_alignment , new_n , exact );
313
318
}
314
319
if (new_n == 0 ) {
315
320
self .free (old_mem );
@@ -408,8 +413,9 @@ pub fn getAllocatorPtr(allocatorStatePtr: var) *Allocator {
408
413
return & allocatorStatePtr .allocator ;
409
414
}
410
415
411
- /// Detects and asserts if the std.mem.Allocator interface is violated
412
- pub fn SanityAllocator (comptime T : type ) type { return struct {
416
+ /// Detects and asserts if the std.mem.Allocator interface is violated by the caller
417
+ /// or the allocator.
418
+ pub fn ValidationAllocator (comptime T : type ) type { return struct {
413
419
const Self = @This ();
414
420
allocator : Allocator ,
415
421
underlying_allocator : T ,
@@ -436,6 +442,7 @@ pub fn SanityAllocator(comptime T: type) type { return struct {
436
442
437
443
const self = @fieldParentPtr (@This (), "allocator" , allocator );
438
444
const result = try self .getUnderlyingAllocatorPtr ().callAllocFn (n , ptr_align , len_align );
445
+ assert (mem .isAligned (@ptrToInt (result .ptr ), ptr_align ));
439
446
if (len_align == 0 ) {
440
447
assert (result .len == n );
441
448
} else {
@@ -467,8 +474,8 @@ pub fn SanityAllocator(comptime T: type) type { return struct {
467
474
};
468
475
};}
469
476
470
- pub fn sanityWrap (allocator : var ) SanityAllocator (@TypeOf (allocator )) {
471
- return SanityAllocator (@TypeOf (allocator )).init (allocator );
477
+ pub fn validationWrap (allocator : var ) ValidationAllocator (@TypeOf (allocator )) {
478
+ return ValidationAllocator (@TypeOf (allocator )).init (allocator );
472
479
}
473
480
474
481
/// An allocator helper function. Adjusts an allocation length satisfy `len_align`.
@@ -2377,6 +2384,8 @@ test "alignForward" {
2377
2384
testing .expect (alignForward (17 , 8 ) == 24 );
2378
2385
}
2379
2386
2387
+ /// Round an address up to the previous aligned address
2388
+ /// Unlike `alignBackward`, `alignment` can be any positive number, not just a power of 2.
2380
2389
pub fn alignBackwardAnyAlign (i : usize , alignment : usize ) usize {
2381
2390
if (@popCount (usize , alignment ) == 1 )
2382
2391
return alignBackward (i , alignment );
0 commit comments