| ... | ... | @@ -402,41 +402,6 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 402 | 402 | } |
| 403 | 403 | } |
| 404 | 404 | |
| 405 | | fn freeSlot( |
| 406 | | self: *Self, |
| 407 | | bucket: *BucketHeader, |
| 408 | | bucket_index: usize, |
| 409 | | size_class: usize, |
| 410 | | slot_index: SlotIndex, |
| 411 | | used_byte: *u8, |
| 412 | | used_bit_index: u3, |
| 413 | | trace_addr: usize, |
| 414 | | ) void { |
| 415 | | // Capture stack trace to be the "first free", in case a double free happens. |
| 416 | | bucket.captureStackTrace(trace_addr, size_class, slot_index, .free); |
| 417 | | |
| 418 | | used_byte.* &= ~(@as(u8, 1) << used_bit_index); |
| 419 | | bucket.used_count -= 1; |
| 420 | | if (bucket.used_count == 0) { |
| 421 | | if (bucket.next == bucket) { |
| 422 | | // it's the only bucket and therefore the current one |
| 423 | | self.buckets[bucket_index] = null; |
| 424 | | } else { |
| 425 | | bucket.next.prev = bucket.prev; |
| 426 | | bucket.prev.next = bucket.next; |
| 427 | | self.buckets[bucket_index] = bucket.prev; |
| 428 | | } |
| 429 | | if (!config.never_unmap) { |
| 430 | | self.backing_allocator.free(bucket.page[0..page_size]); |
| 431 | | } |
| 432 | | const bucket_size = bucketSize(size_class); |
| 433 | | const bucket_slice = @ptrCast([*]align(@alignOf(BucketHeader)) u8, bucket)[0..bucket_size]; |
| 434 | | self.backing_allocator.free(bucket_slice); |
| 435 | | } else { |
| 436 | | @memset(bucket.page + slot_index * size_class, undefined, size_class); |
| 437 | | } |
| 438 | | } |
| 439 | | |
| 440 | 405 | /// This function assumes the object is in the large object storage regardless |
| 441 | 406 | /// of the parameters. |
| 442 | 407 | fn resizeLarge( |
| ... | ... | @@ -560,7 +525,29 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 560 | 525 | } |
| 561 | 526 | } |
| 562 | 527 | if (new_size == 0) { |
| 563 | | self.freeSlot(bucket, bucket_index, size_class, slot_index, used_byte, used_bit_index, ret_addr); |
| 528 | // Capture stack trace to be the "first free", in case a double free happens. |
| 529 | bucket.captureStackTrace(ret_addr, size_class, slot_index, .free); |
| 530 | |
| 531 | used_byte.* &= ~(@as(u8, 1) << used_bit_index); |
| 532 | bucket.used_count -= 1; |
| 533 | if (bucket.used_count == 0) { |
| 534 | if (bucket.next == bucket) { |
| 535 | // it's the only bucket and therefore the current one |
| 536 | self.buckets[bucket_index] = null; |
| 537 | } else { |
| 538 | bucket.next.prev = bucket.prev; |
| 539 | bucket.prev.next = bucket.next; |
| 540 | self.buckets[bucket_index] = bucket.prev; |
| 541 | } |
| 542 | if (!config.never_unmap) { |
| 543 | self.backing_allocator.free(bucket.page[0..page_size]); |
| 544 | } |
| 545 | const bucket_size = bucketSize(size_class); |
| 546 | const bucket_slice = @ptrCast([*]align(@alignOf(BucketHeader)) u8, bucket)[0..bucket_size]; |
| 547 | self.backing_allocator.free(bucket_slice); |
| 548 | } else { |
| 549 | @memset(old_mem.ptr, undefined, old_mem.len); |
| 550 | } |
| 564 | 551 | return @as(usize, 0); |
| 565 | 552 | } |
| 566 | 553 | const new_aligned_size = math.max(new_size, old_align); |