138ExecutableAllocator::Allocation *ExecutableAllocator::allocate(size_t size)
140 QMutexLocker locker(&mutex);
141 Allocation *allocation =
nullptr;
144 size = WTF::roundUpToMultipleOf(16, size + exceptionHandlerSize());
146 QMultiMap<size_t, Allocation*>::Iterator it = freeAllocations.lowerBound(size);
147 if (it != freeAllocations.end()) {
149 freeAllocations.erase(it);
153 ChunkOfPages *chunk =
new ChunkOfPages;
154 size_t allocSize = WTF::roundUpToMultipleOf(WTF::pageSize(), size);
155 chunk->pages =
new WTF::PageAllocation(WTF::PageAllocation::allocate(allocSize, OSAllocator::JSJITCodePages));
156 chunks.insert(
reinterpret_cast<quintptr>(chunk->pages->base()) - 1, chunk);
157 allocation =
new Allocation;
158 allocation->addr =
reinterpret_cast<quintptr>(chunk->pages->base());
159 allocation->size = allocSize;
160 allocation->free =
true;
161 chunk->firstAllocation = allocation;
164 Q_ASSERT(allocation);
165 Q_ASSERT(allocation->free);
167 allocation->free =
false;
169 if (allocation->size > size) {
170 Allocation *remainder = allocation->split(size);
171 remainder->free =
true;
172 if (!remainder->mergeNext(
this))
173 freeAllocations.insert(remainder->size, remainder);
179void ExecutableAllocator::free(Allocation *allocation)
181 QMutexLocker locker(&mutex);
183 Q_ASSERT(allocation);
185 allocation->free =
true;
187 QMap<quintptr, ChunkOfPages*>::Iterator it = chunks.lowerBound(allocation->addr);
188 if (it != chunks.begin())
190 Q_ASSERT(it != chunks.end());
191 ChunkOfPages *chunk = *it;
192 Q_ASSERT(chunk->contains(allocation));
194 bool merged = allocation->mergeNext(
this);
195 merged |= allocation->mergePrevious(
this);
197 freeAllocations.insert(allocation->size, allocation);
199 allocation =
nullptr;
201 if (!chunk->firstAllocation->next) {
202 freeAllocations.remove(chunk->firstAllocation->size, chunk->firstAllocation);