diff options
Diffstat (limited to 'core/src/fxcrt/fx_basic_memmgr_mini.cpp')
-rw-r--r-- | core/src/fxcrt/fx_basic_memmgr_mini.cpp | 1644 |
1 files changed, 822 insertions, 822 deletions
diff --git a/core/src/fxcrt/fx_basic_memmgr_mini.cpp b/core/src/fxcrt/fx_basic_memmgr_mini.cpp index f8385e20d2..8d48bab935 100644 --- a/core/src/fxcrt/fx_basic_memmgr_mini.cpp +++ b/core/src/fxcrt/fx_basic_memmgr_mini.cpp @@ -1,822 +1,822 @@ -// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../include/fxcrt/fx_ext.h"
-#include "mem_int.h"
-#ifdef _FPDFAPI_MINI_
-static FX_MEMCONFIG g_MemConfig = {
- 1,
- 5,
- 8,
- 4,
- 12,
- 8,
- 2,
- 4,
- 32,
- 64,
-};
-#else
-static FX_MEMCONFIG g_MemConfig = {
- 1,
- 8,
- 24,
- 8,
- 32,
- 16,
- 4,
- 8,
- 128,
- 64,
-};
-#endif
-void FXMEM_SetConfig(const FX_MEMCONFIG* memConfig)
-{
- g_MemConfig = *memConfig;
-}
-#ifdef __cplusplus
-extern "C" {
-#endif
-static void* FixedAlloc(FXMEM_SystemMgr* pMgr, size_t size, int flags)
-{
- return ((CFXMEM_FixedMgr*)pMgr->user)->Alloc(size);
-}
-static void* FixedAllocDebug(FXMEM_SystemMgr* pMgr, size_t size, int flags, FX_LPCSTR file, int line)
-{
- return ((CFXMEM_FixedMgr*)pMgr->user)->Alloc(size);
-}
-static void* FixedRealloc(FXMEM_SystemMgr* pMgr, void* pointer, size_t size, int flags)
-{
- return ((CFXMEM_FixedMgr*)pMgr->user)->Realloc(pointer, size);
-}
-static void* FixedReallocDebug(FXMEM_SystemMgr* pMgr, void* pointer, size_t size, int flags, FX_LPCSTR file, int line)
-{
- return ((CFXMEM_FixedMgr*)pMgr->user)->Realloc(pointer, size);
-}
-static void FixedFree(FXMEM_SystemMgr* pMgr, void* pointer, int flags)
-{
- ((CFXMEM_FixedMgr*)pMgr->user)->Free(pointer);
-}
-static void FixedPurge(FXMEM_SystemMgr* pMgr)
-{
- ((CFXMEM_FixedMgr*)pMgr->user)->Purge();
-}
-static void FixedCollectAll(FXMEM_SystemMgr* pMgr)
-{
- ((CFXMEM_FixedMgr*)pMgr->user)->FreeAll();
-}
-#define FIXEDMEM_MINIMUMSIZE (1024 * 1024 * 8)
-FXMEM_FoxitMgr* FXMEM_CreateMemoryMgr(size_t size, FX_BOOL extensible)
-{
- if (size < FIXEDMEM_MINIMUMSIZE) {
- size = FIXEDMEM_MINIMUMSIZE;
- }
- FX_LPVOID pMemory = malloc(size);
- if (!pMemory) {
- return NULL;
- }
- CFixedMgr_Proxy* pProxy = (CFixedMgr_Proxy*)pMemory;
- size_t offsetSize = (sizeof(CFixedMgr_Proxy) + 15) / 16 * 16;
- FXMEM_FoxitMgr* pFoxitMgr = pProxy->Initialize((FX_LPBYTE)pProxy + offsetSize, size - offsetSize, extensible);
- if (!pFoxitMgr) {
- free(pMemory);
- return NULL;
- }
- g_pDefFoxitMgr = (CFX_MemoryMgr*)pFoxitMgr;
- g_pDefFoxitMgr->m_pExternalMemory = pMemory;
- return pFoxitMgr;
-}
-FXMEM_FoxitMgr* FXMEM_CreateFixedMgr(void* pMemory, size_t size, FXMEM_SystemMgr2* pSystemMgr)
-{
- if (pMemory == NULL || size < FX_FIXEDMEM_PAGESIZE) {
- return NULL;
- }
- if (!pSystemMgr && size >= FIXEDMEM_PROXYSIZE_1) {
- CFixedMgr_Proxy* pProxy = (CFixedMgr_Proxy*)pMemory;
- size_t offsetSize = (sizeof(CFixedMgr_Proxy) + 15) / 16 * 16;
- return pProxy->Initialize((FX_LPBYTE)pProxy + offsetSize, size - offsetSize, FALSE);
- }
- CFXMEM_FixedMgr* pHeader = (CFXMEM_FixedMgr*)pMemory;
- pHeader->Initialize(size);
- pHeader->m_pExtender = pSystemMgr;
- CFX_MemoryMgr* p = (CFX_MemoryMgr*)pHeader->Alloc(sizeof(CFX_MemoryMgr));
- if (p == NULL) {
- return NULL;
- }
- p->Init(&pHeader->m_SystemMgr);
- return (FXMEM_FoxitMgr*)p;
-}
-size_t FXMEM_GetBlockSizeInFixedMgr(FXMEM_FoxitMgr* pFoxitMgr, void* ptr)
-{
- return pFoxitMgr ? ((CFXMEM_FixedMgr*)((CFX_MemoryMgr*)pFoxitMgr)->m_pSystemMgr->user)->GetSize(ptr) : 0;
-}
-#ifdef __cplusplus
-}
-#endif
-const FX_MEMCONFIG g_ProxyMgr_MemConfigs[6] = {
- {1, 2, 4, 0, 2, 2, 2, 0, 0, 0},
- {1, 4, 8, 0, 2, 2, 2, 0, 0, 0},
- {1, 4, 16, 4, 8, 8, 2, 1, 16, 16},
- {1, 8, 24, 4, 12, 12, 4, 2, 32, 16},
- {1, 8, 24, 8, 16, 16, 4, 2, 64, 32},
- {1, 8, 24, 8, 24, 32, 4, 2, 128, 64},
-};
-const FX_MEMCONFIG* FixedMgr_GetConfig(size_t nSize)
-{
- int index = 5;
- if (nSize <= FIXEDMEM_PROXYSIZE_0) {
- index = 0;
- } else if (nSize <= FIXEDMEM_PROXYSIZE_1) {
- index = 1;
- } else if (nSize <= FIXEDMEM_PROXYSIZE_2) {
- index = 2;
- } else if (nSize <= FIXEDMEM_PROXYSIZE_3) {
- index = 3;
- } else if (nSize <= FIXEDMEM_PROXYSIZE_4) {
- index = 4;
- }
- return &g_ProxyMgr_MemConfigs[index];
-}
-FXMEM_FoxitMgr* CFixedMgr_Proxy::Initialize(FX_LPVOID pBuffer, size_t nSize, FX_BOOL bExtensible)
-{
- FXSYS_assert(pBuffer != NULL && nSize >= FIXEDMEM_PROXYSIZE_1 - sizeof(CFixedMgr_Proxy));
- FXMEM_SetConfig(FixedMgr_GetConfig(nSize));
- m_SystemMgr.More = &CFixedMgr_Proxy::Common_More;
- m_SystemMgr.Free = &CFixedMgr_Proxy::Common_Free;
- m_pFixedPage = (CFXMEM_Page*)((FX_LPBYTE)pBuffer + FIXEDMEM_PROXYSIZE_0);
- m_pFixedPage->Initialize(nSize - FIXEDMEM_PROXYSIZE_0);
- m_pBuffer = pBuffer;
- m_nSize = nSize;
- m_bExtensible = bExtensible;
- return FXMEM_CreateFixedMgr(pBuffer, FIXEDMEM_PROXYSIZE_0, &m_SystemMgr);
-}
-FX_BOOL CFixedMgr_Proxy::Common_More(FXMEM_SystemMgr2* pMgr, size_t alloc_size, void** new_memory, size_t* new_size)
-{
- CFixedMgr_Proxy* pProxyMgr = (CFixedMgr_Proxy*)pMgr;
- FXSYS_assert(pProxyMgr != NULL && pProxyMgr->m_pFixedPage != NULL);
- *new_size = alloc_size;
- *new_memory = pProxyMgr->m_pFixedPage->Alloc(alloc_size);
- if (*new_memory == NULL && pProxyMgr->m_bExtensible) {
- *new_memory = malloc(alloc_size);
- }
- return *new_memory != NULL;
-}
-void CFixedMgr_Proxy::Common_Free(FXMEM_SystemMgr2* pMgr, void* memory)
-{
- CFixedMgr_Proxy* pProxyMgr = (CFixedMgr_Proxy*)pMgr;
- FXSYS_assert(pProxyMgr != NULL && pProxyMgr->m_pFixedPage != NULL);
- if (memory > pProxyMgr->m_pBuffer && memory < (FX_LPBYTE)pProxyMgr->m_pBuffer + pProxyMgr->m_nSize) {
- pProxyMgr->m_pFixedPage->Free(memory);
- } else if (pProxyMgr->m_bExtensible) {
- free(memory);
- }
-}
-void CFXMEM_Page::Initialize(size_t size)
-{
- CFXMEM_Block *pFirstBlock = (CFXMEM_Block*)(this + 1);
- m_nAvailSize = size - sizeof(CFXMEM_Page) - sizeof(CFXMEM_Block);
- pFirstBlock->m_nBlockSize = m_nAvailSize;
- pFirstBlock->m_pNextBlock = NULL;
- m_AvailHead.m_nBlockSize = m_nAvailSize;
- m_AvailHead.m_pNextBlock = pFirstBlock;
- m_pLimitPos = (CFXMEM_Block*)((FX_LPBYTE)this + size);
-}
-FX_LPVOID CFXMEM_Page::Alloc(CFXMEM_Block* pPrevBlock, CFXMEM_Block* pNextBlock, size_t size, size_t oldsize)
-{
- size_t gap = pNextBlock->m_nBlockSize - size;
- if (gap <= 64 + sizeof(CFXMEM_Block)) {
- pPrevBlock->m_pNextBlock = pNextBlock->m_pNextBlock;
- m_nAvailSize -= pNextBlock->m_nBlockSize;
- } else {
- m_nAvailSize -= size + sizeof(CFXMEM_Block);
- pNextBlock->m_nBlockSize = size;
- CFXMEM_Block *pNewBlock = (CFXMEM_Block*)((FX_LPBYTE)(pNextBlock + 1) + size);
- pNewBlock->m_nBlockSize = gap - sizeof(CFXMEM_Block);
- pNewBlock->m_pNextBlock = pNextBlock->m_pNextBlock;
- pPrevBlock->m_pNextBlock = pNewBlock;
- }
- return (FX_LPVOID)(pNextBlock + 1);
-}
-FX_LPVOID CFXMEM_Page::Alloc(size_t size)
-{
- size_t oldsize = size;
-#if _FX_WORDSIZE_ == _FX_W64_
- size = (size + 31) / 32 * 32;
-#else
- size = (size + 7) / 8 * 8;
-#endif
- if (m_nAvailSize < size) {
- return NULL;
- }
- CFXMEM_Block *pNextBlock;
- CFXMEM_Block *pPrevBlock = &m_AvailHead;
- while (TRUE) {
- pNextBlock = pPrevBlock->m_pNextBlock;
- if (!pNextBlock) {
- return NULL;
- }
- if (pNextBlock->m_nBlockSize >= size) {
- break;
- }
- pPrevBlock = pNextBlock;
- }
- return Alloc(pPrevBlock, pNextBlock, size, oldsize);
-}
-FX_LPVOID CFXMEM_Page::Realloc(FX_LPVOID p, size_t oldSize, size_t newSize)
-{
- FXSYS_assert(p > (FX_LPVOID)this && p < (FX_LPVOID)m_pLimitPos);
- size_t oldnewSize = newSize;
-#if _FX_WORDSIZE_ == _FX_W64_
- newSize = (newSize + 31) / 32 * 32;
-#else
- newSize = (newSize + 7) / 8 * 8;
-#endif
- CFXMEM_Block *pPrevBlock = &m_AvailHead;
- CFXMEM_Block *pNextBlock, *pPrevPrev;
- CFXMEM_Block *pBlock = (CFXMEM_Block*)p - 1;
- pPrevPrev = NULL;
- while (TRUE) {
- pNextBlock = pPrevBlock->m_pNextBlock;
- if (pNextBlock == NULL || pNextBlock > pBlock) {
- break;
- }
- if (pPrevBlock != &m_AvailHead && (FX_LPBYTE)pNextBlock == (FX_LPBYTE)(pPrevBlock + 1) + pPrevBlock->m_nBlockSize) {
- m_nAvailSize += sizeof(CFXMEM_Block);
- pPrevBlock->m_nBlockSize += pNextBlock->m_nBlockSize + sizeof(CFXMEM_Block);
- pPrevBlock->m_pNextBlock = pNextBlock->m_pNextBlock;
- } else {
- pPrevPrev = pPrevBlock;
- pPrevBlock = pNextBlock;
- }
- }
- if (pNextBlock) {
- CFXMEM_Block* pCurBlock = pNextBlock->m_pNextBlock;
- while ((FX_LPBYTE)pCurBlock == (FX_LPBYTE)(pNextBlock + 1) + pNextBlock->m_nBlockSize) {
- m_nAvailSize += sizeof(CFXMEM_Block);
- pNextBlock->m_nBlockSize += pCurBlock->m_nBlockSize + sizeof(CFXMEM_Block);
- pCurBlock = pCurBlock->m_pNextBlock;
- pNextBlock->m_pNextBlock = pCurBlock;
- }
- }
- size_t size = 0;
- FX_DWORD dwFlags = 0;
- if (pPrevBlock != &m_AvailHead && (FX_LPBYTE)pBlock == (FX_LPBYTE)(pPrevBlock + 1) + pPrevBlock->m_nBlockSize) {
- size += pPrevBlock->m_nBlockSize + oldSize + sizeof(CFXMEM_Block);
- dwFlags |= 0x10;
- }
- if (pNextBlock && (FX_LPBYTE)pNextBlock == (FX_LPBYTE)p + oldSize) {
- size += pNextBlock->m_nBlockSize + sizeof(CFXMEM_Block);
- dwFlags |= 0x01;
- }
- if (size >= newSize) {
- m_nAvailSize += pBlock->m_nBlockSize;
- CFXMEM_Block* pCurBlock = pBlock;
- if (dwFlags & 0x10) {
- pCurBlock = pPrevBlock;
- m_nAvailSize += sizeof(CFXMEM_Block);
- pCurBlock->m_nBlockSize += pBlock->m_nBlockSize + sizeof(CFXMEM_Block);
- pPrevBlock = pPrevPrev;
- }
- if (dwFlags & 0x01) {
- m_nAvailSize += sizeof(CFXMEM_Block);
- pCurBlock->m_nBlockSize += pNextBlock->m_nBlockSize + sizeof(CFXMEM_Block);
- pCurBlock->m_pNextBlock = pNextBlock->m_pNextBlock;
- }
- if (pCurBlock != pBlock) {
- FXSYS_memmove32((FX_LPVOID)(pCurBlock + 1), p, oldSize);
- }
- return Alloc(pPrevBlock, pCurBlock, newSize, oldnewSize);
- }
- return NULL;
-}
-void CFXMEM_Page::Free(FX_LPVOID p)
-{
- FXSYS_assert(p > (FX_LPVOID)this && p < (FX_LPVOID)m_pLimitPos);
- CFXMEM_Block *pPrevBlock = &m_AvailHead;
- CFXMEM_Block *pNextBlock;
- CFXMEM_Block *pBlock = (CFXMEM_Block*)p - 1;
- m_nAvailSize += pBlock->m_nBlockSize;
- while (TRUE) {
- pNextBlock = pPrevBlock->m_pNextBlock;
- if (pNextBlock == NULL || pNextBlock > pBlock) {
- break;
- }
- if (pPrevBlock != &m_AvailHead && (FX_LPBYTE)pNextBlock == (FX_LPBYTE)(pPrevBlock + 1) + pPrevBlock->m_nBlockSize) {
- m_nAvailSize += sizeof(CFXMEM_Block);
- pPrevBlock->m_nBlockSize += pNextBlock->m_nBlockSize + sizeof(CFXMEM_Block);
- pPrevBlock->m_pNextBlock = pNextBlock->m_pNextBlock;
- } else {
- pPrevBlock = pNextBlock;
- }
- }
- while ((FX_LPBYTE)pNextBlock == (FX_LPBYTE)(pBlock + 1) + pBlock->m_nBlockSize) {
- m_nAvailSize += sizeof(CFXMEM_Block);
- pBlock->m_nBlockSize += pNextBlock->m_nBlockSize + sizeof(CFXMEM_Block);
- pNextBlock = pNextBlock->m_pNextBlock;
- }
- pBlock->m_pNextBlock = pNextBlock;
- if (pPrevBlock != &m_AvailHead && (FX_LPBYTE)pBlock == (FX_LPBYTE)(pPrevBlock + 1) + pPrevBlock->m_nBlockSize) {
- m_nAvailSize += sizeof(CFXMEM_Block);
- pPrevBlock->m_nBlockSize += pBlock->m_nBlockSize + sizeof(CFXMEM_Block);
- pPrevBlock->m_pNextBlock = pBlock->m_pNextBlock;
- } else {
- FXSYS_assert(pPrevBlock != pBlock);
- pPrevBlock->m_pNextBlock = pBlock;
- }
-}
-void CFXMEM_Pages::Initialize(FX_LPBYTE pStart, size_t pageSize, size_t pages)
-{
- m_pStartPage = m_pCurPage = (CFXMEM_Page*)pStart;
- m_nPageSize = pageSize;
- for (size_t n = 0; n < pages; n++) {
- ((CFXMEM_Page*)pStart)->Initialize(pageSize);
- pStart += pageSize;
- }
- m_pLimitPos = (CFXMEM_Page*)pStart;
-}
-FX_BOOL CFXMEM_Pages::IsEmpty() const
-{
- if (m_pStartPage >= m_pLimitPos) {
- return TRUE;
- }
- FX_LPBYTE pPage = (FX_LPBYTE)m_pStartPage;
- while (pPage < (FX_LPBYTE)m_pLimitPos) {
- if (!((CFXMEM_Page*)pPage)->IsEmpty()) {
- return FALSE;
- }
- pPage += m_nPageSize;
- }
- return TRUE;
-}
-FX_LPVOID CFXMEM_Pages::Alloc(size_t size)
-{
- CFXMEM_Page *pCurPage = m_pCurPage;
- do {
- FX_LPVOID p = m_pCurPage->Alloc(size);
- if (p) {
- return p;
- }
- m_pCurPage = (CFXMEM_Page*)((FX_LPBYTE)m_pCurPage + m_nPageSize);
- if (m_pCurPage == m_pLimitPos) {
- m_pCurPage = m_pStartPage;
- }
- } while (m_pCurPage != pCurPage);
- return NULL;
-}
-FX_LPVOID CFXMEM_Pages::Realloc(FX_LPVOID p, size_t oldSize, size_t newSize)
-{
- FXSYS_assert (p > (FX_LPVOID)m_pStartPage && p < (FX_LPVOID)m_pLimitPos);
- CFXMEM_Page* pPage = (CFXMEM_Page*)((FX_LPBYTE)m_pStartPage + ((FX_LPBYTE)p - (FX_LPBYTE)m_pStartPage) / m_nPageSize * m_nPageSize);
- return pPage->Realloc(p, oldSize, newSize);
-}
-void CFXMEM_Pages::Free(FX_LPVOID p)
-{
- FXSYS_assert (p > (FX_LPVOID)m_pStartPage && p < (FX_LPVOID)m_pLimitPos);
- CFXMEM_Page* pPage = (CFXMEM_Page*)((FX_LPBYTE)m_pStartPage + ((FX_LPBYTE)p - (FX_LPBYTE)m_pStartPage) / m_nPageSize * m_nPageSize);
- pPage->Free(p);
-}
-void CFXMEM_Pool::Initialize(const FX_MEMCONFIG* pMemConfig, size_t size, size_t pageNum8Bytes, size_t pageNum16Bytes, size_t pageNum32Bytes, size_t pageNumMid)
-{
- m_pPrevPool = NULL;
- m_pNextPool = NULL;
- m_bAlone = FALSE;
- FX_LPBYTE pPage = (FX_LPBYTE)this + sizeof(CFXMEM_Pool);
- size -= sizeof(CFXMEM_Pool);
- m_8BytesPages.Initialize(pPage, pageNum8Bytes);
- pPage += pageNum8Bytes * FX_FIXEDMEM_PAGESIZE;
- size -= pageNum8Bytes * FX_FIXEDMEM_PAGESIZE;
- m_16BytesPages.Initialize(pPage, pageNum16Bytes);
- pPage += pageNum16Bytes * FX_FIXEDMEM_PAGESIZE;
- size -= pageNum16Bytes * FX_FIXEDMEM_PAGESIZE;
- m_32BytesPages.Initialize(pPage, pageNum32Bytes);
- pPage += pageNum32Bytes * FX_FIXEDMEM_PAGESIZE;
- size -= pageNum32Bytes * FX_FIXEDMEM_PAGESIZE;
- m_MidPages.Initialize(pPage, pMemConfig->nPageSize_Mid * FX_FIXEDMEM_PAGESIZE, pageNumMid);
- pPage += pageNumMid * pMemConfig->nPageSize_Mid * FX_FIXEDMEM_PAGESIZE;
- size -= pageNumMid * pMemConfig->nPageSize_Mid * FX_FIXEDMEM_PAGESIZE;
- if (size < FX_FIXEDMEM_MIDBLOCKSIZE) {
- m_pLargePage = NULL;
- } else {
- m_pLargePage = (CFXMEM_Page*)pPage;
- m_pLargePage->Initialize(size);
- }
- m_pLimitPos = pPage + size;
-}
-FX_BOOL CFXMEM_Pool::IsEmpty() const
-{
- if (!m_8BytesPages.IsEmpty()) {
- return FALSE;
- }
- if (!m_16BytesPages.IsEmpty()) {
- return FALSE;
- }
- if (!m_32BytesPages.IsEmpty()) {
- return FALSE;
- }
- if (!m_MidPages.IsEmpty()) {
- return FALSE;
- }
- return !m_pLargePage || m_pLargePage->IsEmpty();
-}
-size_t CFXMEM_Pool::GetSize(FX_LPVOID p) const
-{
- FXSYS_assert(p > (FX_LPVOID)this && p < (FX_LPVOID)m_pLimitPos);
- if (p < (FX_LPVOID)m_8BytesPages.m_pLimitPos) {
- return 8;
- }
- if (p < (FX_LPVOID)m_16BytesPages.m_pLimitPos) {
- return 16;
- }
- if (p < (FX_LPVOID)m_32BytesPages.m_pLimitPos) {
- return 32;
- }
- return ((CFXMEM_Block*)p - 1)->m_nBlockSize;
-}
-FX_LPVOID CFXMEM_Pool::Realloc(FX_LPVOID p, size_t oldSize, size_t newSize)
-{
- FXSYS_assert(p > (FX_LPVOID)this && p < (FX_LPVOID)m_pLimitPos);
- if (p > (FX_LPVOID)m_32BytesPages.m_pLimitPos) {
- if (p < (FX_LPVOID)m_MidPages.m_pLimitPos) {
- return m_MidPages.Realloc(p, oldSize, newSize);
- } else if (m_pLargePage) {
- return m_pLargePage->Realloc(p, oldSize, newSize);
- }
- }
- return NULL;
-}
-void CFXMEM_Pool::Free(FX_LPVOID p)
-{
- FXSYS_assert(p > (FX_LPVOID)this && p < (FX_LPVOID)m_pLimitPos);
- if (p < (FX_LPVOID)m_32BytesPages.m_pLimitPos) {
- if (p < (FX_LPVOID)m_8BytesPages.m_pLimitPos) {
- m_8BytesPages.Free(p);
- } else if (p < (FX_LPVOID)m_16BytesPages.m_pLimitPos) {
- m_16BytesPages.Free(p);
- } else {
- m_32BytesPages.Free(p);
- }
- return;
- } else if (p < (FX_LPVOID)m_MidPages.m_pLimitPos) {
- m_MidPages.Free(p);
- } else {
- m_pLargePage->Free(p);
- }
-}
-void CFXMEM_FixedMgr::Initialize(size_t size)
-{
- m_MemConfig = g_MemConfig;
- FXSYS_memset32(&m_SystemMgr, 0, sizeof m_SystemMgr);
- m_SystemMgr.Alloc = FixedAlloc;
- m_SystemMgr.AllocDebug = FixedAllocDebug;
- m_SystemMgr.Free = FixedFree;
- m_SystemMgr.Realloc = FixedRealloc;
- m_SystemMgr.ReallocDebug = FixedReallocDebug;
- m_SystemMgr.CollectAll = FixedCollectAll;
- m_SystemMgr.Purge = FixedPurge;
- m_SystemMgr.user = this;
- size -= sizeof(CFXMEM_FixedMgr);
- size_t nMidPages = 0;
- if (m_MemConfig.nPageSize_Mid) {
- nMidPages = (size - (m_MemConfig.nPageNum_Init8 + m_MemConfig.nPageNum_Init16 + m_MemConfig.nPageNum_Init32) * FX_FIXEDMEM_PAGESIZE) / (m_MemConfig.nPageSize_Mid * FX_FIXEDMEM_PAGESIZE);
- if (nMidPages > m_MemConfig.nPageNum_InitMid) {
- nMidPages = m_MemConfig.nPageNum_InitMid;
- }
- }
- m_FirstPool.Initialize(&m_MemConfig, size, m_MemConfig.nPageNum_Init8, m_MemConfig.nPageNum_Init16, m_MemConfig.nPageNum_Init32, nMidPages);
-}
-FX_LPVOID CFXMEM_FixedMgr::Alloc16(CFXMEM_Pool **pp32Pool, size_t size)
-{
- CFXMEM_Pool *pPool = &m_FirstPool;
- do {
- CFXMEM_16BytesPages &pages = pPool->m_16BytesPages;
- if (pages.HasFreeBlock()) {
- return pages.Alloc(size);
- }
- if (pp32Pool && pPool->m_32BytesPages.HasFreeBlock()) {
- *pp32Pool = pPool;
- }
- pPool = pPool->m_pNextPool;
- } while(pPool);
- return NULL;
-}
-FX_LPVOID CFXMEM_FixedMgr::Alloc32(size_t size)
-{
- if (size <= 8) {
- CFXMEM_8BytesPages &pages = m_FirstPool.m_8BytesPages;
- if (pages.HasFreeBlock()) {
- return pages.Alloc(size);
- }
- }
- CFXMEM_Pool *p32BytesPool;
- if (size <= 16) {
- p32BytesPool = NULL;
- FX_LPVOID p = Alloc16(&p32BytesPool, size);
- if (p) {
- return p;
- }
- } else {
- p32BytesPool = &m_FirstPool;
- }
- while (p32BytesPool) {
- CFXMEM_32BytesPages &pages = p32BytesPool->m_32BytesPages;
- if (pages.HasFreeBlock()) {
- return pages.Alloc(size);
- }
- p32BytesPool = p32BytesPool->m_pNextPool;
- }
- return NULL;
-}
-FX_LPVOID CFXMEM_FixedMgr::AllocSmall(size_t size)
-{
- FX_LPVOID p = Alloc32(size);
- if (p) {
- return p;
- }
- if (!m_pExtender) {
- return NULL;
- }
- size_t requiredSize = (m_MemConfig.nPageNum_More16 + m_MemConfig.nPageNum_More32) * FX_FIXEDMEM_PAGESIZE;
- if (!requiredSize) {
- return NULL;
- }
- CFXMEM_Pool *pNewPool = NULL;
- requiredSize += sizeof(CFXMEM_Pool);
- size_t newSize = requiredSize;
- if (!m_pExtender->More(m_pExtender, newSize, (void**)&pNewPool, &newSize)) {
- return NULL;
- }
- size_t nMidPages = 0;
- if (m_MemConfig.nPageSize_Mid) {
- nMidPages = (newSize - requiredSize) / (m_MemConfig.nPageSize_Mid * FX_FIXEDMEM_PAGESIZE);
- if (nMidPages > m_MemConfig.nPageNum_MoreMid) {
- nMidPages = m_MemConfig.nPageNum_MoreMid;
- }
- }
- pNewPool->Initialize(&m_MemConfig, newSize, 0, m_MemConfig.nPageNum_More16, m_MemConfig.nPageNum_More32, nMidPages);
- pNewPool->m_pPrevPool = &m_FirstPool;
- CFXMEM_Pool *pPool = m_FirstPool.m_pNextPool;
- pNewPool->m_pNextPool = pPool;
- if (pPool) {
- pPool->m_pPrevPool = pNewPool;
- }
- m_FirstPool.m_pNextPool = pNewPool;
- return Alloc32(size);
-}
-FX_LPVOID CFXMEM_FixedMgr::AllocMid(size_t size)
-{
- CFXMEM_Pool *pPool = &m_FirstPool;
- do {
- CFXMEM_Pages &pages = pPool->m_MidPages;
- if (pages.m_pLimitPos > pages.m_pStartPage) {
- FX_LPVOID p = pages.Alloc(size);
- if (p) {
- return p;
- }
- }
- pPool = pPool->m_pNextPool;
- } while(pPool);
- if (!m_pExtender) {
- return NULL;
- }
- size_t newSize = m_MemConfig.nPageSize_Mid * FX_FIXEDMEM_PAGESIZE * m_MemConfig.nPageNum_MoreMid;
- if (!newSize) {
- return NULL;
- }
- CFXMEM_Pool *pNewPool = NULL;
- newSize += sizeof(CFXMEM_Pool);
- if (!m_pExtender->More(m_pExtender, newSize, (void**)&pNewPool, &newSize)) {
- return NULL;
- }
- size_t nMidPages = (newSize - sizeof(CFXMEM_Pool)) / (m_MemConfig.nPageSize_Mid * FX_FIXEDMEM_PAGESIZE);
- if (nMidPages > m_MemConfig.nPageNum_MoreMid) {
- nMidPages = m_MemConfig.nPageNum_MoreMid;
- }
- pNewPool->Initialize(&m_MemConfig, newSize, 0, 0, 0, nMidPages);
- pNewPool->m_pPrevPool = &m_FirstPool;
- pPool = m_FirstPool.m_pNextPool;
- pNewPool->m_pNextPool = pPool;
- if (pPool) {
- pPool->m_pPrevPool = pNewPool;
- }
- m_FirstPool.m_pNextPool = pNewPool;
- return pNewPool->m_MidPages.Alloc(size);
-}
-FX_LPVOID CFXMEM_FixedMgr::AllocLarge(size_t size)
-{
- CFXMEM_Pool *pPool = &m_FirstPool;
- do {
- if (!pPool->m_bAlone && pPool->m_pLargePage) {
- FX_LPVOID p = pPool->m_pLargePage->Alloc(size);
- if (p) {
- return p;
- }
- }
- pPool = pPool->m_pNextPool;
- } while(pPool);
- if (!m_pExtender || !m_MemConfig.nPageSize_Large) {
- return NULL;
- }
- CFXMEM_Pool *pNewPool = NULL;
-#if _FX_WORDSIZE_ == _FX_W64_
- size_t newSize = ((size + 31) / 32 * 32 + sizeof(CFXMEM_Pool) + sizeof(CFXMEM_Page) + sizeof(CFXMEM_Block) + 4095) / 4096 * 4096;
-#else
- size_t newSize = (size + 7) / 8 * 8 + sizeof(CFXMEM_Pool) + sizeof(CFXMEM_Page) + sizeof(CFXMEM_Block);
-#endif
- if (newSize < m_MemConfig.nPageSize_Large * FX_FIXEDMEM_PAGESIZE) {
- newSize = m_MemConfig.nPageSize_Large * FX_FIXEDMEM_PAGESIZE;
- }
- if (!m_pExtender->More(m_pExtender, newSize, (void**)&pNewPool, &newSize)) {
- return NULL;
- }
- pNewPool->Initialize(&m_MemConfig, newSize, 0, 0, 0, 0);
- pNewPool->m_bAlone = size >= m_MemConfig.nPageSize_Alone * FX_FIXEDMEM_PAGESIZE;
- pNewPool->m_pPrevPool = &m_FirstPool;
- pPool = m_FirstPool.m_pNextPool;
- pNewPool->m_pNextPool = pPool;
- if (pPool) {
- pPool->m_pPrevPool = pNewPool;
- }
- m_FirstPool.m_pNextPool = pNewPool;
- return pNewPool->m_pLargePage->Alloc(size);
-}
-size_t CFXMEM_FixedMgr::GetSize(FX_LPVOID p) const
-{
- const CFXMEM_Pool *pFind = &m_FirstPool;
- do {
- if (p > (FX_LPVOID)pFind && p < pFind->m_pLimitPos) {
- return pFind->GetSize(p);
- }
- pFind = pFind->m_pNextPool;
- } while (pFind);
- return 0;
-}
-FX_LPVOID CFXMEM_FixedMgr::Alloc(size_t size)
-{
- FX_LPVOID p;
- if (size <= 32) {
- p = AllocSmall(size);
- if (p) {
- return p;
- }
- }
- if (size <= FX_FIXEDMEM_MIDBLOCKSIZE) {
- p = AllocMid(size);
- if (p) {
- return p;
- }
- }
- p = AllocLarge(size);
- return p;
-}
-FX_LPVOID CFXMEM_FixedMgr::ReallocSmall(CFXMEM_Pool* pPool, FX_LPVOID p, size_t oldSize, size_t newSize)
-{
- FX_LPVOID np = AllocSmall(newSize);
- if (!np) {
- return NULL;
- }
- FXSYS_memcpy32(np, p, oldSize);
- pPool->Free(p);
- return np;
-}
-FX_LPVOID CFXMEM_FixedMgr::Realloc(FX_LPVOID p, size_t newSize)
-{
- if (!p) {
- return Alloc(newSize);
- }
- size_t oldSize = 0;
- CFXMEM_Pool *pFind = &m_FirstPool;
- do {
- if (p > (FX_LPVOID)pFind && p < pFind->m_pLimitPos) {
- oldSize = pFind->GetSize(p);
- if (oldSize >= newSize) {
- return p;
- }
- break;
- }
- pFind = pFind->m_pNextPool;
- } while (pFind);
- if (!oldSize || !pFind) {
- return Alloc(newSize);
- }
- FX_LPVOID np = NULL;
- if (newSize <= 32) {
- np = ReallocSmall(pFind, p, oldSize, newSize);
- if (np) {
- return np;
- }
- }
- if (newSize <= FX_FIXEDMEM_MIDBLOCKSIZE) {
- np = pFind->Realloc(p, oldSize, newSize);
- if (np) {
- return np;
- }
- }
- np = Alloc(newSize);
- if (np) {
- FXSYS_memcpy32(np, p, oldSize);
- pFind->Free(p);
- }
- if (pFind->m_bAlone && pFind->IsEmpty()) {
- FreePool(pFind);
- }
- return np;
-}
-void CFXMEM_FixedMgr::Free(FX_LPVOID p)
-{
- CFXMEM_Pool *pFind = &m_FirstPool;
- do {
- if (p > (FX_LPVOID)pFind && p < pFind->m_pLimitPos) {
- pFind->Free(p);
- if (pFind->m_bAlone && pFind->IsEmpty()) {
- FreePool(pFind);
- }
- return;
- }
- pFind = pFind->m_pNextPool;
- } while (pFind);
-}
-void CFXMEM_FixedMgr::FreePool(CFXMEM_Pool* pPool)
-{
- FXSYS_assert(pPool->m_bAlone && pPool->IsEmpty());
- FXSYS_assert(m_pExtender != NULL);
- CFXMEM_Pool* pPrevPool = pPool->m_pPrevPool;
- CFXMEM_Pool* pNextPool = pPool->m_pNextPool;
- if (pPrevPool) {
- pPrevPool->m_pNextPool = pNextPool;
- }
- if (pNextPool) {
- pNextPool->m_pPrevPool = pPrevPool;
- }
- m_pExtender->Free(m_pExtender, pPool);
-}
-void CFXMEM_FixedMgr::FreeAll()
-{
- if (!m_pExtender) {
- return;
- }
- CFXMEM_Pool* pPool = m_FirstPool.m_pNextPool;
- while (pPool) {
- CFXMEM_Pool* pPrevPool = pPool;
- pPool = pPool->m_pNextPool;
- m_pExtender->Free(m_pExtender, pPrevPool);
- }
- m_FirstPool.m_pNextPool = NULL;
-}
-void CFXMEM_FixedMgr::Purge()
-{
- if (!m_pExtender) {
- return;
- }
- CFXMEM_Pool* pPool = m_FirstPool.m_pNextPool;
- while (pPool) {
- CFXMEM_Pool* pNextPool = pPool->m_pNextPool;
- if (pPool->IsEmpty()) {
- CFXMEM_Pool* pPrevPool = pPool->m_pPrevPool;
- pPrevPool->m_pNextPool = pNextPool;
- if (pNextPool) {
- pNextPool->m_pPrevPool = pPrevPool;
- }
- m_pExtender->Free(m_pExtender, pPool);
- }
- pPool = pNextPool;
- }
-}
-extern const FX_BYTE OneLeadPos[256] = {
- 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-extern const FX_BYTE ZeroLeadPos[256] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8,
-};
+// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "../../include/fxcrt/fx_ext.h" +#include "mem_int.h" +#ifdef _FPDFAPI_MINI_ +static FX_MEMCONFIG g_MemConfig = { + 1, + 5, + 8, + 4, + 12, + 8, + 2, + 4, + 32, + 64, +}; +#else +static FX_MEMCONFIG g_MemConfig = { + 1, + 8, + 24, + 8, + 32, + 16, + 4, + 8, + 128, + 64, +}; +#endif +void FXMEM_SetConfig(const FX_MEMCONFIG* memConfig) +{ + g_MemConfig = *memConfig; +} +#ifdef __cplusplus +extern "C" { +#endif +static void* FixedAlloc(FXMEM_SystemMgr* pMgr, size_t size, int flags) +{ + return ((CFXMEM_FixedMgr*)pMgr->user)->Alloc(size); +} +static void* FixedAllocDebug(FXMEM_SystemMgr* pMgr, size_t size, int flags, FX_LPCSTR file, int line) +{ + return ((CFXMEM_FixedMgr*)pMgr->user)->Alloc(size); +} +static void* FixedRealloc(FXMEM_SystemMgr* pMgr, void* pointer, size_t size, int flags) +{ + return ((CFXMEM_FixedMgr*)pMgr->user)->Realloc(pointer, size); +} +static void* FixedReallocDebug(FXMEM_SystemMgr* pMgr, void* pointer, size_t size, int flags, FX_LPCSTR file, int line) +{ + return ((CFXMEM_FixedMgr*)pMgr->user)->Realloc(pointer, size); +} +static void FixedFree(FXMEM_SystemMgr* pMgr, void* pointer, int flags) +{ + ((CFXMEM_FixedMgr*)pMgr->user)->Free(pointer); +} +static void FixedPurge(FXMEM_SystemMgr* pMgr) +{ + ((CFXMEM_FixedMgr*)pMgr->user)->Purge(); +} +static void FixedCollectAll(FXMEM_SystemMgr* pMgr) +{ + ((CFXMEM_FixedMgr*)pMgr->user)->FreeAll(); +} +#define FIXEDMEM_MINIMUMSIZE (1024 * 1024 * 8) +FXMEM_FoxitMgr* FXMEM_CreateMemoryMgr(size_t size, FX_BOOL extensible) +{ + if (size < FIXEDMEM_MINIMUMSIZE) { + size = FIXEDMEM_MINIMUMSIZE; + } + FX_LPVOID pMemory = malloc(size); + if (!pMemory) { + return NULL; + } + CFixedMgr_Proxy* pProxy = (CFixedMgr_Proxy*)pMemory; + size_t offsetSize = (sizeof(CFixedMgr_Proxy) + 15) / 16 * 16; + FXMEM_FoxitMgr* pFoxitMgr = pProxy->Initialize((FX_LPBYTE)pProxy + offsetSize, size - offsetSize, extensible); + if (!pFoxitMgr) { + free(pMemory); + return NULL; + } + g_pDefFoxitMgr = (CFX_MemoryMgr*)pFoxitMgr; + g_pDefFoxitMgr->m_pExternalMemory = pMemory; + return pFoxitMgr; +} +FXMEM_FoxitMgr* FXMEM_CreateFixedMgr(void* pMemory, size_t size, FXMEM_SystemMgr2* pSystemMgr) +{ + if (pMemory == NULL || size < FX_FIXEDMEM_PAGESIZE) { + return NULL; + } + if (!pSystemMgr && size >= FIXEDMEM_PROXYSIZE_1) { + CFixedMgr_Proxy* pProxy = (CFixedMgr_Proxy*)pMemory; + size_t offsetSize = (sizeof(CFixedMgr_Proxy) + 15) / 16 * 16; + return pProxy->Initialize((FX_LPBYTE)pProxy + offsetSize, size - offsetSize, FALSE); + } + CFXMEM_FixedMgr* pHeader = (CFXMEM_FixedMgr*)pMemory; + pHeader->Initialize(size); + pHeader->m_pExtender = pSystemMgr; + CFX_MemoryMgr* p = (CFX_MemoryMgr*)pHeader->Alloc(sizeof(CFX_MemoryMgr)); + if (p == NULL) { + return NULL; + } + p->Init(&pHeader->m_SystemMgr); + return (FXMEM_FoxitMgr*)p; +} +size_t FXMEM_GetBlockSizeInFixedMgr(FXMEM_FoxitMgr* pFoxitMgr, void* ptr) +{ + return pFoxitMgr ? ((CFXMEM_FixedMgr*)((CFX_MemoryMgr*)pFoxitMgr)->m_pSystemMgr->user)->GetSize(ptr) : 0; +} +#ifdef __cplusplus +} +#endif +const FX_MEMCONFIG g_ProxyMgr_MemConfigs[6] = { + {1, 2, 4, 0, 2, 2, 2, 0, 0, 0}, + {1, 4, 8, 0, 2, 2, 2, 0, 0, 0}, + {1, 4, 16, 4, 8, 8, 2, 1, 16, 16}, + {1, 8, 24, 4, 12, 12, 4, 2, 32, 16}, + {1, 8, 24, 8, 16, 16, 4, 2, 64, 32}, + {1, 8, 24, 8, 24, 32, 4, 2, 128, 64}, +}; +const FX_MEMCONFIG* FixedMgr_GetConfig(size_t nSize) +{ + int index = 5; + if (nSize <= FIXEDMEM_PROXYSIZE_0) { + index = 0; + } else if (nSize <= FIXEDMEM_PROXYSIZE_1) { + index = 1; + } else if (nSize <= FIXEDMEM_PROXYSIZE_2) { + index = 2; + } else if (nSize <= FIXEDMEM_PROXYSIZE_3) { + index = 3; + } else if (nSize <= FIXEDMEM_PROXYSIZE_4) { + index = 4; + } + return &g_ProxyMgr_MemConfigs[index]; +} +FXMEM_FoxitMgr* CFixedMgr_Proxy::Initialize(FX_LPVOID pBuffer, size_t nSize, FX_BOOL bExtensible) +{ + FXSYS_assert(pBuffer != NULL && nSize >= FIXEDMEM_PROXYSIZE_1 - sizeof(CFixedMgr_Proxy)); + FXMEM_SetConfig(FixedMgr_GetConfig(nSize)); + m_SystemMgr.More = &CFixedMgr_Proxy::Common_More; + m_SystemMgr.Free = &CFixedMgr_Proxy::Common_Free; + m_pFixedPage = (CFXMEM_Page*)((FX_LPBYTE)pBuffer + FIXEDMEM_PROXYSIZE_0); + m_pFixedPage->Initialize(nSize - FIXEDMEM_PROXYSIZE_0); + m_pBuffer = pBuffer; + m_nSize = nSize; + m_bExtensible = bExtensible; + return FXMEM_CreateFixedMgr(pBuffer, FIXEDMEM_PROXYSIZE_0, &m_SystemMgr); +} +FX_BOOL CFixedMgr_Proxy::Common_More(FXMEM_SystemMgr2* pMgr, size_t alloc_size, void** new_memory, size_t* new_size) +{ + CFixedMgr_Proxy* pProxyMgr = (CFixedMgr_Proxy*)pMgr; + FXSYS_assert(pProxyMgr != NULL && pProxyMgr->m_pFixedPage != NULL); + *new_size = alloc_size; + *new_memory = pProxyMgr->m_pFixedPage->Alloc(alloc_size); + if (*new_memory == NULL && pProxyMgr->m_bExtensible) { + *new_memory = malloc(alloc_size); + } + return *new_memory != NULL; +} +void CFixedMgr_Proxy::Common_Free(FXMEM_SystemMgr2* pMgr, void* memory) +{ + CFixedMgr_Proxy* pProxyMgr = (CFixedMgr_Proxy*)pMgr; + FXSYS_assert(pProxyMgr != NULL && pProxyMgr->m_pFixedPage != NULL); + if (memory > pProxyMgr->m_pBuffer && memory < (FX_LPBYTE)pProxyMgr->m_pBuffer + pProxyMgr->m_nSize) { + pProxyMgr->m_pFixedPage->Free(memory); + } else if (pProxyMgr->m_bExtensible) { + free(memory); + } +} +void CFXMEM_Page::Initialize(size_t size) +{ + CFXMEM_Block *pFirstBlock = (CFXMEM_Block*)(this + 1); + m_nAvailSize = size - sizeof(CFXMEM_Page) - sizeof(CFXMEM_Block); + pFirstBlock->m_nBlockSize = m_nAvailSize; + pFirstBlock->m_pNextBlock = NULL; + m_AvailHead.m_nBlockSize = m_nAvailSize; + m_AvailHead.m_pNextBlock = pFirstBlock; + m_pLimitPos = (CFXMEM_Block*)((FX_LPBYTE)this + size); +} +FX_LPVOID CFXMEM_Page::Alloc(CFXMEM_Block* pPrevBlock, CFXMEM_Block* pNextBlock, size_t size, size_t oldsize) +{ + size_t gap = pNextBlock->m_nBlockSize - size; + if (gap <= 64 + sizeof(CFXMEM_Block)) { + pPrevBlock->m_pNextBlock = pNextBlock->m_pNextBlock; + m_nAvailSize -= pNextBlock->m_nBlockSize; + } else { + m_nAvailSize -= size + sizeof(CFXMEM_Block); + pNextBlock->m_nBlockSize = size; + CFXMEM_Block *pNewBlock = (CFXMEM_Block*)((FX_LPBYTE)(pNextBlock + 1) + size); + pNewBlock->m_nBlockSize = gap - sizeof(CFXMEM_Block); + pNewBlock->m_pNextBlock = pNextBlock->m_pNextBlock; + pPrevBlock->m_pNextBlock = pNewBlock; + } + return (FX_LPVOID)(pNextBlock + 1); +} +FX_LPVOID CFXMEM_Page::Alloc(size_t size) +{ + size_t oldsize = size; +#if _FX_WORDSIZE_ == _FX_W64_ + size = (size + 31) / 32 * 32; +#else + size = (size + 7) / 8 * 8; +#endif + if (m_nAvailSize < size) { + return NULL; + } + CFXMEM_Block *pNextBlock; + CFXMEM_Block *pPrevBlock = &m_AvailHead; + while (TRUE) { + pNextBlock = pPrevBlock->m_pNextBlock; + if (!pNextBlock) { + return NULL; + } + if (pNextBlock->m_nBlockSize >= size) { + break; + } + pPrevBlock = pNextBlock; + } + return Alloc(pPrevBlock, pNextBlock, size, oldsize); +} +FX_LPVOID CFXMEM_Page::Realloc(FX_LPVOID p, size_t oldSize, size_t newSize) +{ + FXSYS_assert(p > (FX_LPVOID)this && p < (FX_LPVOID)m_pLimitPos); + size_t oldnewSize = newSize; +#if _FX_WORDSIZE_ == _FX_W64_ + newSize = (newSize + 31) / 32 * 32; +#else + newSize = (newSize + 7) / 8 * 8; +#endif + CFXMEM_Block *pPrevBlock = &m_AvailHead; + CFXMEM_Block *pNextBlock, *pPrevPrev; + CFXMEM_Block *pBlock = (CFXMEM_Block*)p - 1; + pPrevPrev = NULL; + while (TRUE) { + pNextBlock = pPrevBlock->m_pNextBlock; + if (pNextBlock == NULL || pNextBlock > pBlock) { + break; + } + if (pPrevBlock != &m_AvailHead && (FX_LPBYTE)pNextBlock == (FX_LPBYTE)(pPrevBlock + 1) + pPrevBlock->m_nBlockSize) { + m_nAvailSize += sizeof(CFXMEM_Block); + pPrevBlock->m_nBlockSize += pNextBlock->m_nBlockSize + sizeof(CFXMEM_Block); + pPrevBlock->m_pNextBlock = pNextBlock->m_pNextBlock; + } else { + pPrevPrev = pPrevBlock; + pPrevBlock = pNextBlock; + } + } + if (pNextBlock) { + CFXMEM_Block* pCurBlock = pNextBlock->m_pNextBlock; + while ((FX_LPBYTE)pCurBlock == (FX_LPBYTE)(pNextBlock + 1) + pNextBlock->m_nBlockSize) { + m_nAvailSize += sizeof(CFXMEM_Block); + pNextBlock->m_nBlockSize += pCurBlock->m_nBlockSize + sizeof(CFXMEM_Block); + pCurBlock = pCurBlock->m_pNextBlock; + pNextBlock->m_pNextBlock = pCurBlock; + } + } + size_t size = 0; + FX_DWORD dwFlags = 0; + if (pPrevBlock != &m_AvailHead && (FX_LPBYTE)pBlock == (FX_LPBYTE)(pPrevBlock + 1) + pPrevBlock->m_nBlockSize) { + size += pPrevBlock->m_nBlockSize + oldSize + sizeof(CFXMEM_Block); + dwFlags |= 0x10; + } + if (pNextBlock && (FX_LPBYTE)pNextBlock == (FX_LPBYTE)p + oldSize) { + size += pNextBlock->m_nBlockSize + sizeof(CFXMEM_Block); + dwFlags |= 0x01; + } + if (size >= newSize) { + m_nAvailSize += pBlock->m_nBlockSize; + CFXMEM_Block* pCurBlock = pBlock; + if (dwFlags & 0x10) { + pCurBlock = pPrevBlock; + m_nAvailSize += sizeof(CFXMEM_Block); + pCurBlock->m_nBlockSize += pBlock->m_nBlockSize + sizeof(CFXMEM_Block); + pPrevBlock = pPrevPrev; + } + if (dwFlags & 0x01) { + m_nAvailSize += sizeof(CFXMEM_Block); + pCurBlock->m_nBlockSize += pNextBlock->m_nBlockSize + sizeof(CFXMEM_Block); + pCurBlock->m_pNextBlock = pNextBlock->m_pNextBlock; + } + if (pCurBlock != pBlock) { + FXSYS_memmove32((FX_LPVOID)(pCurBlock + 1), p, oldSize); + } + return Alloc(pPrevBlock, pCurBlock, newSize, oldnewSize); + } + return NULL; +} +void CFXMEM_Page::Free(FX_LPVOID p) +{ + FXSYS_assert(p > (FX_LPVOID)this && p < (FX_LPVOID)m_pLimitPos); + CFXMEM_Block *pPrevBlock = &m_AvailHead; + CFXMEM_Block *pNextBlock; + CFXMEM_Block *pBlock = (CFXMEM_Block*)p - 1; + m_nAvailSize += pBlock->m_nBlockSize; + while (TRUE) { + pNextBlock = pPrevBlock->m_pNextBlock; + if (pNextBlock == NULL || pNextBlock > pBlock) { + break; + } + if (pPrevBlock != &m_AvailHead && (FX_LPBYTE)pNextBlock == (FX_LPBYTE)(pPrevBlock + 1) + pPrevBlock->m_nBlockSize) { + m_nAvailSize += sizeof(CFXMEM_Block); + pPrevBlock->m_nBlockSize += pNextBlock->m_nBlockSize + sizeof(CFXMEM_Block); + pPrevBlock->m_pNextBlock = pNextBlock->m_pNextBlock; + } else { + pPrevBlock = pNextBlock; + } + } + while ((FX_LPBYTE)pNextBlock == (FX_LPBYTE)(pBlock + 1) + pBlock->m_nBlockSize) { + m_nAvailSize += sizeof(CFXMEM_Block); + pBlock->m_nBlockSize += pNextBlock->m_nBlockSize + sizeof(CFXMEM_Block); + pNextBlock = pNextBlock->m_pNextBlock; + } + pBlock->m_pNextBlock = pNextBlock; + if (pPrevBlock != &m_AvailHead && (FX_LPBYTE)pBlock == (FX_LPBYTE)(pPrevBlock + 1) + pPrevBlock->m_nBlockSize) { + m_nAvailSize += sizeof(CFXMEM_Block); + pPrevBlock->m_nBlockSize += pBlock->m_nBlockSize + sizeof(CFXMEM_Block); + pPrevBlock->m_pNextBlock = pBlock->m_pNextBlock; + } else { + FXSYS_assert(pPrevBlock != pBlock); + pPrevBlock->m_pNextBlock = pBlock; + } +} +void CFXMEM_Pages::Initialize(FX_LPBYTE pStart, size_t pageSize, size_t pages) +{ + m_pStartPage = m_pCurPage = (CFXMEM_Page*)pStart; + m_nPageSize = pageSize; + for (size_t n = 0; n < pages; n++) { + ((CFXMEM_Page*)pStart)->Initialize(pageSize); + pStart += pageSize; + } + m_pLimitPos = (CFXMEM_Page*)pStart; +} +FX_BOOL CFXMEM_Pages::IsEmpty() const +{ + if (m_pStartPage >= m_pLimitPos) { + return TRUE; + } + FX_LPBYTE pPage = (FX_LPBYTE)m_pStartPage; + while (pPage < (FX_LPBYTE)m_pLimitPos) { + if (!((CFXMEM_Page*)pPage)->IsEmpty()) { + return FALSE; + } + pPage += m_nPageSize; + } + return TRUE; +} +FX_LPVOID CFXMEM_Pages::Alloc(size_t size) +{ + CFXMEM_Page *pCurPage = m_pCurPage; + do { + FX_LPVOID p = m_pCurPage->Alloc(size); + if (p) { + return p; + } + m_pCurPage = (CFXMEM_Page*)((FX_LPBYTE)m_pCurPage + m_nPageSize); + if (m_pCurPage == m_pLimitPos) { + m_pCurPage = m_pStartPage; + } + } while (m_pCurPage != pCurPage); + return NULL; +} +FX_LPVOID CFXMEM_Pages::Realloc(FX_LPVOID p, size_t oldSize, size_t newSize) +{ + FXSYS_assert (p > (FX_LPVOID)m_pStartPage && p < (FX_LPVOID)m_pLimitPos); + CFXMEM_Page* pPage = (CFXMEM_Page*)((FX_LPBYTE)m_pStartPage + ((FX_LPBYTE)p - (FX_LPBYTE)m_pStartPage) / m_nPageSize * m_nPageSize); + return pPage->Realloc(p, oldSize, newSize); +} +void CFXMEM_Pages::Free(FX_LPVOID p) +{ + FXSYS_assert (p > (FX_LPVOID)m_pStartPage && p < (FX_LPVOID)m_pLimitPos); + CFXMEM_Page* pPage = (CFXMEM_Page*)((FX_LPBYTE)m_pStartPage + ((FX_LPBYTE)p - (FX_LPBYTE)m_pStartPage) / m_nPageSize * m_nPageSize); + pPage->Free(p); +} +void CFXMEM_Pool::Initialize(const FX_MEMCONFIG* pMemConfig, size_t size, size_t pageNum8Bytes, size_t pageNum16Bytes, size_t pageNum32Bytes, size_t pageNumMid) +{ + m_pPrevPool = NULL; + m_pNextPool = NULL; + m_bAlone = FALSE; + FX_LPBYTE pPage = (FX_LPBYTE)this + sizeof(CFXMEM_Pool); + size -= sizeof(CFXMEM_Pool); + m_8BytesPages.Initialize(pPage, pageNum8Bytes); + pPage += pageNum8Bytes * FX_FIXEDMEM_PAGESIZE; + size -= pageNum8Bytes * FX_FIXEDMEM_PAGESIZE; + m_16BytesPages.Initialize(pPage, pageNum16Bytes); + pPage += pageNum16Bytes * FX_FIXEDMEM_PAGESIZE; + size -= pageNum16Bytes * FX_FIXEDMEM_PAGESIZE; + m_32BytesPages.Initialize(pPage, pageNum32Bytes); + pPage += pageNum32Bytes * FX_FIXEDMEM_PAGESIZE; + size -= pageNum32Bytes * FX_FIXEDMEM_PAGESIZE; + m_MidPages.Initialize(pPage, pMemConfig->nPageSize_Mid * FX_FIXEDMEM_PAGESIZE, pageNumMid); + pPage += pageNumMid * pMemConfig->nPageSize_Mid * FX_FIXEDMEM_PAGESIZE; + size -= pageNumMid * pMemConfig->nPageSize_Mid * FX_FIXEDMEM_PAGESIZE; + if (size < FX_FIXEDMEM_MIDBLOCKSIZE) { + m_pLargePage = NULL; + } else { + m_pLargePage = (CFXMEM_Page*)pPage; + m_pLargePage->Initialize(size); + } + m_pLimitPos = pPage + size; +} +FX_BOOL CFXMEM_Pool::IsEmpty() const +{ + if (!m_8BytesPages.IsEmpty()) { + return FALSE; + } + if (!m_16BytesPages.IsEmpty()) { + return FALSE; + } + if (!m_32BytesPages.IsEmpty()) { + return FALSE; + } + if (!m_MidPages.IsEmpty()) { + return FALSE; + } + return !m_pLargePage || m_pLargePage->IsEmpty(); +} +size_t CFXMEM_Pool::GetSize(FX_LPVOID p) const +{ + FXSYS_assert(p > (FX_LPVOID)this && p < (FX_LPVOID)m_pLimitPos); + if (p < (FX_LPVOID)m_8BytesPages.m_pLimitPos) { + return 8; + } + if (p < (FX_LPVOID)m_16BytesPages.m_pLimitPos) { + return 16; + } + if (p < (FX_LPVOID)m_32BytesPages.m_pLimitPos) { + return 32; + } + return ((CFXMEM_Block*)p - 1)->m_nBlockSize; +} +FX_LPVOID CFXMEM_Pool::Realloc(FX_LPVOID p, size_t oldSize, size_t newSize) +{ + FXSYS_assert(p > (FX_LPVOID)this && p < (FX_LPVOID)m_pLimitPos); + if (p > (FX_LPVOID)m_32BytesPages.m_pLimitPos) { + if (p < (FX_LPVOID)m_MidPages.m_pLimitPos) { + return m_MidPages.Realloc(p, oldSize, newSize); + } else if (m_pLargePage) { + return m_pLargePage->Realloc(p, oldSize, newSize); + } + } + return NULL; +} +void CFXMEM_Pool::Free(FX_LPVOID p) +{ + FXSYS_assert(p > (FX_LPVOID)this && p < (FX_LPVOID)m_pLimitPos); + if (p < (FX_LPVOID)m_32BytesPages.m_pLimitPos) { + if (p < (FX_LPVOID)m_8BytesPages.m_pLimitPos) { + m_8BytesPages.Free(p); + } else if (p < (FX_LPVOID)m_16BytesPages.m_pLimitPos) { + m_16BytesPages.Free(p); + } else { + m_32BytesPages.Free(p); + } + return; + } else if (p < (FX_LPVOID)m_MidPages.m_pLimitPos) { + m_MidPages.Free(p); + } else { + m_pLargePage->Free(p); + } +} +void CFXMEM_FixedMgr::Initialize(size_t size) +{ + m_MemConfig = g_MemConfig; + FXSYS_memset32(&m_SystemMgr, 0, sizeof m_SystemMgr); + m_SystemMgr.Alloc = FixedAlloc; + m_SystemMgr.AllocDebug = FixedAllocDebug; + m_SystemMgr.Free = FixedFree; + m_SystemMgr.Realloc = FixedRealloc; + m_SystemMgr.ReallocDebug = FixedReallocDebug; + m_SystemMgr.CollectAll = FixedCollectAll; + m_SystemMgr.Purge = FixedPurge; + m_SystemMgr.user = this; + size -= sizeof(CFXMEM_FixedMgr); + size_t nMidPages = 0; + if (m_MemConfig.nPageSize_Mid) { + nMidPages = (size - (m_MemConfig.nPageNum_Init8 + m_MemConfig.nPageNum_Init16 + m_MemConfig.nPageNum_Init32) * FX_FIXEDMEM_PAGESIZE) / (m_MemConfig.nPageSize_Mid * FX_FIXEDMEM_PAGESIZE); + if (nMidPages > m_MemConfig.nPageNum_InitMid) { + nMidPages = m_MemConfig.nPageNum_InitMid; + } + } + m_FirstPool.Initialize(&m_MemConfig, size, m_MemConfig.nPageNum_Init8, m_MemConfig.nPageNum_Init16, m_MemConfig.nPageNum_Init32, nMidPages); +} +FX_LPVOID CFXMEM_FixedMgr::Alloc16(CFXMEM_Pool **pp32Pool, size_t size) +{ + CFXMEM_Pool *pPool = &m_FirstPool; + do { + CFXMEM_16BytesPages &pages = pPool->m_16BytesPages; + if (pages.HasFreeBlock()) { + return pages.Alloc(size); + } + if (pp32Pool && pPool->m_32BytesPages.HasFreeBlock()) { + *pp32Pool = pPool; + } + pPool = pPool->m_pNextPool; + } while(pPool); + return NULL; +} +FX_LPVOID CFXMEM_FixedMgr::Alloc32(size_t size) +{ + if (size <= 8) { + CFXMEM_8BytesPages &pages = m_FirstPool.m_8BytesPages; + if (pages.HasFreeBlock()) { + return pages.Alloc(size); + } + } + CFXMEM_Pool *p32BytesPool; + if (size <= 16) { + p32BytesPool = NULL; + FX_LPVOID p = Alloc16(&p32BytesPool, size); + if (p) { + return p; + } + } else { + p32BytesPool = &m_FirstPool; + } + while (p32BytesPool) { + CFXMEM_32BytesPages &pages = p32BytesPool->m_32BytesPages; + if (pages.HasFreeBlock()) { + return pages.Alloc(size); + } + p32BytesPool = p32BytesPool->m_pNextPool; + } + return NULL; +} +FX_LPVOID CFXMEM_FixedMgr::AllocSmall(size_t size) +{ + FX_LPVOID p = Alloc32(size); + if (p) { + return p; + } + if (!m_pExtender) { + return NULL; + } + size_t requiredSize = (m_MemConfig.nPageNum_More16 + m_MemConfig.nPageNum_More32) * FX_FIXEDMEM_PAGESIZE; + if (!requiredSize) { + return NULL; + } + CFXMEM_Pool *pNewPool = NULL; + requiredSize += sizeof(CFXMEM_Pool); + size_t newSize = requiredSize; + if (!m_pExtender->More(m_pExtender, newSize, (void**)&pNewPool, &newSize)) { + return NULL; + } + size_t nMidPages = 0; + if (m_MemConfig.nPageSize_Mid) { + nMidPages = (newSize - requiredSize) / (m_MemConfig.nPageSize_Mid * FX_FIXEDMEM_PAGESIZE); + if (nMidPages > m_MemConfig.nPageNum_MoreMid) { + nMidPages = m_MemConfig.nPageNum_MoreMid; + } + } + pNewPool->Initialize(&m_MemConfig, newSize, 0, m_MemConfig.nPageNum_More16, m_MemConfig.nPageNum_More32, nMidPages); + pNewPool->m_pPrevPool = &m_FirstPool; + CFXMEM_Pool *pPool = m_FirstPool.m_pNextPool; + pNewPool->m_pNextPool = pPool; + if (pPool) { + pPool->m_pPrevPool = pNewPool; + } + m_FirstPool.m_pNextPool = pNewPool; + return Alloc32(size); +} +FX_LPVOID CFXMEM_FixedMgr::AllocMid(size_t size) +{ + CFXMEM_Pool *pPool = &m_FirstPool; + do { + CFXMEM_Pages &pages = pPool->m_MidPages; + if (pages.m_pLimitPos > pages.m_pStartPage) { + FX_LPVOID p = pages.Alloc(size); + if (p) { + return p; + } + } + pPool = pPool->m_pNextPool; + } while(pPool); + if (!m_pExtender) { + return NULL; + } + size_t newSize = m_MemConfig.nPageSize_Mid * FX_FIXEDMEM_PAGESIZE * m_MemConfig.nPageNum_MoreMid; + if (!newSize) { + return NULL; + } + CFXMEM_Pool *pNewPool = NULL; + newSize += sizeof(CFXMEM_Pool); + if (!m_pExtender->More(m_pExtender, newSize, (void**)&pNewPool, &newSize)) { + return NULL; + } + size_t nMidPages = (newSize - sizeof(CFXMEM_Pool)) / (m_MemConfig.nPageSize_Mid * FX_FIXEDMEM_PAGESIZE); + if (nMidPages > m_MemConfig.nPageNum_MoreMid) { + nMidPages = m_MemConfig.nPageNum_MoreMid; + } + pNewPool->Initialize(&m_MemConfig, newSize, 0, 0, 0, nMidPages); + pNewPool->m_pPrevPool = &m_FirstPool; + pPool = m_FirstPool.m_pNextPool; + pNewPool->m_pNextPool = pPool; + if (pPool) { + pPool->m_pPrevPool = pNewPool; + } + m_FirstPool.m_pNextPool = pNewPool; + return pNewPool->m_MidPages.Alloc(size); +} +FX_LPVOID CFXMEM_FixedMgr::AllocLarge(size_t size) +{ + CFXMEM_Pool *pPool = &m_FirstPool; + do { + if (!pPool->m_bAlone && pPool->m_pLargePage) { + FX_LPVOID p = pPool->m_pLargePage->Alloc(size); + if (p) { + return p; + } + } + pPool = pPool->m_pNextPool; + } while(pPool); + if (!m_pExtender || !m_MemConfig.nPageSize_Large) { + return NULL; + } + CFXMEM_Pool *pNewPool = NULL; +#if _FX_WORDSIZE_ == _FX_W64_ + size_t newSize = ((size + 31) / 32 * 32 + sizeof(CFXMEM_Pool) + sizeof(CFXMEM_Page) + sizeof(CFXMEM_Block) + 4095) / 4096 * 4096; +#else + size_t newSize = (size + 7) / 8 * 8 + sizeof(CFXMEM_Pool) + sizeof(CFXMEM_Page) + sizeof(CFXMEM_Block); +#endif + if (newSize < m_MemConfig.nPageSize_Large * FX_FIXEDMEM_PAGESIZE) { + newSize = m_MemConfig.nPageSize_Large * FX_FIXEDMEM_PAGESIZE; + } + if (!m_pExtender->More(m_pExtender, newSize, (void**)&pNewPool, &newSize)) { + return NULL; + } + pNewPool->Initialize(&m_MemConfig, newSize, 0, 0, 0, 0); + pNewPool->m_bAlone = size >= m_MemConfig.nPageSize_Alone * FX_FIXEDMEM_PAGESIZE; + pNewPool->m_pPrevPool = &m_FirstPool; + pPool = m_FirstPool.m_pNextPool; + pNewPool->m_pNextPool = pPool; + if (pPool) { + pPool->m_pPrevPool = pNewPool; + } + m_FirstPool.m_pNextPool = pNewPool; + return pNewPool->m_pLargePage->Alloc(size); +} +size_t CFXMEM_FixedMgr::GetSize(FX_LPVOID p) const +{ + const CFXMEM_Pool *pFind = &m_FirstPool; + do { + if (p > (FX_LPVOID)pFind && p < pFind->m_pLimitPos) { + return pFind->GetSize(p); + } + pFind = pFind->m_pNextPool; + } while (pFind); + return 0; +} +FX_LPVOID CFXMEM_FixedMgr::Alloc(size_t size) +{ + FX_LPVOID p; + if (size <= 32) { + p = AllocSmall(size); + if (p) { + return p; + } + } + if (size <= FX_FIXEDMEM_MIDBLOCKSIZE) { + p = AllocMid(size); + if (p) { + return p; + } + } + p = AllocLarge(size); + return p; +} +FX_LPVOID CFXMEM_FixedMgr::ReallocSmall(CFXMEM_Pool* pPool, FX_LPVOID p, size_t oldSize, size_t newSize) +{ + FX_LPVOID np = AllocSmall(newSize); + if (!np) { + return NULL; + } + FXSYS_memcpy32(np, p, oldSize); + pPool->Free(p); + return np; +} +FX_LPVOID CFXMEM_FixedMgr::Realloc(FX_LPVOID p, size_t newSize) +{ + if (!p) { + return Alloc(newSize); + } + size_t oldSize = 0; + CFXMEM_Pool *pFind = &m_FirstPool; + do { + if (p > (FX_LPVOID)pFind && p < pFind->m_pLimitPos) { + oldSize = pFind->GetSize(p); + if (oldSize >= newSize) { + return p; + } + break; + } + pFind = pFind->m_pNextPool; + } while (pFind); + if (!oldSize || !pFind) { + return Alloc(newSize); + } + FX_LPVOID np = NULL; + if (newSize <= 32) { + np = ReallocSmall(pFind, p, oldSize, newSize); + if (np) { + return np; + } + } + if (newSize <= FX_FIXEDMEM_MIDBLOCKSIZE) { + np = pFind->Realloc(p, oldSize, newSize); + if (np) { + return np; + } + } + np = Alloc(newSize); + if (np) { + FXSYS_memcpy32(np, p, oldSize); + pFind->Free(p); + } + if (pFind->m_bAlone && pFind->IsEmpty()) { + FreePool(pFind); + } + return np; +} +void CFXMEM_FixedMgr::Free(FX_LPVOID p) +{ + CFXMEM_Pool *pFind = &m_FirstPool; + do { + if (p > (FX_LPVOID)pFind && p < pFind->m_pLimitPos) { + pFind->Free(p); + if (pFind->m_bAlone && pFind->IsEmpty()) { + FreePool(pFind); + } + return; + } + pFind = pFind->m_pNextPool; + } while (pFind); +} +void CFXMEM_FixedMgr::FreePool(CFXMEM_Pool* pPool) +{ + FXSYS_assert(pPool->m_bAlone && pPool->IsEmpty()); + FXSYS_assert(m_pExtender != NULL); + CFXMEM_Pool* pPrevPool = pPool->m_pPrevPool; + CFXMEM_Pool* pNextPool = pPool->m_pNextPool; + if (pPrevPool) { + pPrevPool->m_pNextPool = pNextPool; + } + if (pNextPool) { + pNextPool->m_pPrevPool = pPrevPool; + } + m_pExtender->Free(m_pExtender, pPool); +} +void CFXMEM_FixedMgr::FreeAll() +{ + if (!m_pExtender) { + return; + } + CFXMEM_Pool* pPool = m_FirstPool.m_pNextPool; + while (pPool) { + CFXMEM_Pool* pPrevPool = pPool; + pPool = pPool->m_pNextPool; + m_pExtender->Free(m_pExtender, pPrevPool); + } + m_FirstPool.m_pNextPool = NULL; +} +void CFXMEM_FixedMgr::Purge() +{ + if (!m_pExtender) { + return; + } + CFXMEM_Pool* pPool = m_FirstPool.m_pNextPool; + while (pPool) { + CFXMEM_Pool* pNextPool = pPool->m_pNextPool; + if (pPool->IsEmpty()) { + CFXMEM_Pool* pPrevPool = pPool->m_pPrevPool; + pPrevPool->m_pNextPool = pNextPool; + if (pNextPool) { + pNextPool->m_pPrevPool = pPrevPool; + } + m_pExtender->Free(m_pExtender, pPool); + } + pPool = pNextPool; + } +} +extern const FX_BYTE OneLeadPos[256] = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; +extern const FX_BYTE ZeroLeadPos[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, +}; |