MF_API MFStringData *MFStringData_Alloc() { MFStringData *pData = (MFStringData*)stringPool.Alloc(); pData->refCount = 1; pData->pMemory = NULL; pData->allocated = pData->bytes = 0; return pData; }
MFInitStatus MFHeap_InitModule() { MFCALLSTACK; MFDebug_Assert(MFThread_GetMutexSizePlatformSpecific() <= sizeof(gMutexBuffer), "Mutex buffer too small!"); MFThread_InitMutexPlatformSpecific((MFMutex)gMutexBuffer, "MFHeap alloc mutex"); gAllocMutex = (MFMutex)gMutexBuffer; // any heap tracking allocations should be made in the debug space MFHeap *pOld = MFHeap_SetActiveHeap(MFHeap_GetDebugHeap()); #if defined(_USE_TRACKING_HASH_TABLE) // set up the memory tracking hash table // note: this is slightly complicated due to the chicken and egg nature // of making the first allocation for the pool its self ;) static const int numAllocHeaders = 1024; // uint32 bytes = (sizeof(MFHeap_AllocItem) + sizeof(void**)) * numAllocHeaders; // void *pPoolMemory = MFHeap_Alloc(bytes); // gAllocHeaderPool.Init(sizeof(MFHeap_AllocItem), numAllocHeaders, 1024, pPoolMemory, bytes); gAllocHeaderPool.Init(sizeof(MFHeap_AllocItem), numAllocHeaders, 1024); MFZeroMemory(gpAllocTable, sizeof(gpAllocTable)); // artificially add an entry for the pool its self... MFHeap_AllocItem *pHeader = (MFHeap_AllocItem*)gAllocHeaderPool.Alloc(); pHeader->header.pHeap = &gExternalHeap; pHeader->header.size = bytes; pHeader->header.pFile = __FILE__; pHeader->header.line = (uint16)__LINE__; pHeader->header.alignment = 4; pHeader->pMemory = pPoolMemory; pHeader->pNext = NULL; gpAllocTable[MFUtil_HashPointer(pPoolMemory) % MFHeap_AllocTableLength] = pHeader; #endif #if defined(_USE_ALLOC_TRACKER) gAllocList.Init(sizeof(void*), 1024, 1024); gPoolInitialised = true; #endif // restore the active heap MFHeap_SetActiveHeap(pOld); // init the heap MFHeap_InitModulePlatformSpecific(); return MFAIC_Succeeded; }
MF_API void *MFHeap_AllocInternal(size_t bytes, MFHeap *pHeap) { MFCALLSTACK; MFHeap *pAllocHeap = pOverrideHeap ? pOverrideHeap : (pHeap ? pHeap : pActiveHeap); int pad = 0; while(pad < (int)sizeof(MFAllocHeader)) pad += heapAlignment; size_t allocExtra = pad + sizeof(MFAllocHeader) + MFHeap_MungwallBytes; size_t allocBytes = bytes + allocExtra; MFThread_LockMutex(gAllocMutex); char *pMemory = (char*)pAllocHeap->pCallbacks->pMalloc(allocBytes, pAllocHeap->pHeapData); MFDebug_Assert(pMemory, "Failed to allocate memory!"); if(pMemory) { int alignment = (int)(MFALIGN(pMemory + sizeof(MFAllocHeader), heapAlignment) - (uintp)pMemory); pMemory += alignment; MFAllocHeader *pHeader = &((MFAllocHeader*)pMemory)[-1]; pHeader->alignment = (uint16)alignment; pHeader->pHeap = pAllocHeap; pHeader->size = (uint32)bytes; pHeader->pFile = gpMFHeap_TrackerFile; pHeader->line = (uint16)gMFHeap_TrackerLine; #if defined(USE_PRE_MUNGWALL) MFCopyMemory(pHeader->llawgnum, gLlawgnum, MFHeap_MungwallBytes); #endif if(pAllocHeap->heapType != MFHT_Debug) { #if defined(_USE_TRACKING_HASH_TABLE) MFHeap_AllocItem *pAlloc = (MFHeap_AllocItem*)gAllocHeaderPool.Alloc(); pAlloc->header.alignment = (uint16)alignment; pAlloc->header.pHeap = pAllocHeap; pAlloc->header.size = (uint32)bytes; pAlloc->header.pFile = gpMFHeap_TrackerFile; pAlloc->header.line = (uint16)gMFHeap_TrackerLine; pAlloc->pMemory = pMemory; int hash = MFUtil_HashPointer(pMemory) % MFHeap_AllocTableLength; pAlloc->pNext = gpAllocTable[hash]; gpAllocTable[hash] = pAlloc; #endif #if defined(_USE_ALLOC_TRACKER) if(gPoolInitialised) *(void**)gAllocList.Alloc() = pMemory; #endif } #if !defined(_RETAIL) MFCopyMemory(pMemory + bytes, gMungwall, MFHeap_MungwallBytes); pAllocHeap->totalAllocated += allocBytes; pAllocHeap->totalWaste += allocExtra; ++pAllocHeap->allocCount; // MFDebug_Log(2, MFStr("Alloc: %08X(%08X), %d bytes - %s:(%d)", pMemory, pMemory - pHeader->alignment, bytes, gpMFHeap_TrackerFile, gMFHeap_TrackerLine)); #endif } MFThread_ReleaseMutex(gAllocMutex); return (void*)pMemory; }