| ... | @@ -104,12 +104,13 @@ const StackTrace = std.builtin.StackTrace; | ... | @@ -104,12 +104,13 @@ const StackTrace = std.builtin.StackTrace; |
| 104 | const page_size: usize = @max(std.heap.page_size_max, switch (builtin.os.tag) { | 104 | const page_size: usize = @max(std.heap.page_size_max, switch (builtin.os.tag) { |
| 105 | .windows => 64 * 1024, // Makes `std.heap.PageAllocator` take the happy path. | 105 | .windows => 64 * 1024, // Makes `std.heap.PageAllocator` take the happy path. |
| 106 | .wasi => 64 * 1024, // Max alignment supported by `std.heap.WasmAllocator`. | 106 | .wasi => 64 * 1024, // Max alignment supported by `std.heap.WasmAllocator`. |
| 107 | else => 2 * 1024 * 1024, // Avoids too many active mappings when `page_size_max` is low. | 107 | else => 512 * 1024, // Avoids too many active mappings when `page_size_max` is low. |
| 108 | }); | 108 | }); |
| 109 | const page_align: mem.Alignment = .fromByteUnits(page_size); | 109 | const page_align: mem.Alignment = .fromByteUnits(page_size); |
| 110 | | 110 | |
| 111 | /// Integer type for pointing to slots in a small allocation | 111 | /// Integer type for pointing to slots in a small allocation |
| 112 | const SlotIndex = std.meta.Int(.unsigned, math.log2(page_size) + 1); | 112 | const SlotIndex = std.meta.Int(.unsigned, math.log2(page_size) + 1); |
| | 113 | const Log2USize = std.math.Log2Int(usize); |
| 113 | | 114 | |
| 114 | const default_test_stack_trace_frames: usize = if (builtin.is_test) 10 else 6; | 115 | const default_test_stack_trace_frames: usize = if (builtin.is_test) 10 else 6; |
| 115 | const default_sys_stack_trace_frames: usize = if (std.debug.sys_can_stack_trace) default_test_stack_trace_frames else 0; | 116 | const default_sys_stack_trace_frames: usize = if (std.debug.sys_can_stack_trace) default_test_stack_trace_frames else 0; |
| ... | @@ -383,7 +384,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { | ... | @@ -383,7 +384,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 383 | | 384 | |
| 384 | /// This is executed only at compile-time to prepopulate a lookup table. | 385 | /// This is executed only at compile-time to prepopulate a lookup table. |
| 385 | fn calculateSlotCount(size_class_index: usize) SlotIndex { | 386 | fn calculateSlotCount(size_class_index: usize) SlotIndex { |
| 386 | const size_class = @as(usize, 1) << @as(u6, @intCast(size_class_index)); | 387 | const size_class = @as(usize, 1) << @as(Log2USize, @intCast(size_class_index)); |
| 387 | var lower: usize = 8; | 388 | var lower: usize = 8; |
| 388 | var upper: usize = (page_size - bucketSize(lower)) / size_class; | 389 | var upper: usize = (page_size - bucketSize(lower)) / size_class; |
| 389 | while (upper > lower) { | 390 | while (upper > lower) { |
| ... | @@ -408,7 +409,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { | ... | @@ -408,7 +409,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 408 | } | 409 | } |
| 409 | | 410 | |
| 410 | fn detectLeaksInBucket(bucket: *BucketHeader, size_class_index: usize, used_bits_count: usize) bool { | 411 | fn detectLeaksInBucket(bucket: *BucketHeader, size_class_index: usize, used_bits_count: usize) bool { |
| 411 | const size_class = @as(usize, 1) << @as(u6, @intCast(size_class_index)); | 412 | const size_class = @as(usize, 1) << @as(Log2USize, @intCast(size_class_index)); |
| 412 | const slot_count = slot_counts[size_class_index]; | 413 | const slot_count = slot_counts[size_class_index]; |
| 413 | var leaks = false; | 414 | var leaks = false; |
| 414 | var used_bits_byte: usize = 0; | 415 | var used_bits_byte: usize = 0; |
| ... | @@ -745,7 +746,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { | ... | @@ -745,7 +746,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 745 | const used_bits_byte = bucket.usedBits(slot_index / 8); | 746 | const used_bits_byte = bucket.usedBits(slot_index / 8); |
| 746 | const used_bit_index: u3 = @intCast(slot_index % 8); | 747 | const used_bit_index: u3 = @intCast(slot_index % 8); |
| 747 | used_bits_byte.* |= (@as(u8, 1) << used_bit_index); | 748 | used_bits_byte.* |= (@as(u8, 1) << used_bit_index); |
| 748 | const size_class = @as(usize, 1) << @as(u6, @intCast(size_class_index)); | 749 | const size_class = @as(usize, 1) << @as(Log2USize, @intCast(size_class_index)); |
| 749 | if (config.stack_trace_frames > 0) { | 750 | if (config.stack_trace_frames > 0) { |
| 750 | bucket.captureStackTrace(ret_addr, slot_count, slot_index, .alloc); | 751 | bucket.captureStackTrace(ret_addr, slot_count, slot_index, .alloc); |
| 751 | } | 752 | } |
| ... | @@ -858,7 +859,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { | ... | @@ -858,7 +859,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 858 | const bucket: *BucketHeader = .fromPage(page_addr, slot_count); | 859 | const bucket: *BucketHeader = .fromPage(page_addr, slot_count); |
| 859 | if (bucket.canary != config.canary) @panic("Invalid free"); | 860 | if (bucket.canary != config.canary) @panic("Invalid free"); |
| 860 | const page_offset = freed_addr - page_addr; | 861 | const page_offset = freed_addr - page_addr; |
| 861 | const size_class = @as(usize, 1) << @as(u6, @intCast(size_class_index)); | 862 | const size_class = @as(usize, 1) << @as(Log2USize, @intCast(size_class_index)); |
| 862 | const slot_index: SlotIndex = @intCast(page_offset / size_class); | 863 | const slot_index: SlotIndex = @intCast(page_offset / size_class); |
| 863 | const used_byte_index = slot_index / 8; | 864 | const used_byte_index = slot_index / 8; |
| 864 | const used_bit_index: u3 = @intCast(slot_index % 8); | 865 | const used_bit_index: u3 = @intCast(slot_index % 8); |
| ... | @@ -953,7 +954,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { | ... | @@ -953,7 +954,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 953 | const bucket: *BucketHeader = .fromPage(page_addr, slot_count); | 954 | const bucket: *BucketHeader = .fromPage(page_addr, slot_count); |
| 954 | if (bucket.canary != config.canary) @panic("Invalid free"); | 955 | if (bucket.canary != config.canary) @panic("Invalid free"); |
| 955 | const page_offset = memory_addr - page_addr; | 956 | const page_offset = memory_addr - page_addr; |
| 956 | const size_class = @as(usize, 1) << @as(u6, @intCast(size_class_index)); | 957 | const size_class = @as(usize, 1) << @as(Log2USize, @intCast(size_class_index)); |
| 957 | const slot_index: SlotIndex = @intCast(page_offset / size_class); | 958 | const slot_index: SlotIndex = @intCast(page_offset / size_class); |
| 958 | const used_byte_index = slot_index / 8; | 959 | const used_byte_index = slot_index / 8; |
| 959 | const used_bit_index: u3 = @intCast(slot_index % 8); | 960 | const used_bit_index: u3 = @intCast(slot_index % 8); |