mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
269 lines
5.8 KiB
269 lines
5.8 KiB
// MemAlloc.cpp -- Implementations for the memory allocation routines used within Tome
|
|
|
|
#include "StdAfx.h"
|
|
|
|
static HANDLE hheap = NULL;
|
|
static UINT cAllocs = 0;
|
|
static UINT cbAllocated = 0;
|
|
static UINT cFrees = 0;
|
|
static UINT cbFreed = 0;
|
|
|
|
|
|
// static SYSTEM_INFO si;
|
|
|
|
static PVOID pvTrap= NULL;
|
|
|
|
#define HEAP_SIZE_LIMIT 500000
|
|
|
|
typedef struct _HeapHeader
|
|
{
|
|
struct _HeapHeader *phhNext;
|
|
struct _HeapHeader *phhPrev;
|
|
|
|
PSZ pszFileWhereAllocated;
|
|
UINT iLineWhereAllocated;
|
|
UINT cbAllocated;
|
|
PVOID pvAllocated;
|
|
|
|
} HeapHeader, *PHeapHeader;
|
|
|
|
|
|
void * __cdecl operator new(size_t nSize, PSZ pszWhichFile, UINT iWhichLine)
|
|
{
|
|
return AllocateMemory((UINT) nSize, FALSE, FALSE, pszWhichFile, iWhichLine);
|
|
}
|
|
|
|
void * __cdecl operator new(size_t nSize)
|
|
{
|
|
RonM_ASSERT(FALSE); // This routine should not be called by the debugging version
|
|
// so long as everyone uses the New macro instead of the new
|
|
// operator.
|
|
|
|
return AllocateMemory((UINT) nSize, FALSE, FALSE);
|
|
}
|
|
|
|
void __cdecl operator delete(void *pbData)
|
|
{
|
|
ReleaseMemory(pbData);
|
|
}
|
|
|
|
#define BOOLEVAL(f) ((f) ? "TRUE" : "FALSE")
|
|
|
|
static PHeapHeader phhAllocatedChain= NULL;
|
|
|
|
PVOID AllocateMemory(UINT cb, BOOL fZeroMemory, BOOL fExceptions, PSZ pszWhichFile, UINT iWhichLine)
|
|
{
|
|
if (hheap == NULL)
|
|
{
|
|
hheap = GetProcessHeap();
|
|
|
|
RonM_ASSERT(hheap != NULL);
|
|
|
|
if (hheap == NULL) return NULL;
|
|
// GetSystemInfo(&si);
|
|
}
|
|
|
|
PVOID pv = NULL;
|
|
PHeapHeader phh = NULL;
|
|
|
|
fZeroMemory= TRUE; // for now...
|
|
|
|
do
|
|
{
|
|
if (cb <= HEAP_SIZE_LIMIT)
|
|
{
|
|
|
|
UINT fHeapOptions= 0;
|
|
|
|
if (fZeroMemory) fHeapOptions |= HEAP_ZERO_MEMORY;
|
|
|
|
RonM_ASSERT(HeapValidate(hheap, 0, NULL));
|
|
|
|
pv= (PVOID) HeapAlloc(hheap, fHeapOptions, cb + sizeof(HeapHeader));
|
|
|
|
}
|
|
else
|
|
pv= VirtualAlloc(NULL, cb + sizeof(HeapHeader), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
|
|
|
if (pv)
|
|
{
|
|
phh= (PHeapHeader) pv;
|
|
|
|
pv= PVOID(phh + 1);
|
|
}
|
|
else
|
|
{
|
|
if (fExceptions)
|
|
RaiseException(STATUS_NO_MEMORY, EXCEPTION_NONCONTINUABLE, 0, NULL);
|
|
else return NULL;
|
|
}
|
|
} while (pv == NULL); // Don't leave unhappy
|
|
|
|
#ifdef _DEBUG
|
|
|
|
phh->pszFileWhereAllocated = pszWhichFile;
|
|
phh-> iLineWhereAllocated = iWhichLine;
|
|
phh-> cbAllocated = cb;
|
|
phh-> pvAllocated = pv;
|
|
phh-> phhNext = phhAllocatedChain;
|
|
phh-> phhPrev = NULL;
|
|
|
|
if (phhAllocatedChain) phhAllocatedChain->phhPrev= phh;
|
|
|
|
phhAllocatedChain= phh;
|
|
|
|
++cAllocs;
|
|
cbAllocated += cb;
|
|
|
|
if (pvTrap) RonM_ASSERT(pv != pvTrap);
|
|
|
|
#else // _DEBUG
|
|
|
|
phh->cbAllocated= cb;
|
|
|
|
#endif // _DEBUG
|
|
|
|
return pv;
|
|
}
|
|
|
|
PVOID AllocateMemory(UINT cb, BOOL fZeroMemory, BOOL fExceptions)
|
|
{
|
|
if (hheap == NULL)
|
|
{
|
|
hheap = GetProcessHeap();
|
|
|
|
RonM_ASSERT(hheap != NULL);
|
|
|
|
if (hheap == NULL) return NULL;
|
|
}
|
|
|
|
PVOID pv = NULL;
|
|
PHeapHeader phh = NULL;
|
|
|
|
fZeroMemory= TRUE; // for now...
|
|
|
|
do
|
|
{
|
|
if (cb <= HEAP_SIZE_LIMIT)
|
|
{
|
|
|
|
UINT fHeapOptions= 0;
|
|
|
|
if (fZeroMemory) fHeapOptions |= HEAP_ZERO_MEMORY;
|
|
|
|
RonM_ASSERT(HeapValidate(hheap, 0, NULL));
|
|
|
|
pv= (PVOID) HeapAlloc(hheap, fHeapOptions, cb + sizeof(HeapHeader));
|
|
|
|
}
|
|
else
|
|
pv= VirtualAlloc(NULL, cb + sizeof(HeapHeader), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
|
|
|
if (pv)
|
|
{
|
|
phh= (PHeapHeader) pv;
|
|
|
|
pv= PVOID(phh + 1);
|
|
}
|
|
else
|
|
{
|
|
if (fExceptions)
|
|
RaiseException(STATUS_NO_MEMORY, EXCEPTION_NONCONTINUABLE, 0, NULL);
|
|
else return NULL;
|
|
}
|
|
} while (pv == NULL); // Don't leave unhappy
|
|
|
|
phh->cbAllocated= cb;
|
|
|
|
return pv;
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
|
|
void ValidateHeap()
|
|
{
|
|
RonM_ASSERT(HeapValidate(hheap, 0, NULL));
|
|
}
|
|
|
|
#endif // _DEBUG
|
|
|
|
void ReleaseMemory(PVOID pv)
|
|
{
|
|
RonM_ASSERT(HeapValidate(hheap, 0, NULL));
|
|
|
|
PHeapHeader phh= PHeapHeader(pv) - 1;
|
|
|
|
RonM_ASSERT(phh->pvAllocated == pv);
|
|
|
|
#ifdef _DEBUG
|
|
|
|
if (phh->phhNext) phh->phhNext->phhPrev = phh->phhPrev;
|
|
if (phh->phhPrev) phh->phhPrev->phhNext = phh->phhNext;
|
|
else phhAllocatedChain = phh->phhNext;
|
|
|
|
#endif // _DEBUG
|
|
|
|
pv= PVOID(phh);
|
|
|
|
UINT cb= phh->cbAllocated;
|
|
|
|
cbFreed+= cb;
|
|
|
|
++cFrees;
|
|
|
|
if (cb <= HEAP_SIZE_LIMIT) HeapFree(hheap, 0, pv);
|
|
else VirtualFree(pv, 0, MEM_RELEASE);
|
|
|
|
RonM_ASSERT(HeapValidate(hheap, 0, NULL));
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
|
|
void DumpResidualAllocations()
|
|
{
|
|
char acDebugBuff[256];
|
|
|
|
wsprintf(acDebugBuff, "%u Orphan Allocations (%u byte total):\n", cAllocs - cFrees, cbAllocated - cbFreed);
|
|
|
|
OutputDebugString(acDebugBuff);
|
|
|
|
UINT iOrphan= 0;
|
|
|
|
for (PHeapHeader phh= phhAllocatedChain; phh; phh= phh->phhNext)
|
|
{
|
|
wsprintf(acDebugBuff,
|
|
" [%u]: %10u Bytes @ 0x%08x Allocated in %s[%u]\n", iOrphan++,
|
|
phh->cbAllocated, UINT_PTR(phh->pvAllocated),
|
|
phh->pszFileWhereAllocated,
|
|
phh->iLineWhereAllocated
|
|
);
|
|
|
|
OutputDebugString(acDebugBuff);
|
|
}
|
|
}
|
|
|
|
#endif _DEBUG
|
|
|
|
void LiberateHeap()
|
|
{
|
|
if (hheap == NULL) return;
|
|
|
|
#ifdef _DEBUG
|
|
|
|
if (phhAllocatedChain) DumpResidualAllocations();
|
|
|
|
#endif // _DEBUG
|
|
|
|
// BOOL fDone= HeapDestroy(hheap);
|
|
|
|
#ifdef _DEBUG
|
|
|
|
UINT iReason= GetLastError();
|
|
|
|
#endif // _DEBUG
|
|
|
|
// RonM_ASSERT(fDone);
|
|
|
|
hheap = NULL;
|
|
}
|
|
|