34 class KZoneAllocator::MemBlock
37 MemBlock(
size_t s) : size(s),
ref(0), older(0), newer(0)
38 { begin =
new char[s]; }
39 ~MemBlock() {
delete [] begin; }
40 bool is_in(
void *ptr)
const {
return !(begin > (
char *)ptr
41 || (begin + size) <= (
char *)ptr); }
49 class KZoneAllocator::Private
53 : currentBlock(0), blockSize(1),
54 blockOffset(0), log2(0), num_blocks(0),
55 hashList(0), hashSize(0), hashDirty(true)
60 MemBlock *currentBlock;
62 unsigned long blockSize;
64 unsigned long blockOffset;
68 unsigned int num_blocks;
72 unsigned int hashSize;
80 while (d->blockSize < _blockSize) {
87 d->blockOffset = d->blockSize + 1;
92 unsigned int count = 0;
96 for (
unsigned int i = 0; i < d->hashSize; i++)
97 delete d->hashList[i];
98 delete [] d->hashList;
102 for (; d->currentBlock; d->currentBlock = next) {
103 next = d->currentBlock->older;
104 delete d->currentBlock;
107 #ifndef NDEBUG // as this is called quite late in the app, we don't care
110 qDebug(
"zone still contained %d blocks", count);
117 quintptr adr = ((quintptr)b->begin) & (~(d->blockSize - 1));
118 quintptr end = ((quintptr)b->begin) + d->blockSize;
120 quintptr key = adr >> d->log2;
121 key = key & (d->hashSize - 1);
122 if (!d->hashList[key])
124 d->hashList[key]->append(b);
137 b->older = d->currentBlock;
145 if (d->hashList && ((d->num_blocks / 4) > d->hashSize && d->hashSize < 64*1024))
149 if (d->hashList && !d->hashDirty)
157 for (
unsigned int i = 0; i < d->hashSize; i++)
158 delete d->hashList[i];
159 delete [] d->hashList;
163 while (d->hashSize < d->num_blocks)
165 if (d->hashSize < 1024)
167 if (d->hashSize > 64*1024)
168 d->hashSize = 64*1024;
171 d->hashDirty =
false;
172 for (MemBlock *b = d->currentBlock; b; b = b->older)
184 if (d->hashList && !d->hashDirty) {
185 quintptr adr = (( quintptr )b->begin) & (~(d->blockSize - 1));
186 quintptr end = (( quintptr )b->begin) + d->blockSize;
188 quintptr key = adr >> d->log2;
189 key = key & (d->hashSize - 1);
190 if (d->hashList[key]) {
194 for (; it != endit; ++it)
204 b->older->newer = b->newer;
206 b->newer->older = b->older;
207 if (b == d->currentBlock) {
209 d->blockOffset = d->blockSize;
219 const size_t alignment =
sizeof(
void *) - 1;
220 _size = (_size + alignment) & ~alignment;
222 if ((
unsigned long) _size + d->blockOffset > d->blockSize)
224 if (_size > d->blockSize) {
225 qDebug(
"KZoneAllocator: allocating more than %lu bytes", d->blockSize);
228 addBlock(
new MemBlock(d->blockSize));
232 void *result = (
void *)(d->currentBlock->begin+d->blockOffset);
233 d->currentBlock->ref++;
234 d->blockOffset += _size;
244 quintptr key = (((quintptr)ptr) >> d->log2) & (d->hashSize - 1);
254 for (; it != endit; ++it) {
256 if (cur->is_in(ptr)) {
258 if (cur != d->currentBlock)
277 if (d->hashList && !d->hashDirty)
280 unsigned int removed = 0;
281 for (b = d->currentBlock; b; b = b->older, removed++)
284 if (d->hashSize >= 4 * (d->num_blocks - removed))
287 while (d->currentBlock && !d->currentBlock->is_in(ptr)) {
288 d->currentBlock = d->currentBlock->older;
291 d->blockOffset = ((
char*)ptr) - d->currentBlock->begin;