Source code of Windows XP (NT5)
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

  1. // MemAlloc.cpp -- Implementations for the memory allocation routines used within Tome
  2. #include "StdAfx.h"
  3. static HANDLE hheap = NULL;
  4. static UINT cAllocs = 0;
  5. static UINT cbAllocated = 0;
  6. static UINT cFrees = 0;
  7. static UINT cbFreed = 0;
  8. // static SYSTEM_INFO si;
  9. static PVOID pvTrap= NULL;
  10. #define HEAP_SIZE_LIMIT 500000
  11. typedef struct _HeapHeader
  12. {
  13. struct _HeapHeader *phhNext;
  14. struct _HeapHeader *phhPrev;
  15. PSZ pszFileWhereAllocated;
  16. UINT iLineWhereAllocated;
  17. UINT cbAllocated;
  18. PVOID pvAllocated;
  19. } HeapHeader, *PHeapHeader;
  20. void * __cdecl operator new(size_t nSize, PSZ pszWhichFile, UINT iWhichLine)
  21. {
  22. return AllocateMemory((UINT) nSize, FALSE, FALSE, pszWhichFile, iWhichLine);
  23. }
  24. void * __cdecl operator new(size_t nSize)
  25. {
  26. RonM_ASSERT(FALSE); // This routine should not be called by the debugging version
  27. // so long as everyone uses the New macro instead of the new
  28. // operator.
  29. return AllocateMemory((UINT) nSize, FALSE, FALSE);
  30. }
  31. void __cdecl operator delete(void *pbData)
  32. {
  33. ReleaseMemory(pbData);
  34. }
  35. #define BOOLEVAL(f) ((f) ? "TRUE" : "FALSE")
  36. static PHeapHeader phhAllocatedChain= NULL;
  37. PVOID AllocateMemory(UINT cb, BOOL fZeroMemory, BOOL fExceptions, PSZ pszWhichFile, UINT iWhichLine)
  38. {
  39. if (hheap == NULL)
  40. {
  41. hheap = GetProcessHeap();
  42. RonM_ASSERT(hheap != NULL);
  43. if (hheap == NULL) return NULL;
  44. // GetSystemInfo(&si);
  45. }
  46. PVOID pv = NULL;
  47. PHeapHeader phh = NULL;
  48. fZeroMemory= TRUE; // for now...
  49. do
  50. {
  51. if (cb <= HEAP_SIZE_LIMIT)
  52. {
  53. UINT fHeapOptions= 0;
  54. if (fZeroMemory) fHeapOptions |= HEAP_ZERO_MEMORY;
  55. RonM_ASSERT(HeapValidate(hheap, 0, NULL));
  56. pv= (PVOID) HeapAlloc(hheap, fHeapOptions, cb + sizeof(HeapHeader));
  57. }
  58. else
  59. pv= VirtualAlloc(NULL, cb + sizeof(HeapHeader), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
  60. if (pv)
  61. {
  62. phh= (PHeapHeader) pv;
  63. pv= PVOID(phh + 1);
  64. }
  65. else
  66. {
  67. if (fExceptions)
  68. RaiseException(STATUS_NO_MEMORY, EXCEPTION_NONCONTINUABLE, 0, NULL);
  69. else return NULL;
  70. }
  71. } while (pv == NULL); // Don't leave unhappy
  72. #ifdef _DEBUG
  73. phh->pszFileWhereAllocated = pszWhichFile;
  74. phh-> iLineWhereAllocated = iWhichLine;
  75. phh-> cbAllocated = cb;
  76. phh-> pvAllocated = pv;
  77. phh-> phhNext = phhAllocatedChain;
  78. phh-> phhPrev = NULL;
  79. if (phhAllocatedChain) phhAllocatedChain->phhPrev= phh;
  80. phhAllocatedChain= phh;
  81. ++cAllocs;
  82. cbAllocated += cb;
  83. if (pvTrap) RonM_ASSERT(pv != pvTrap);
  84. #else // _DEBUG
  85. phh->cbAllocated= cb;
  86. #endif // _DEBUG
  87. return pv;
  88. }
  89. PVOID AllocateMemory(UINT cb, BOOL fZeroMemory, BOOL fExceptions)
  90. {
  91. if (hheap == NULL)
  92. {
  93. hheap = GetProcessHeap();
  94. RonM_ASSERT(hheap != NULL);
  95. if (hheap == NULL) return NULL;
  96. }
  97. PVOID pv = NULL;
  98. PHeapHeader phh = NULL;
  99. fZeroMemory= TRUE; // for now...
  100. do
  101. {
  102. if (cb <= HEAP_SIZE_LIMIT)
  103. {
  104. UINT fHeapOptions= 0;
  105. if (fZeroMemory) fHeapOptions |= HEAP_ZERO_MEMORY;
  106. RonM_ASSERT(HeapValidate(hheap, 0, NULL));
  107. pv= (PVOID) HeapAlloc(hheap, fHeapOptions, cb + sizeof(HeapHeader));
  108. }
  109. else
  110. pv= VirtualAlloc(NULL, cb + sizeof(HeapHeader), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
  111. if (pv)
  112. {
  113. phh= (PHeapHeader) pv;
  114. pv= PVOID(phh + 1);
  115. }
  116. else
  117. {
  118. if (fExceptions)
  119. RaiseException(STATUS_NO_MEMORY, EXCEPTION_NONCONTINUABLE, 0, NULL);
  120. else return NULL;
  121. }
  122. } while (pv == NULL); // Don't leave unhappy
  123. phh->cbAllocated= cb;
  124. return pv;
  125. }
  126. #ifdef _DEBUG
  127. void ValidateHeap()
  128. {
  129. RonM_ASSERT(HeapValidate(hheap, 0, NULL));
  130. }
  131. #endif // _DEBUG
  132. void ReleaseMemory(PVOID pv)
  133. {
  134. RonM_ASSERT(HeapValidate(hheap, 0, NULL));
  135. PHeapHeader phh= PHeapHeader(pv) - 1;
  136. RonM_ASSERT(phh->pvAllocated == pv);
  137. #ifdef _DEBUG
  138. if (phh->phhNext) phh->phhNext->phhPrev = phh->phhPrev;
  139. if (phh->phhPrev) phh->phhPrev->phhNext = phh->phhNext;
  140. else phhAllocatedChain = phh->phhNext;
  141. #endif // _DEBUG
  142. pv= PVOID(phh);
  143. UINT cb= phh->cbAllocated;
  144. cbFreed+= cb;
  145. ++cFrees;
  146. if (cb <= HEAP_SIZE_LIMIT) HeapFree(hheap, 0, pv);
  147. else VirtualFree(pv, 0, MEM_RELEASE);
  148. RonM_ASSERT(HeapValidate(hheap, 0, NULL));
  149. }
  150. #ifdef _DEBUG
  151. void DumpResidualAllocations()
  152. {
  153. char acDebugBuff[256];
  154. wsprintf(acDebugBuff, "%u Orphan Allocations (%u byte total):\n", cAllocs - cFrees, cbAllocated - cbFreed);
  155. OutputDebugString(acDebugBuff);
  156. UINT iOrphan= 0;
  157. for (PHeapHeader phh= phhAllocatedChain; phh; phh= phh->phhNext)
  158. {
  159. wsprintf(acDebugBuff,
  160. " [%u]: %10u Bytes @ 0x%08x Allocated in %s[%u]\n", iOrphan++,
  161. phh->cbAllocated, UINT_PTR(phh->pvAllocated),
  162. phh->pszFileWhereAllocated,
  163. phh->iLineWhereAllocated
  164. );
  165. OutputDebugString(acDebugBuff);
  166. }
  167. }
  168. #endif _DEBUG
  169. void LiberateHeap()
  170. {
  171. if (hheap == NULL) return;
  172. #ifdef _DEBUG
  173. if (phhAllocatedChain) DumpResidualAllocations();
  174. #endif // _DEBUG
  175. // BOOL fDone= HeapDestroy(hheap);
  176. #ifdef _DEBUG
  177. UINT iReason= GetLastError();
  178. #endif // _DEBUG
  179. // RonM_ASSERT(fDone);
  180. hheap = NULL;
  181. }