| ... | @@ -147,12 +147,12 @@ const CAllocator = struct { | ... | @@ -147,12 +147,12 @@ const CAllocator = struct { |
| 147 | return @as(*[*]u8, @ptrFromInt(@intFromPtr(ptr) - @sizeOf(usize))); | 147 | return @as(*[*]u8, @ptrFromInt(@intFromPtr(ptr) - @sizeOf(usize))); |
| 148 | } | 148 | } |
| 149 | | 149 | |
| 150 | fn alignedAlloc(len: usize, log2_align: u8) ?[*]u8 { | 150 | fn alignedAlloc(len: usize, alignment: mem.Alignment) ?[*]u8 { |
| 151 | const alignment = @as(usize, 1) << @as(Allocator.Log2Align, @intCast(log2_align)); | 151 | const alignment_bytes = alignment.toByteUnits(); |
| 152 | if (supports_posix_memalign) { | 152 | if (supports_posix_memalign) { |
| 153 | // The posix_memalign only accepts alignment values that are a | 153 | // The posix_memalign only accepts alignment values that are a |
| 154 | // multiple of the pointer size | 154 | // multiple of the pointer size |
| 155 | const eff_alignment = @max(alignment, @sizeOf(usize)); | 155 | const eff_alignment = @max(alignment_bytes, @sizeOf(usize)); |
| 156 | | 156 | |
| 157 | var aligned_ptr: ?*anyopaque = undefined; | 157 | var aligned_ptr: ?*anyopaque = undefined; |
| 158 | if (c.posix_memalign(&aligned_ptr, eff_alignment, len) != 0) | 158 | if (c.posix_memalign(&aligned_ptr, eff_alignment, len) != 0) |
| ... | @@ -164,9 +164,9 @@ const CAllocator = struct { | ... | @@ -164,9 +164,9 @@ const CAllocator = struct { |
| 164 | // Thin wrapper around regular malloc, overallocate to account for | 164 | // Thin wrapper around regular malloc, overallocate to account for |
| 165 | // alignment padding and store the original malloc()'ed pointer before | 165 | // alignment padding and store the original malloc()'ed pointer before |
| 166 | // the aligned address. | 166 | // the aligned address. |
| 167 | const unaligned_ptr = @as([*]u8, @ptrCast(c.malloc(len + alignment - 1 + @sizeOf(usize)) orelse return null)); | 167 | const unaligned_ptr = @as([*]u8, @ptrCast(c.malloc(len + alignment_bytes - 1 + @sizeOf(usize)) orelse return null)); |
| 168 | const unaligned_addr = @intFromPtr(unaligned_ptr); | 168 | const unaligned_addr = @intFromPtr(unaligned_ptr); |
| 169 | const aligned_addr = mem.alignForward(usize, unaligned_addr + @sizeOf(usize), alignment); | 169 | const aligned_addr = mem.alignForward(usize, unaligned_addr + @sizeOf(usize), alignment_bytes); |
| 170 | const aligned_ptr = unaligned_ptr + (aligned_addr - unaligned_addr); | 170 | const aligned_ptr = unaligned_ptr + (aligned_addr - unaligned_addr); |
| 171 | getHeader(aligned_ptr).* = unaligned_ptr; | 171 | getHeader(aligned_ptr).* = unaligned_ptr; |
| 172 | | 172 | |
| ... | @@ -195,22 +195,22 @@ const CAllocator = struct { | ... | @@ -195,22 +195,22 @@ const CAllocator = struct { |
| 195 | fn alloc( | 195 | fn alloc( |
| 196 | _: *anyopaque, | 196 | _: *anyopaque, |
| 197 | len: usize, | 197 | len: usize, |
| 198 | log2_align: u8, | 198 | alignment: mem.Alignment, |
| 199 | return_address: usize, | 199 | return_address: usize, |
| 200 | ) ?[*]u8 { | 200 | ) ?[*]u8 { |
| 201 | _ = return_address; | 201 | _ = return_address; |
| 202 | assert(len > 0); | 202 | assert(len > 0); |
| 203 | return alignedAlloc(len, log2_align); | 203 | return alignedAlloc(len, alignment); |
| 204 | } | 204 | } |
| 205 | | 205 | |
| 206 | fn resize( | 206 | fn resize( |
| 207 | _: *anyopaque, | 207 | _: *anyopaque, |
| 208 | buf: []u8, | 208 | buf: []u8, |
| 209 | log2_buf_align: u8, | 209 | alignment: mem.Alignment, |
| 210 | new_len: usize, | 210 | new_len: usize, |
| 211 | return_address: usize, | 211 | return_address: usize, |
| 212 | ) bool { | 212 | ) bool { |
| 213 | _ = log2_buf_align; | 213 | _ = alignment; |
| 214 | _ = return_address; | 214 | _ = return_address; |
| 215 | if (new_len <= buf.len) { | 215 | if (new_len <= buf.len) { |
| 216 | return true; | 216 | return true; |
| ... | @@ -227,10 +227,10 @@ const CAllocator = struct { | ... | @@ -227,10 +227,10 @@ const CAllocator = struct { |
| 227 | fn free( | 227 | fn free( |
| 228 | _: *anyopaque, | 228 | _: *anyopaque, |
| 229 | buf: []u8, | 229 | buf: []u8, |
| 230 | log2_buf_align: u8, | 230 | alignment: mem.Alignment, |
| 231 | return_address: usize, | 231 | return_address: usize, |
| 232 | ) void { | 232 | ) void { |
| 233 | _ = log2_buf_align; | 233 | _ = alignment; |
| 234 | _ = return_address; | 234 | _ = return_address; |
| 235 | alignedFree(buf.ptr); | 235 | alignedFree(buf.ptr); |
| 236 | } | 236 | } |
| ... | @@ -267,28 +267,28 @@ const raw_c_allocator_vtable = Allocator.VTable{ | ... | @@ -267,28 +267,28 @@ const raw_c_allocator_vtable = Allocator.VTable{ |
| 267 | fn rawCAlloc( | 267 | fn rawCAlloc( |
| 268 | _: *anyopaque, | 268 | _: *anyopaque, |
| 269 | len: usize, | 269 | len: usize, |
| 270 | log2_ptr_align: u8, | 270 | alignment: mem.Alignment, |
| 271 | ret_addr: usize, | 271 | ret_addr: usize, |
| 272 | ) ?[*]u8 { | 272 | ) ?[*]u8 { |
| 273 | _ = ret_addr; | 273 | _ = ret_addr; |
| 274 | assert(log2_ptr_align <= comptime std.math.log2_int(usize, @alignOf(std.c.max_align_t))); | 274 | assert(alignment.order(.le, comptime .fromByteUnits(@alignOf(std.c.max_align_t)))); |
| 275 | // Note that this pointer cannot be aligncasted to max_align_t because if | 275 | // Note that this pointer cannot be aligncasted to max_align_t because if |
| 276 | // len is < max_align_t then the alignment can be smaller. For example, if | 276 | // len is < max_align_t then the alignment can be smaller. For example, if |
| 277 | // max_align_t is 16, but the user requests 8 bytes, there is no built-in | 277 | // max_align_t is 16, but the user requests 8 bytes, there is no built-in |
| 278 | // type in C that is size 8 and has 16 byte alignment, so the alignment may | 278 | // type in C that is size 8 and has 16 byte alignment, so the alignment may |
| 279 | // be 8 bytes rather than 16. Similarly if only 1 byte is requested, malloc | 279 | // be 8 bytes rather than 16. Similarly if only 1 byte is requested, malloc |
| 280 | // is allowed to return a 1-byte aligned pointer. | 280 | // is allowed to return a 1-byte aligned pointer. |
| 281 | return @as(?[*]u8, @ptrCast(c.malloc(len))); | 281 | return @ptrCast(c.malloc(len)); |
| 282 | } | 282 | } |
| 283 | | 283 | |
| 284 | fn rawCResize( | 284 | fn rawCResize( |
| 285 | _: *anyopaque, | 285 | _: *anyopaque, |
| 286 | buf: []u8, | 286 | buf: []u8, |
| 287 | log2_old_align: u8, | 287 | alignment: mem.Alignment, |
| 288 | new_len: usize, | 288 | new_len: usize, |
| 289 | ret_addr: usize, | 289 | ret_addr: usize, |
| 290 | ) bool { | 290 | ) bool { |
| 291 | _ = log2_old_align; | 291 | _ = alignment; |
| 292 | _ = ret_addr; | 292 | _ = ret_addr; |
| 293 | | 293 | |
| 294 | if (new_len <= buf.len) | 294 | if (new_len <= buf.len) |
| ... | @@ -305,10 +305,10 @@ fn rawCResize( | ... | @@ -305,10 +305,10 @@ fn rawCResize( |
| 305 | fn rawCFree( | 305 | fn rawCFree( |
| 306 | _: *anyopaque, | 306 | _: *anyopaque, |
| 307 | buf: []u8, | 307 | buf: []u8, |
| 308 | log2_old_align: u8, | 308 | alignment: mem.Alignment, |
| 309 | ret_addr: usize, | 309 | ret_addr: usize, |
| 310 | ) void { | 310 | ) void { |
| 311 | _ = log2_old_align; | 311 | _ = alignment; |
| 312 | _ = ret_addr; | 312 | _ = ret_addr; |
| 313 | c.free(buf.ptr); | 313 | c.free(buf.ptr); |
| 314 | } | 314 | } |
| ... | @@ -380,13 +380,13 @@ pub const HeapAllocator = switch (builtin.os.tag) { | ... | @@ -380,13 +380,13 @@ pub const HeapAllocator = switch (builtin.os.tag) { |
| 380 | fn alloc( | 380 | fn alloc( |
| 381 | ctx: *anyopaque, | 381 | ctx: *anyopaque, |
| 382 | n: usize, | 382 | n: usize, |
| 383 | log2_ptr_align: u8, | 383 | alignment: mem.Alignment, |
| 384 | return_address: usize, | 384 | return_address: usize, |
| 385 | ) ?[*]u8 { | 385 | ) ?[*]u8 { |
| 386 | _ = return_address; | 386 | _ = return_address; |
| 387 | const self: *HeapAllocator = @ptrCast(@alignCast(ctx)); | 387 | const self: *HeapAllocator = @ptrCast(@alignCast(ctx)); |
| 388 | | 388 | |
| 389 | const ptr_align = @as(usize, 1) << @as(Allocator.Log2Align, @intCast(log2_ptr_align)); | 389 | const ptr_align = alignment.toByteUnits(); |
| 390 | const amt = n + ptr_align - 1 + @sizeOf(usize); | 390 | const amt = n + ptr_align - 1 + @sizeOf(usize); |
| 391 | const optional_heap_handle = @atomicLoad(?HeapHandle, &self.heap_handle, .seq_cst); | 391 | const optional_heap_handle = @atomicLoad(?HeapHandle, &self.heap_handle, .seq_cst); |
| 392 | const heap_handle = optional_heap_handle orelse blk: { | 392 | const heap_handle = optional_heap_handle orelse blk: { |
| ... | @@ -407,11 +407,11 @@ pub const HeapAllocator = switch (builtin.os.tag) { | ... | @@ -407,11 +407,11 @@ pub const HeapAllocator = switch (builtin.os.tag) { |
| 407 | fn resize( | 407 | fn resize( |
| 408 | ctx: *anyopaque, | 408 | ctx: *anyopaque, |
| 409 | buf: []u8, | 409 | buf: []u8, |
| 410 | log2_buf_align: u8, | 410 | alignment: mem.Alignment, |
| 411 | new_size: usize, | 411 | new_size: usize, |
| 412 | return_address: usize, | 412 | return_address: usize, |
| 413 | ) bool { | 413 | ) bool { |
| 414 | _ = log2_buf_align; | 414 | _ = alignment; |
| 415 | _ = return_address; | 415 | _ = return_address; |
| 416 | const self: *HeapAllocator = @ptrCast(@alignCast(ctx)); | 416 | const self: *HeapAllocator = @ptrCast(@alignCast(ctx)); |
| 417 | | 417 | |
| ... | @@ -432,10 +432,10 @@ pub const HeapAllocator = switch (builtin.os.tag) { | ... | @@ -432,10 +432,10 @@ pub const HeapAllocator = switch (builtin.os.tag) { |
| 432 | fn free( | 432 | fn free( |
| 433 | ctx: *anyopaque, | 433 | ctx: *anyopaque, |
| 434 | buf: []u8, | 434 | buf: []u8, |
| 435 | log2_buf_align: u8, | 435 | alignment: mem.Alignment, |
| 436 | return_address: usize, | 436 | return_address: usize, |
| 437 | ) void { | 437 | ) void { |
| 438 | _ = log2_buf_align; | 438 | _ = alignment; |
| 439 | _ = return_address; | 439 | _ = return_address; |
| 440 | const self: *HeapAllocator = @ptrCast(@alignCast(ctx)); | 440 | const self: *HeapAllocator = @ptrCast(@alignCast(ctx)); |
| 441 | windows.HeapFree(self.heap_handle.?, 0, @as(*anyopaque, @ptrFromInt(getRecordPtr(buf).*))); | 441 | windows.HeapFree(self.heap_handle.?, 0, @as(*anyopaque, @ptrFromInt(getRecordPtr(buf).*))); |
| ... | @@ -482,6 +482,7 @@ pub fn StackFallbackAllocator(comptime size: usize) type { | ... | @@ -482,6 +482,7 @@ pub fn StackFallbackAllocator(comptime size: usize) type { |
| 482 | .vtable = &.{ | 482 | .vtable = &.{ |
| 483 | .alloc = alloc, | 483 | .alloc = alloc, |
| 484 | .resize = resize, | 484 | .resize = resize, |
| | 485 | .remap = remap, |
| 485 | .free = free, | 486 | .free = free, |
| 486 | }, | 487 | }, |
| 487 | }; | 488 | }; |
| ... | @@ -496,40 +497,55 @@ pub fn StackFallbackAllocator(comptime size: usize) type { | ... | @@ -496,40 +497,55 @@ pub fn StackFallbackAllocator(comptime size: usize) type { |
| 496 | fn alloc( | 497 | fn alloc( |
| 497 | ctx: *anyopaque, | 498 | ctx: *anyopaque, |
| 498 | len: usize, | 499 | len: usize, |
| 499 | log2_ptr_align: u8, | 500 | alignment: mem.Alignment, |
| 500 | ra: usize, | 501 | ra: usize, |
| 501 | ) ?[*]u8 { | 502 | ) ?[*]u8 { |
| 502 | const self: *Self = @ptrCast(@alignCast(ctx)); | 503 | const self: *Self = @ptrCast(@alignCast(ctx)); |
| 503 | return FixedBufferAllocator.alloc(&self.fixed_buffer_allocator, len, log2_ptr_align, ra) orelse | 504 | return FixedBufferAllocator.alloc(&self.fixed_buffer_allocator, len, alignment, ra) orelse |
| 504 | return self.fallback_allocator.rawAlloc(len, log2_ptr_align, ra); | 505 | return self.fallback_allocator.rawAlloc(len, alignment, ra); |
| 505 | } | 506 | } |
| 506 | | 507 | |
| 507 | fn resize( | 508 | fn resize( |
| 508 | ctx: *anyopaque, | 509 | ctx: *anyopaque, |
| 509 | buf: []u8, | 510 | buf: []u8, |
| 510 | log2_buf_align: u8, | 511 | alignment: mem.Alignment, |
| 511 | new_len: usize, | 512 | new_len: usize, |
| 512 | ra: usize, | 513 | ra: usize, |
| 513 | ) bool { | 514 | ) bool { |
| 514 | const self: *Self = @ptrCast(@alignCast(ctx)); | 515 | const self: *Self = @ptrCast(@alignCast(ctx)); |
| 515 | if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) { | 516 | if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) { |
| 516 | return FixedBufferAllocator.resize(&self.fixed_buffer_allocator, buf, log2_buf_align, new_len, ra); | 517 | return FixedBufferAllocator.resize(&self.fixed_buffer_allocator, buf, alignment, new_len, ra); |
| 517 | } else { | 518 | } else { |
| 518 | return self.fallback_allocator.rawResize(buf, log2_buf_align, new_len, ra); | 519 | return self.fallback_allocator.rawResize(buf, alignment, new_len, ra); |
| | 520 | } |
| | 521 | } |
| | 522 | |
| | 523 | fn remap( |
| | 524 | context: *anyopaque, |
| | 525 | memory: []u8, |
| | 526 | alignment: mem.Alignment, |
| | 527 | new_len: usize, |
| | 528 | return_address: usize, |
| | 529 | ) ?[*]u8 { |
| | 530 | const self: *Self = @ptrCast(@alignCast(context)); |
| | 531 | if (self.fixed_buffer_allocator.ownsPtr(memory.ptr)) { |
| | 532 | return FixedBufferAllocator.remap(&self.fixed_buffer_allocator, memory, alignment, new_len, return_address); |
| | 533 | } else { |
| | 534 | return self.fallback_allocator.rawRemap(memory, alignment, new_len, return_address); |
| 519 | } | 535 | } |
| 520 | } | 536 | } |
| 521 | | 537 | |
| 522 | fn free( | 538 | fn free( |
| 523 | ctx: *anyopaque, | 539 | ctx: *anyopaque, |
| 524 | buf: []u8, | 540 | buf: []u8, |
| 525 | log2_buf_align: u8, | 541 | alignment: mem.Alignment, |
| 526 | ra: usize, | 542 | ra: usize, |
| 527 | ) void { | 543 | ) void { |
| 528 | const self: *Self = @ptrCast(@alignCast(ctx)); | 544 | const self: *Self = @ptrCast(@alignCast(ctx)); |
| 529 | if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) { | 545 | if (self.fixed_buffer_allocator.ownsPtr(buf.ptr)) { |
| 530 | return FixedBufferAllocator.free(&self.fixed_buffer_allocator, buf, log2_buf_align, ra); | 546 | return FixedBufferAllocator.free(&self.fixed_buffer_allocator, buf, alignment, ra); |
| 531 | } else { | 547 | } else { |
| 532 | return self.fallback_allocator.rawFree(buf, log2_buf_align, ra); | 548 | return self.fallback_allocator.rawFree(buf, alignment, ra); |
| 533 | } | 549 | } |
| 534 | } | 550 | } |
| 535 | }; | 551 | }; |