| ... | @@ -319,11 +319,6 @@ fn pushFreeList(arena: *ArenaAllocator, first: *Node, last: *Node) void { | ... | @@ -319,11 +319,6 @@ fn pushFreeList(arena: *ArenaAllocator, first: *Node, last: *Node) void { |
| 319 | } | 319 | } |
| 320 | } | 320 | } |
| 321 | | 321 | |
| 322 | fn sliceContainsSlice(container: []u8, slice: []u8) bool { | | |
| 323 | return @intFromPtr(slice.ptr) >= @intFromPtr(container.ptr) and | | |
| 324 | @intFromPtr(slice.ptr + slice.len) <= @intFromPtr(container.ptr + container.len); | | |
| 325 | } | | |
| 326 | | | |
| 327 | fn alignedIndex(buf_ptr: [*]u8, end_index: usize, alignment: Alignment) usize { | 322 | fn alignedIndex(buf_ptr: [*]u8, end_index: usize, alignment: Alignment) usize { |
| 328 | // Wrapping arithmetic to avoid overflows since `end_index` isn't bounded by | 323 | // Wrapping arithmetic to avoid overflows since `end_index` isn't bounded by |
| 329 | // `size`. This is always ok since the max alignment in byte units is also | 324 | // `size`. This is always ok since the max alignment in byte units is also |
| ... | @@ -548,17 +543,12 @@ fn resize(ctx: *anyopaque, memory: []u8, alignment: Alignment, new_len: usize, r | ... | @@ -548,17 +543,12 @@ fn resize(ctx: *anyopaque, memory: []u8, alignment: Alignment, new_len: usize, r |
| 548 | assert(new_len > 0); | 543 | assert(new_len > 0); |
| 549 | | 544 | |
| 550 | const node = arena.loadFirstNode().?; | 545 | const node = arena.loadFirstNode().?; |
| 551 | const buf = node.loadBuf(); | 546 | const buf_ptr = @as([*]u8, @ptrCast(node)) + @sizeOf(Node); |
| 552 | | | |
| 553 | if (!sliceContainsSlice(buf, memory)) { | | |
| 554 | // Not within current node. | | |
| 555 | return new_len <= memory.len; | | |
| 556 | } | | |
| 557 | | 547 | |
| 558 | const cur_end_index = @atomicLoad(usize, &node.end_index, .monotonic); | 548 | const cur_end_index = @atomicLoad(usize, &node.end_index, .monotonic); |
| 559 | | 549 | if (buf_ptr + cur_end_index != memory.ptr + memory.len) { |
| 560 | if (buf.ptr + cur_end_index != memory.ptr + memory.len) { | 550 | // It's not the most recent allocation, so it cannot be expanded, |
| 561 | // It's not the most recent allocation, so it cannot be expanded. | 551 | // but it's fine if they want to make it smaller. |
| 562 | return new_len <= memory.len; | 552 | return new_len <= memory.len; |
| 563 | } | 553 | } |
| 564 | | 554 | |
| ... | @@ -566,12 +556,15 @@ fn resize(ctx: *anyopaque, memory: []u8, alignment: Alignment, new_len: usize, r | ... | @@ -566,12 +556,15 @@ fn resize(ctx: *anyopaque, memory: []u8, alignment: Alignment, new_len: usize, r |
| 566 | if (memory.len >= new_len) { | 556 | if (memory.len >= new_len) { |
| 567 | break :new_end_index cur_end_index - (memory.len - new_len); | 557 | break :new_end_index cur_end_index - (memory.len - new_len); |
| 568 | } | 558 | } |
| 569 | if (buf.len - cur_end_index >= new_len - memory.len) { | 559 | const cur_buf_len: usize = node.loadBuf().len; |
| | 560 | // Saturating arithmetic because `end_index` and `size` are not |
| | 561 | // guaranteed to be in sync. |
| | 562 | if (cur_buf_len -| cur_end_index >= new_len - memory.len) { |
| 570 | break :new_end_index cur_end_index + (new_len - memory.len); | 563 | break :new_end_index cur_end_index + (new_len - memory.len); |
| 571 | } | 564 | } |
| 572 | return false; | 565 | return false; |
| 573 | }; | 566 | }; |
| 574 | assert(buf.ptr + new_end_index == memory.ptr + new_len); | 567 | assert(buf_ptr + new_end_index == memory.ptr + new_len); |
| 575 | | 568 | |
| 576 | return null == @cmpxchgStrong( | 569 | return null == @cmpxchgStrong( |
| 577 | usize, | 570 | usize, |
| ... | @@ -596,22 +589,16 @@ fn free(ctx: *anyopaque, memory: []u8, alignment: Alignment, ret_addr: usize) vo | ... | @@ -596,22 +589,16 @@ fn free(ctx: *anyopaque, memory: []u8, alignment: Alignment, ret_addr: usize) vo |
| 596 | assert(memory.len > 0); | 589 | assert(memory.len > 0); |
| 597 | | 590 | |
| 598 | const node = arena.loadFirstNode().?; | 591 | const node = arena.loadFirstNode().?; |
| 599 | const buf = node.loadBuf(); | 592 | const buf_ptr = @as([*]u8, @ptrCast(node)) + @sizeOf(Node); |
| 600 | | | |
| 601 | if (!sliceContainsSlice(buf, memory)) { | | |
| 602 | // Not within current node; we cannot free it. | | |
| 603 | return; | | |
| 604 | } | | |
| 605 | | 593 | |
| 606 | const cur_end_index = @atomicLoad(usize, &node.end_index, .monotonic); | 594 | const cur_end_index = @atomicLoad(usize, &node.end_index, .monotonic); |
| 607 | | 595 | if (buf_ptr + cur_end_index != memory.ptr + memory.len) { |
| 608 | if (buf.ptr + cur_end_index != memory.ptr + memory.len) { | | |
| 609 | // Not the most recent allocation; we cannot free it. | 596 | // Not the most recent allocation; we cannot free it. |
| 610 | return; | 597 | return; |
| 611 | } | 598 | } |
| 612 | | 599 | |
| 613 | const new_end_index = cur_end_index - memory.len; | 600 | const new_end_index = cur_end_index - memory.len; |
| 614 | assert(buf.ptr + new_end_index == memory.ptr); | 601 | assert(buf_ptr + new_end_index == memory.ptr); |
| 615 | | 602 | |
| 616 | _ = @cmpxchgStrong( | 603 | _ = @cmpxchgStrong( |
| 617 | usize, | 604 | usize, |