| 93 | } // namespace |
| 94 | |
| 95 | void* PoolAllocator::AllocateRaw(size_t alignment, size_t num_bytes) { |
| 96 | if (num_bytes == 0) return nullptr; |
| 97 | |
| 98 | // If alignment is larger than kPoolAlignment, increase num_bytes so that we |
| 99 | // are guaranteed to be able to return an aligned ptr by advancing user_ptr |
| 100 | // without overrunning the end of the chunk. |
| 101 | if (alignment > kPoolAlignment) { |
| 102 | num_bytes += alignment; |
| 103 | } |
| 104 | num_bytes += sizeof(ChunkPrefix); |
| 105 | num_bytes = size_rounder_->RoundUp(num_bytes); |
| 106 | PtrRecord* pr = nullptr; |
| 107 | if (has_size_limit_) { |
| 108 | { |
| 109 | mutex_lock lock(mutex_); |
| 110 | auto iter = pool_.find(num_bytes); |
| 111 | if (iter == pool_.end()) { |
| 112 | allocated_count_++; |
| 113 | // Deliberately fall out of lock scope before |
| 114 | // calling the allocator. No further modification |
| 115 | // to the pool will be performed. |
| 116 | } else { |
| 117 | get_from_pool_count_++; |
| 118 | pr = iter->second; |
| 119 | RemoveFromList(pr); |
| 120 | pool_.erase(iter); |
| 121 | // Fall out of lock scope and do the result without the lock held. |
| 122 | } |
| 123 | } |
| 124 | } |
| 125 | if (pr != nullptr) { |
| 126 | void* r = pr->ptr; |
| 127 | delete pr; |
| 128 | return PrepareChunk(r, alignment, num_bytes); |
| 129 | } else { |
| 130 | void* ptr = allocator_->Alloc(kPoolAlignment, num_bytes); |
| 131 | return PrepareChunk(ptr, alignment, num_bytes); |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | void PoolAllocator::DeallocateRaw(void* ptr) { |
| 136 | if (ptr == nullptr) return; |