| 68 | } |
| 69 | |
| 70 | void* BNativeHeap::alloc(U32 len, U32* blockSize) { |
| 71 | U32 index = powerOf2(len + 4); |
| 72 | if (index < 4) { |
| 73 | index = 4; |
| 74 | } |
| 75 | U32 size = 1 << index; |
| 76 | for (auto it = delayedFreeLargeBlocks.begin(); it != delayedFreeLargeBlocks.end();) { |
| 77 | if (it->value < KSystem::getMilliesSinceStart() - delayedFree) { |
| 78 | if (delayedFreeCallback) { |
| 79 | delayedFreeCallback(it->key, *((U32*)it->key)); |
| 80 | } |
| 81 | Platform::releaseNativeMemory(it->key, *((U32*)it->key)); |
| 82 | delayedFreeLargeBlocks.remove(it->key); |
| 83 | it = delayedFreeLargeBlocks.begin(); |
| 84 | } |
| 85 | if (it != delayedFreeLargeBlocks.end()) { |
| 86 | it++; |
| 87 | } |
| 88 | } |
| 89 | if (size >= BNATIVEHEAD_64K_BLOCK_SIZE) { |
| 90 | U32 count = (len + 4 + BNATIVEHEAD_64K_BLOCK_SIZE - 1) / BNATIVEHEAD_64K_BLOCK_SIZE; |
| 91 | |
| 92 | U8* result = Platform::alloc64kBlock(count, isCodeMemory); |
| 93 | if (isCodeMemory) { |
| 94 | Platform::writeCodeToMemory(result, 4, [result, count]() { |
| 95 | *((U32*)result) = count * BNATIVEHEAD_64K_BLOCK_SIZE; |
| 96 | }); |
| 97 | } else { |
| 98 | *((U32*)result) = count * BNATIVEHEAD_64K_BLOCK_SIZE; |
| 99 | } |
| 100 | largeBlocks.set(result, count * BNATIVEHEAD_64K_BLOCK_SIZE); |
| 101 | if (blockSize) { |
| 102 | *blockSize = BNATIVEHEAD_64K_BLOCK_SIZE * count - 4; |
| 103 | } |
| 104 | return result + 4; |
| 105 | } |
| 106 | if (buckets.contains(index) && buckets[index].size()) { |
| 107 | void* result = buckets[index].back(); |
| 108 | U32* pInfo = (U32*)result; |
| 109 | pInfo--; |
| 110 | bool isDelayedFree = *pInfo < KSystem::getMilliesSinceStart() - delayedFree; |
| 111 | |
| 112 | if (!delayedFree || isDelayedFree) { |
| 113 | if (isDelayedFree && delayedFreeCallback) { |
| 114 | delayedFreeCallback(pInfo, len + 4); |
| 115 | } |
| 116 | |
| 117 | buckets[index].pop_back(); |
| 118 | if (isCodeMemory) { |
| 119 | Platform::writeCodeToMemory(pInfo, len + 4, [index, pInfo, result, len]() { |
| 120 | memset(result, 0, len); |
| 121 | *pInfo = index; |
| 122 | }); |
| 123 | } else { |
| 124 | memset(result, 0, len); |
| 125 | *pInfo = index; |
| 126 | } |
| 127 | U32* address = ((U32*)result) - 1; |