| 567 | } |
| 568 | |
| 569 | inline bool HashStringAllocator::storeStringFast( |
| 570 | const char* bytes, |
| 571 | int32_t numBytes, |
| 572 | char* destination) { |
| 573 | auto roundedBytes = std::max(numBytes, kMinAlloc); |
| 574 | Header* header = nullptr; |
| 575 | if (free_[kNumFreeLists - 1].empty()) { |
| 576 | if (roundedBytes >= kMaxAlloc) { |
| 577 | return false; |
| 578 | } |
| 579 | auto index = freeListIndex(roundedBytes); |
| 580 | auto available = bits::findFirstBit(freeNonEmpty_, index, kNumFreeLists); |
| 581 | if (available < 0) { |
| 582 | return false; |
| 583 | } |
| 584 | header = allocateFromFreeList(roundedBytes, true, true, available); |
| 585 | BOLT_CHECK_NOT_NULL(header); |
| 586 | } else { |
| 587 | auto& freeList = free_[kNumFreeLists - 1]; |
| 588 | header = headerOf(freeList.next()); |
| 589 | const auto spaceTaken = roundedBytes + sizeof(Header); |
| 590 | if (spaceTaken > header->size()) { |
| 591 | return false; |
| 592 | } |
| 593 | if (header->size() - spaceTaken > kMaxAlloc) { |
| 594 | // The entry after allocation stays in the largest free list. |
| 595 | // The size at the end of the block is changed in place. |
| 596 | reinterpret_cast<int32_t*>(header->end())[-1] -= spaceTaken; |
| 597 | auto freeHeader = new (header->begin() + roundedBytes) |
| 598 | Header(header->size() - spaceTaken); |
| 599 | freeHeader->setFree(); |
| 600 | header->clearFree(); |
| 601 | memcpy(freeHeader->begin(), header->begin(), sizeof(CompactDoubleList)); |
| 602 | freeList.nextMoved( |
| 603 | reinterpret_cast<CompactDoubleList*>(freeHeader->begin())); |
| 604 | header->setSize(roundedBytes); |
| 605 | freeBytes_ -= spaceTaken; |
| 606 | cumulativeBytes_ += roundedBytes; |
| 607 | } else { |
| 608 | header = |
| 609 | allocateFromFreeList(roundedBytes, true, true, kNumFreeLists - 1); |
| 610 | if (!header) { |
| 611 | return false; |
| 612 | } |
| 613 | } |
| 614 | } |
| 615 | simd::memcpy(header->begin(), bytes, numBytes); |
| 616 | *reinterpret_cast<StringView*>(destination) = |
| 617 | StringView(reinterpret_cast<char*>(header->begin()), numBytes); |
| 618 | return true; |
| 619 | } |
| 620 | |
| 621 | void HashStringAllocator::copyMultipartNoInline( |
| 622 | const StringView& srcStr, |
nothing calls this directly
no test coverage detected