| 62 | } |
| 63 | |
| 64 | char* AllocationPool::allocateFixed(uint64_t bytes, int32_t alignment) { |
| 65 | BOLT_CHECK_GT(bytes, 0, "Cannot allocate zero bytes"); |
| 66 | if (freeAddressableBytes() >= bytes && alignment == 1) { |
| 67 | auto* result = startOfRun_ + currentOffset_; |
| 68 | currentOffset_ += bytes; |
| 69 | if (currentOffset_ > endOfReservedRun()) { |
| 70 | growLastAllocation(); |
| 71 | } |
| 72 | return result; |
| 73 | } |
| 74 | BOLT_CHECK_EQ( |
| 75 | __builtin_popcount(alignment), 1, "Alignment can only be power of 2"); |
| 76 | |
| 77 | auto numPages = AllocationTraits::numPages(bytes + alignment - 1); |
| 78 | |
| 79 | if (freeAddressableBytes() == 0) { |
| 80 | newRunImpl(numPages); |
| 81 | } else { |
| 82 | auto alignedBytes = bytes + alignmentPadding(firstFreeInRun(), alignment); |
| 83 | if (freeAddressableBytes() < alignedBytes) { |
| 84 | newRunImpl(numPages); |
| 85 | } |
| 86 | } |
| 87 | currentOffset_ += alignmentPadding(firstFreeInRun(), alignment); |
| 88 | BOLT_CHECK_LE(bytes + currentOffset_, bytesInRun_); |
| 89 | auto* result = startOfRun_ + currentOffset_; |
| 90 | BOLT_CHECK_EQ(reinterpret_cast<uintptr_t>(result) % alignment, 0); |
| 91 | currentOffset_ += bytes; |
| 92 | if (currentOffset_ > endOfReservedRun()) { |
| 93 | growLastAllocation(); |
| 94 | } |
| 95 | return result; |
| 96 | } |
| 97 | |
| 98 | void AllocationPool::growLastAllocation() { |
| 99 | BOLT_CHECK_GT(bytesInRun_, AllocationTraits::kHugePageSize); |