| 212 | } |
| 213 | |
| 214 | std::pair<HashStringAllocator::Position, HashStringAllocator::Position> |
| 215 | HashStringAllocator::finishWrite( |
| 216 | ByteOutputStream& stream, |
| 217 | int32_t numReserveBytes) { |
| 218 | BOLT_CHECK( |
| 219 | currentHeader_, "Must call newWrite or extendWrite before finishWrite"); |
| 220 | auto writePosition = stream.writePosition(); |
| 221 | const auto offset = writePosition - currentHeader_->begin(); |
| 222 | |
| 223 | BOLT_CHECK_GE( |
| 224 | offset, 0, "finishWrite called with writePosition out of range"); |
| 225 | BOLT_CHECK_LE( |
| 226 | offset, |
| 227 | currentHeader_->usableSize(), |
| 228 | "finishWrite called with writePosition out of range"); |
| 229 | |
| 230 | Position currentPosition = Position::atOffset(currentHeader_, offset); |
| 231 | if (currentHeader_->isContinued()) { |
| 232 | free(currentHeader_->nextContinued()); |
| 233 | currentHeader_->clearContinued(); |
| 234 | } |
| 235 | // Free remainder of block if there is a lot left over. |
| 236 | freeRestOfBlock( |
| 237 | currentHeader_, |
| 238 | writePosition - currentHeader_->begin() + numReserveBytes); |
| 239 | currentHeader_ = nullptr; |
| 240 | |
| 241 | // The starting position may have shifted if it was at the end of the block |
| 242 | // and the block was extended. Calculate the new position. |
| 243 | if (startPosition_.header->isContinued()) { |
| 244 | auto header = startPosition_.header; |
| 245 | const auto offset = startPosition_.offset(); |
| 246 | const auto extra = offset - header->usableSize(); |
| 247 | if (extra > 0) { |
| 248 | auto newHeader = header->nextContinued(); |
| 249 | auto newPosition = newHeader->begin() + extra; |
| 250 | startPosition_ = {newHeader, newPosition}; |
| 251 | } |
| 252 | } |
| 253 | return {startPosition_, currentPosition}; |
| 254 | } |
| 255 | |
| 256 | void HashStringAllocator::newSlab() { |
| 257 | constexpr int32_t kSimdPadding = simd::kPadding - sizeof(Header); |