[1378] | 1 | #include "dxstdafx.h"
|
---|
| 2 |
|
---|
| 3 | #ifdef WIN32
|
---|
| 4 | #define NOMINMAX
|
---|
| 5 | #include <windows.h>
|
---|
| 6 | #elif LINUX
|
---|
| 7 | #include "string.h"
|
---|
| 8 | #endif
|
---|
| 9 |
|
---|
| 10 | #include <stdio.h>
|
---|
| 11 | #include "NxPhysics.h"
|
---|
| 12 | #include "UserAllocator.h"
|
---|
| 13 |
|
---|
| 14 | #define MEMBLOCKSTART 64
|
---|
| 15 | static const size_t g_pointerMarker = (size_t)0xbadbad00deadbabe;
|
---|
| 16 |
|
---|
| 17 |
|
---|
| 18 | UserAllocator::UserAllocator() : mNbAllocatedBytes(0), mHighWaterMark(0), mTotalNbAllocs(0), mNbAllocs(0), mNbReallocs(0)
|
---|
| 19 | {
|
---|
| 20 | mMemBlockList = NULL;
|
---|
| 21 |
|
---|
| 22 | #ifdef _DEBUG
|
---|
| 23 | //Initialize the Memory blocks list (DEBUG mode only)
|
---|
| 24 | mMemBlockList = (size_t*)::malloc(MEMBLOCKSTART*sizeof(size_t));
|
---|
| 25 | memset(mMemBlockList, 0, MEMBLOCKSTART*sizeof(size_t));
|
---|
| 26 | mMemBlockListSize = MEMBLOCKSTART;
|
---|
| 27 | mMemBlockFirstFree = 0;
|
---|
| 28 | mMemBlockUsed = 0;
|
---|
| 29 | #endif
|
---|
| 30 | }
|
---|
| 31 |
|
---|
| 32 | UserAllocator::~UserAllocator()
|
---|
| 33 | {
|
---|
| 34 | if(mNbAllocatedBytes) printf("Memory leak detected: %d bytes non released\n", mNbAllocatedBytes);
|
---|
| 35 | if(mNbAllocs) printf("Remaining allocs: %d\n", mNbAllocs);
|
---|
| 36 | printf("Nb alloc: %d\n", mTotalNbAllocs);
|
---|
| 37 | printf("Nb realloc: %d\n", mNbReallocs);
|
---|
| 38 | printf("High water mark: %d Kb\n", mHighWaterMark/1024);
|
---|
| 39 |
|
---|
| 40 | #ifdef _DEBUG
|
---|
| 41 | // Scanning for memory leaks
|
---|
| 42 | if(mMemBlockList && mMemBlockUsed)
|
---|
| 43 | {
|
---|
| 44 | NxU32 NbLeaks = 0;
|
---|
| 45 | printf("\n\n ICE Message Memory leaks detected :\n\n");
|
---|
| 46 | NxU32 used = mMemBlockUsed;
|
---|
| 47 | for(NxU32 i=0, j=0; i<used; i++, j++)
|
---|
| 48 | {
|
---|
| 49 | while(!mMemBlockList[j]) j++;
|
---|
| 50 | size_t* cur = (size_t*)mMemBlockList[j];
|
---|
| 51 | printf(" Address 0x%.8X, %d bytes (%s), allocated in: %s(%d):\n\n", cur+6, cur[1], (const char*)cur[5], (const char*)cur[2], cur[3]);
|
---|
| 52 | NbLeaks++;
|
---|
| 53 | // Free(cur+4);
|
---|
| 54 | }
|
---|
| 55 | printf("\n Dump complete (%d leaks)\n\n", NbLeaks);
|
---|
| 56 | }
|
---|
| 57 |
|
---|
| 58 | // Free the Memory Block list
|
---|
| 59 | ::free(mMemBlockList);
|
---|
| 60 | mMemBlockList = NULL;
|
---|
| 61 | #endif
|
---|
| 62 | }
|
---|
| 63 |
|
---|
| 64 | void UserAllocator::reset()
|
---|
| 65 | {
|
---|
| 66 | mNbAllocatedBytes = 0;
|
---|
| 67 | mHighWaterMark = 0;
|
---|
| 68 | mNbAllocs = 0;
|
---|
| 69 | }
|
---|
| 70 |
|
---|
| 71 | void* UserAllocator::malloc(size_t size)
|
---|
| 72 | {
|
---|
| 73 | printf("Obsolete code called!\n");
|
---|
| 74 | return NULL;
|
---|
| 75 | }
|
---|
| 76 |
|
---|
| 77 | void* UserAllocator::malloc(size_t size, NxMemoryType type)
|
---|
| 78 | {
|
---|
| 79 | #ifdef _DEBUG
|
---|
| 80 | return mallocDEBUG(size, NULL, 0, "Undefined", type);
|
---|
| 81 | #endif
|
---|
| 82 |
|
---|
| 83 | if(size == 0)
|
---|
| 84 | {
|
---|
| 85 | printf("Warning: trying to allocate 0 bytes\n");
|
---|
| 86 | return NULL;
|
---|
| 87 | }
|
---|
| 88 |
|
---|
| 89 | void* ptr = (void*)::malloc(size+2*sizeof(size_t));
|
---|
| 90 | mTotalNbAllocs++;
|
---|
| 91 | mNbAllocs++;
|
---|
| 92 |
|
---|
| 93 | size_t* blockStart = (size_t*)ptr;
|
---|
| 94 | blockStart[0] = g_pointerMarker;
|
---|
| 95 | blockStart[1] = size;
|
---|
| 96 |
|
---|
| 97 | mNbAllocatedBytes+=(NxI32)size;
|
---|
| 98 | if(mNbAllocatedBytes>mHighWaterMark) mHighWaterMark = mNbAllocatedBytes;
|
---|
| 99 |
|
---|
| 100 | return ((size_t*)ptr)+2;
|
---|
| 101 | }
|
---|
| 102 |
|
---|
| 103 | void* UserAllocator::mallocDEBUG(size_t size, const char* file, int line)
|
---|
| 104 | {
|
---|
| 105 | printf("Obsolete code called!\n");
|
---|
| 106 | return NULL;
|
---|
| 107 | }
|
---|
| 108 |
|
---|
| 109 | #ifdef _DEBUG
|
---|
| 110 | void* UserAllocator::mallocDEBUG(size_t size, const char* file, int line, const char* className, NxMemoryType type)
|
---|
| 111 | {
|
---|
| 112 | if(size == 0)
|
---|
| 113 | {
|
---|
| 114 | printf("Warning: trying to allocate 0 bytes\n");
|
---|
| 115 | return NULL;
|
---|
| 116 | }
|
---|
| 117 |
|
---|
| 118 | void* ptr = (void*)::malloc(size+6*sizeof(size_t));
|
---|
| 119 | mTotalNbAllocs++;
|
---|
| 120 | mNbAllocs++;
|
---|
| 121 |
|
---|
| 122 | size_t* blockStart = (size_t*)ptr;
|
---|
| 123 | blockStart[0] = g_pointerMarker;
|
---|
| 124 | blockStart[1] = size;
|
---|
| 125 | blockStart[2] = (size_t)file;
|
---|
| 126 | blockStart[3] = line;
|
---|
| 127 |
|
---|
| 128 | mNbAllocatedBytes+=size;
|
---|
| 129 | if(mNbAllocatedBytes>mHighWaterMark) mHighWaterMark = mNbAllocatedBytes;
|
---|
| 130 |
|
---|
| 131 | // Insert the allocated block in the debug memory block list
|
---|
| 132 | if(mMemBlockList)
|
---|
| 133 | {
|
---|
| 134 |
|
---|
| 135 | mMemBlockList[mMemBlockFirstFree] = (size_t)ptr;
|
---|
| 136 | blockStart[4] = mMemBlockFirstFree;
|
---|
| 137 | mMemBlockUsed++;
|
---|
| 138 |
|
---|
| 139 | if(mMemBlockUsed==mMemBlockListSize)
|
---|
| 140 | {
|
---|
| 141 | size_t* tps = (size_t*)::malloc((mMemBlockListSize+MEMBLOCKSTART)*sizeof(size_t));
|
---|
| 142 | memcpy(tps, mMemBlockList, mMemBlockListSize*sizeof(size_t));
|
---|
| 143 | memset((tps+mMemBlockListSize), 0, MEMBLOCKSTART*sizeof(size_t));
|
---|
| 144 | ::free(mMemBlockList);
|
---|
| 145 | mMemBlockList = tps;
|
---|
| 146 | mMemBlockFirstFree = mMemBlockListSize-1;
|
---|
| 147 | mMemBlockListSize += MEMBLOCKSTART;
|
---|
| 148 | }
|
---|
| 149 |
|
---|
| 150 | while(mMemBlockList[++mMemBlockFirstFree] && (mMemBlockFirstFree<mMemBlockListSize));
|
---|
| 151 |
|
---|
| 152 | if(mMemBlockFirstFree==mMemBlockListSize)
|
---|
| 153 | {
|
---|
| 154 | mMemBlockFirstFree = (size_t)-1;
|
---|
| 155 | while(mMemBlockList[++mMemBlockFirstFree] && (mMemBlockFirstFree<mMemBlockListSize));
|
---|
| 156 | }
|
---|
| 157 | }
|
---|
| 158 | else
|
---|
| 159 | {
|
---|
| 160 | blockStart[4] = 0;
|
---|
| 161 | }
|
---|
| 162 |
|
---|
| 163 | blockStart[5] = (size_t)className;
|
---|
| 164 |
|
---|
| 165 | return ((size_t*)ptr)+6;
|
---|
| 166 | }
|
---|
| 167 | #endif
|
---|
| 168 |
|
---|
| 169 | void* UserAllocator::realloc(void* memory, size_t size)
|
---|
| 170 | {
|
---|
| 171 | // return ::realloc(memory, size);
|
---|
| 172 |
|
---|
| 173 | if(memory == NULL)
|
---|
| 174 | {
|
---|
| 175 | printf("Warning: trying to realloc null pointer\n");
|
---|
| 176 | return NULL;
|
---|
| 177 | }
|
---|
| 178 |
|
---|
| 179 | if(size == 0)
|
---|
| 180 | {
|
---|
| 181 | printf("Warning: trying to realloc 0 bytes\n");
|
---|
| 182 | }
|
---|
| 183 |
|
---|
| 184 | #ifdef _DEBUG
|
---|
| 185 |
|
---|
| 186 | size_t* ptr = ((size_t*)memory)-6;
|
---|
| 187 | if(ptr[0]!=g_pointerMarker)
|
---|
| 188 | {
|
---|
| 189 | printf("Error: realloc unknown memory!!\n");
|
---|
| 190 | }
|
---|
| 191 | mNbAllocatedBytes -= ptr[1];
|
---|
| 192 | mNbAllocatedBytes += size;
|
---|
| 193 |
|
---|
| 194 | if(mNbAllocatedBytes>mHighWaterMark) mHighWaterMark = mNbAllocatedBytes;
|
---|
| 195 |
|
---|
| 196 | void* ptr2 = ::realloc(ptr, size+6*sizeof(size_t));
|
---|
| 197 | mNbReallocs++;
|
---|
| 198 | *(((size_t*)ptr2)+1) = size;
|
---|
| 199 | if(ptr==ptr2)
|
---|
| 200 | {
|
---|
| 201 | return memory;
|
---|
| 202 | }
|
---|
| 203 |
|
---|
| 204 | *(((size_t*)ptr2)) = g_pointerMarker;
|
---|
| 205 | *(((size_t*)ptr2)+1) = size;
|
---|
| 206 | *(((size_t*)ptr2)+2) = 0; // File
|
---|
| 207 | *(((size_t*)ptr2)+3) = 0; // Line
|
---|
| 208 |
|
---|
| 209 | NxU32* blockStart = (NxU32*)ptr2;
|
---|
| 210 |
|
---|
| 211 | // Insert the allocated block in the debug memory block list
|
---|
| 212 | if(mMemBlockList)
|
---|
| 213 | {
|
---|
| 214 | mMemBlockList[mMemBlockFirstFree] = (size_t)ptr;
|
---|
| 215 | blockStart[4] = mMemBlockFirstFree;
|
---|
| 216 | mMemBlockUsed++;
|
---|
| 217 | if(mMemBlockUsed==mMemBlockListSize)
|
---|
| 218 | {
|
---|
| 219 | size_t* tps = (size_t*)::malloc((mMemBlockListSize+MEMBLOCKSTART)*sizeof(size_t));
|
---|
| 220 | memcpy(tps, mMemBlockList, mMemBlockListSize*sizeof(size_t));
|
---|
| 221 | memset((tps+mMemBlockListSize), 0, MEMBLOCKSTART*sizeof(size_t));
|
---|
| 222 | ::free(mMemBlockList);
|
---|
| 223 | mMemBlockList = tps;
|
---|
| 224 | mMemBlockFirstFree = mMemBlockListSize-1;
|
---|
| 225 | mMemBlockListSize += MEMBLOCKSTART;
|
---|
| 226 | }
|
---|
| 227 |
|
---|
| 228 | while(mMemBlockList[++mMemBlockFirstFree] && (mMemBlockFirstFree<mMemBlockListSize));
|
---|
| 229 |
|
---|
| 230 | if(mMemBlockFirstFree==mMemBlockListSize)
|
---|
| 231 | {
|
---|
| 232 | mMemBlockFirstFree = (size_t)-1;
|
---|
| 233 | while(mMemBlockList[++mMemBlockFirstFree] && (mMemBlockFirstFree<mMemBlockListSize));
|
---|
| 234 | }
|
---|
| 235 | }
|
---|
| 236 | else
|
---|
| 237 | {
|
---|
| 238 | blockStart[4] = 0;
|
---|
| 239 | }
|
---|
| 240 |
|
---|
| 241 | blockStart[5] = 0; // Classname
|
---|
| 242 |
|
---|
| 243 | return ((size_t*)ptr2)+6;
|
---|
| 244 |
|
---|
| 245 | #else
|
---|
| 246 |
|
---|
| 247 | size_t* ptr = ((size_t*)memory)-2;
|
---|
| 248 | if(ptr[0]!=g_pointerMarker)
|
---|
| 249 | {
|
---|
| 250 | printf("Error: realloc unknown memory!!\n");
|
---|
| 251 | }
|
---|
| 252 |
|
---|
| 253 | mNbAllocatedBytes -= (NxI32)ptr[1];
|
---|
| 254 | mNbAllocatedBytes += (NxI32)size;
|
---|
| 255 |
|
---|
| 256 | if(mNbAllocatedBytes>mHighWaterMark) mHighWaterMark = mNbAllocatedBytes;
|
---|
| 257 |
|
---|
| 258 | void* ptr2 = ::realloc(ptr, size+2*sizeof(size_t));
|
---|
| 259 | mNbReallocs++;
|
---|
| 260 |
|
---|
| 261 | *(((size_t*)ptr2)+1) = size;
|
---|
| 262 | if(ptr == ptr2) return memory;
|
---|
| 263 |
|
---|
| 264 | *(((size_t*)ptr2)) = g_pointerMarker;
|
---|
| 265 | return ((size_t*)ptr2)+2;
|
---|
| 266 | #endif
|
---|
| 267 |
|
---|
| 268 | }
|
---|
| 269 |
|
---|
| 270 | void UserAllocator::free(void* memory)
|
---|
| 271 | {
|
---|
| 272 | if(memory == NULL)
|
---|
| 273 | {
|
---|
| 274 | printf("Warning: trying to free null pointer\n");
|
---|
| 275 | return;
|
---|
| 276 | }
|
---|
| 277 |
|
---|
| 278 | #ifdef _DEBUG
|
---|
| 279 | size_t* ptr = ((size_t*)memory)-6;
|
---|
| 280 | if(ptr[0] != g_pointerMarker)
|
---|
| 281 | {
|
---|
| 282 | printf("Error: free unknown memory!!\n");
|
---|
| 283 | }
|
---|
| 284 | mNbAllocatedBytes -= ptr[1];
|
---|
| 285 | mNbAllocs--;
|
---|
| 286 |
|
---|
| 287 | const char* File = (const char*)ptr[2];
|
---|
| 288 | size_t Line = ptr[3];
|
---|
| 289 | size_t MemBlockFirstFree = ptr[4];
|
---|
| 290 |
|
---|
| 291 | // Remove the block from the Memory block list
|
---|
| 292 | if(mMemBlockList)
|
---|
| 293 | {
|
---|
| 294 | mMemBlockList[MemBlockFirstFree] = 0;
|
---|
| 295 | mMemBlockUsed--;
|
---|
| 296 | }
|
---|
| 297 | #else
|
---|
| 298 | size_t* ptr = ((size_t*)memory)-2;
|
---|
| 299 | if(ptr[0] != g_pointerMarker)
|
---|
| 300 | {
|
---|
| 301 | printf("Error: free unknown memory!!\n");
|
---|
| 302 | }
|
---|
| 303 |
|
---|
| 304 | mNbAllocatedBytes -= (NxI32)ptr[1];
|
---|
| 305 |
|
---|
| 306 | if(mNbAllocatedBytes < 0)
|
---|
| 307 | {
|
---|
| 308 | printf("Oops (%d)\n", ptr[1]);
|
---|
| 309 | }
|
---|
| 310 |
|
---|
| 311 | mNbAllocs--;
|
---|
| 312 | #endif
|
---|
| 313 |
|
---|
| 314 | ptr[0]=g_pointerMarker;
|
---|
| 315 | ptr[1]=0;
|
---|
| 316 | ::free(ptr);
|
---|
| 317 | }
|
---|