| ... | ... | @@ -567,38 +567,40 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 567 | 567 | const held = self.mutex.acquire(); |
| 568 | 568 | defer held.release(); |
| 569 | 569 | |
| 570 | | const prev_req_bytes = self.total_requested_bytes; |
| 570 | const new_aligned_size = math.max(len, ptr_align); |
| 571 | const mem_slice = blk: { |
| 572 | if (new_aligned_size > largest_bucket_object_size) { |
| 573 | try self.large_allocations.ensureCapacity( |
| 574 | self.backing_allocator, |
| 575 | self.large_allocations.entries.items.len + 1, |
| 576 | ); |
| 577 | |
| 578 | const slice = try self.backing_allocator.allocFn(self.backing_allocator, len, ptr_align, len_align, ret_addr); |
| 579 | |
| 580 | const gop = self.large_allocations.getOrPutAssumeCapacity(@ptrToInt(slice.ptr)); |
| 581 | assert(!gop.found_existing); // This would mean the kernel double-mapped pages. |
| 582 | gop.entry.value.bytes = slice; |
| 583 | collectStackTrace(ret_addr, &gop.entry.value.stack_addresses); |
| 584 | |
| 585 | break :blk slice; |
| 586 | } else { |
| 587 | const new_size_class = math.ceilPowerOfTwoAssert(usize, new_aligned_size); |
| 588 | const ptr = try self.allocSlot(new_size_class, ret_addr); |
| 589 | break :blk ptr[0..len]; |
| 590 | } |
| 591 | }; |
| 592 | |
| 571 | 593 | if (config.enable_memory_limit) { |
| 572 | | const new_req_bytes = prev_req_bytes + len; |
| 594 | // The backing allocator may return a memory block bigger than |
| 595 | // `len`, use the effective size for bookkeeping purposes |
| 596 | const new_req_bytes = self.total_requested_bytes + mem_slice.len; |
| 573 | 597 | if (new_req_bytes > self.requested_memory_limit) { |
| 574 | 598 | return error.OutOfMemory; |
| 575 | 599 | } |
| 576 | 600 | self.total_requested_bytes = new_req_bytes; |
| 577 | 601 | } |
| 578 | | errdefer if (config.enable_memory_limit) { |
| 579 | | self.total_requested_bytes = prev_req_bytes; |
| 580 | | }; |
| 581 | | |
| 582 | | const new_aligned_size = math.max(len, ptr_align); |
| 583 | | if (new_aligned_size > largest_bucket_object_size) { |
| 584 | | try self.large_allocations.ensureCapacity( |
| 585 | | self.backing_allocator, |
| 586 | | self.large_allocations.entries.items.len + 1, |
| 587 | | ); |
| 588 | 602 | |
| 589 | | const slice = try self.backing_allocator.allocFn(self.backing_allocator, len, ptr_align, len_align, ret_addr); |
| 590 | | |
| 591 | | const gop = self.large_allocations.getOrPutAssumeCapacity(@ptrToInt(slice.ptr)); |
| 592 | | assert(!gop.found_existing); // This would mean the kernel double-mapped pages. |
| 593 | | gop.entry.value.bytes = slice; |
| 594 | | collectStackTrace(ret_addr, &gop.entry.value.stack_addresses); |
| 595 | | |
| 596 | | return slice; |
| 597 | | } else { |
| 598 | | const new_size_class = math.ceilPowerOfTwoAssert(usize, new_aligned_size); |
| 599 | | const ptr = try self.allocSlot(new_size_class, ret_addr); |
| 600 | | return ptr[0..len]; |
| 601 | | } |
| 603 | return mem_slice; |
| 602 | 604 | } |
| 603 | 605 | |
| 604 | 606 | fn createBucket(self: *Self, size_class: usize, bucket_index: usize) Error!*BucketHeader { |