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