| ... | @@ -68,7 +68,7 @@ fn alloc(ctx: *anyopaque, len: usize, alignment: u29, len_align: u29, ra: usize) | ... | @@ -68,7 +68,7 @@ fn alloc(ctx: *anyopaque, len: usize, alignment: u29, len_align: u29, ra: usize) |
| 68 | _ = len_align; | 68 | _ = len_align; |
| 69 | _ = ra; | 69 | _ = ra; |
| 70 | const aligned_len = @max(len, alignment); | 70 | const aligned_len = @max(len, alignment); |
| 71 | const slot_size = math.ceilPowerOfTwoAssert(usize, aligned_len); | 71 | const slot_size = math.ceilPowerOfTwo(usize, aligned_len) catch return error.OutOfMemory; |
| 72 | const class = math.log2(slot_size); | 72 | const class = math.log2(slot_size); |
| 73 | if (class < size_class_count) { | 73 | if (class < size_class_count) { |
| 74 | const addr = a: { | 74 | const addr = a: { |
| ... | @@ -113,12 +113,28 @@ fn resize( | ... | @@ -113,12 +113,28 @@ fn resize( |
| 113 | return_address: usize, | 113 | return_address: usize, |
| 114 | ) ?usize { | 114 | ) ?usize { |
| 115 | _ = ctx; | 115 | _ = ctx; |
| 116 | _ = buf_align; | | |
| 117 | _ = return_address; | 116 | _ = return_address; |
| 118 | _ = len_align; | 117 | _ = len_align; |
| 119 | _ = new_len; | 118 | // We don't want to move anything from one size class to another. But we can recover bytes |
| 120 | _ = buf; | 119 | // in between powers of two. |
| 121 | @panic("handle resize"); | 120 | const old_aligned_len = @max(buf.len, buf_align); |
| | 121 | const new_aligned_len = @max(new_len, buf_align); |
| | 122 | const old_small_slot_size = math.ceilPowerOfTwoAssert(usize, old_aligned_len); |
| | 123 | const old_small_class = math.log2(old_small_slot_size); |
| | 124 | if (old_small_class < size_class_count) { |
| | 125 | const new_small_slot_size = math.ceilPowerOfTwo(usize, new_aligned_len) catch return null; |
| | 126 | //std.debug.print("resize: old_small_slot_size={d} new_small_slot_size={d}\n", .{ |
| | 127 | // old_small_slot_size, new_small_slot_size, |
| | 128 | //}); |
| | 129 | if (old_small_slot_size != new_small_slot_size) return null; |
| | 130 | } else { |
| | 131 | const old_bigpages_needed = (old_aligned_len + (bigpage_size - 1)) / bigpage_size; |
| | 132 | const old_big_slot_size = math.ceilPowerOfTwoAssert(usize, old_bigpages_needed); |
| | 133 | const new_bigpages_needed = (new_aligned_len + (bigpage_size - 1)) / bigpage_size; |
| | 134 | const new_big_slot_size = math.ceilPowerOfTwo(usize, new_bigpages_needed) catch return null; |
| | 135 | if (old_big_slot_size != new_big_slot_size) return null; |
| | 136 | } |
| | 137 | return new_len; |
| 122 | } | 138 | } |
| 123 | | 139 | |
| 124 | fn free( | 140 | fn free( |
| ... | @@ -234,3 +250,44 @@ test "large allocations" { | ... | @@ -234,3 +250,44 @@ test "large allocations" { |
| 234 | test_ally.free(ptr3); | 250 | test_ally.free(ptr3); |
| 235 | test_ally.free(ptr2); | 251 | test_ally.free(ptr2); |
| 236 | } | 252 | } |
| | 253 | |
| | 254 | test "very large allocation" { |
| | 255 | try std.testing.expectError(error.OutOfMemory, test_ally.alloc(u8, math.maxInt(usize))); |
| | 256 | } |
| | 257 | |
| | 258 | test "realloc" { |
| | 259 | var slice = try test_ally.alignedAlloc(u8, @alignOf(u32), 1); |
| | 260 | defer test_ally.free(slice); |
| | 261 | slice[0] = 0x12; |
| | 262 | |
| | 263 | // This reallocation should keep its pointer address. |
| | 264 | const old_slice = slice; |
| | 265 | slice = try test_ally.realloc(slice, 2); |
| | 266 | try std.testing.expect(old_slice.ptr == slice.ptr); |
| | 267 | try std.testing.expect(slice[0] == 0x12); |
| | 268 | slice[1] = 0x34; |
| | 269 | |
| | 270 | // This requires upgrading to a larger size class |
| | 271 | slice = try test_ally.realloc(slice, 17); |
| | 272 | try std.testing.expect(slice[0] == 0x12); |
| | 273 | try std.testing.expect(slice[1] == 0x34); |
| | 274 | } |
| | 275 | |
| | 276 | test "shrink" { |
| | 277 | var slice = try test_ally.alloc(u8, 20); |
| | 278 | defer test_ally.free(slice); |
| | 279 | |
| | 280 | mem.set(u8, slice, 0x11); |
| | 281 | |
| | 282 | slice = test_ally.shrink(slice, 17); |
| | 283 | |
| | 284 | for (slice) |b| { |
| | 285 | try std.testing.expect(b == 0x11); |
| | 286 | } |
| | 287 | |
| | 288 | slice = test_ally.shrink(slice, 16); |
| | 289 | |
| | 290 | for (slice) |b| { |
| | 291 | try std.testing.expect(b == 0x11); |
| | 292 | } |
| | 293 | } |