hkStlDebugMemory.h
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:22k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /* 
  2.  * 
  3.  * Confidential Information of Telekinesys Research Limited (t/a Havok). Not for disclosure or distribution without Havok's
  4.  * prior written consent. This software contains code, techniques and know-how which is confidential and proprietary to Havok.
  5.  * Level 2 and Level 3 source code contains trade secrets of Havok. Havok Software (C) Copyright 1999-2009 Telekinesys Research Limited t/a Havok. All Rights Reserved. Use of this software is subject to the terms of an end user license agreement.
  6.  * 
  7.  */
  8. // The demoframework will use hkStlDebugMemory if the demos project properties
  9. // is given the "-c" (mem Check) option in 'Debugging->Command Arguments'.
  10. // hkStlDebugMemory will not operate in debug configuration as defined by Havok.
  11. // Debug configuration is an optimized build with line numbers enabled.
  12. // If there are memory leaks, their location and call stack
  13. // are printed to the debug window.
  14. #ifndef HK_STL_DEBUG_MEMORY_H
  15. #define HK_STL_DEBUG_MEMORY_H
  16. #include <Common/Base/Memory/Memory/hkMemory.h>
  17. #include <Common/Base/Memory/StackTracer/hkStackTracer.h>
  18. #include <Common/Base/Thread/CriticalSection/hkCriticalSection.h>
  19. #include <Common/Base/Memory/Memory/Debug/hkDebugMemory.h>
  20. #include <Common/Base/Memory/hkDebugMemorySnapshot.h>
  21. // use STL here so we avoid memory recursion.
  22. #include <map>
  23. #if defined(HK_PLATFORM_PS3_PPU) && (_HAS_EXCEPTIONS==0) && HK_CELL_SDK_VERSION < 0x190002
  24. void std::exception::_Raise() const { HK_BREAKPOINT(0); }
  25. #endif
  26. # define PTR_CLASS _FARQ
  27. template <typename T>
  28. class hkAllocator : public std::allocator<T>
  29. {
  30. public:
  31. hkAllocator() {}
  32. template <typename U> hkAllocator(const hkAllocator<U>&) {};
  33. char PTR_CLASS * _Charalloc(size_t size)
  34. {
  35. return (char PTR_CLASS *)malloc( size );
  36. }
  37. T PTR_CLASS * allocate(size_t count)
  38. {
  39. return (T PTR_CLASS *)malloc( count * sizeof(T) );
  40. }
  41. void deallocate(void PTR_CLASS * ptr, size_t )
  42. {
  43. free(ptr);
  44. }
  45. template <typename U>
  46. struct rebind { typedef hkAllocator<U> other; };
  47. };
  48. class hkDebugMemorySnapshot;
  49. /// Memory implementation to find common memory problems.
  50. /// hkStlDebugMemory finds leaks, multiple frees and underrun/overruns.
  51. /// hkStlDebugMemory always scrubs allocations in contrast to hkPoolMemory
  52. /// which only scrubs when HK_DEBUG is defined.
  53. /// See the userguide for more details.<p>
  54. class hkStlDebugMemory : public hkDebugMemory
  55. {
  56. public:
  57. typedef void (HK_CALL *OutputStringFunc)(const char* s, void* arg);
  58. static void HK_CALL defaultOutputStringFunc(const char* s, void* a);
  59. virtual void allocateChunkBatch(void** blocksOut, int nblocks, int nbytes,HK_MEMORY_CLASS cl )
  60. {
  61. for( int i = 0; i < nblocks; ++i )
  62. {
  63. blocksOut[i] = allocateChunk(nbytes, cl);
  64. }
  65. }
  66. virtual void deallocateChunkBatch(void** blocks, int nblocks, int nbytes,HK_MEMORY_CLASS cl )
  67. {
  68. for( int i = 0; i < nblocks; ++i )
  69. {
  70. deallocateChunk(blocks[i], nbytes, cl);
  71. }
  72. }
  73.         hkStlDebugMemory( OutputStringFunc outFunc = defaultOutputStringFunc, void* funcArg = HK_NULL, hkUint32 maxStackTrace = MAX_STACKTRACE);
  74.         ~hkStlDebugMemory();
  75. virtual void* allocateChunk(int nbytes, HK_MEMORY_CLASS cl);
  76. virtual void deallocateChunk(void*, int nbytes, HK_MEMORY_CLASS );
  77. virtual void preAllocateRuntimeBlock(int nbytes, HK_MEMORY_CLASS cl);
  78. virtual void* allocateRuntimeBlock(int nbytes, HK_MEMORY_CLASS cl);
  79. virtual void deallocateRuntimeBlock(void*, int nbytes, HK_MEMORY_CLASS cl);
  80. virtual void provideRuntimeBlock(void*, int nbytes, HK_MEMORY_CLASS cl);
  81. virtual void registerStaticAddress(void*, int nbytes);
  82. virtual void freeRuntimeBlocks();
  83. virtual void printStatistics(hkOstream* c);
  84. virtual hkBool isOk() const;
  85. virtual void* findBaseAddress(void* p, int nbytes);
  86. virtual void lockBlock(void* p);
  87. virtual void unlockBlock(void* p);
  88.         virtual void calculateStatistics(hkMemoryStatistics& stats);
  89.         virtual hkBool hasMemoryAvailable(hk_size_t size);
  90. virtual void setMaxStackTraceDepth(int maxDepth);
  91.         virtual void setLimitedMemoryListener(hkLimitedMemoryListener* listener)
  92.         {
  93.             hkCriticalSectionLock lock( &m_section );
  94.             m_listener = listener;
  95.         }
  96.         virtual hkLimitedMemoryListener* getLimitedMemoryListener() { return m_listener; }
  97.         virtual void setMemoryHardLimit(hk_size_t maxMemory)
  98.         {
  99.             hkCriticalSectionLock lock( &m_section );
  100.             if (maxMemory==0)
  101.             {
  102.                 m_hardLimit = maxMemory;
  103.                 return;
  104.             }
  105.             HK_ASSERT(0x3423434,!(maxMemory < hk_size_t(m_sysAllocsSize)));
  106.             if (maxMemory < hk_size_t(m_sysAllocsSize)) { return; }
  107.             HK_ASSERT(0x3423434,!(m_softLimit!=0&&maxMemory<m_softLimit));
  108.             if (m_softLimit!=0&&maxMemory<m_softLimit) { return; }
  109.             m_hardLimit = maxMemory;
  110.         }
  111.         virtual hk_size_t getMemoryHardLimit() { return m_hardLimit; }
  112.         virtual void setMemorySoftLimit(hk_size_t maxMemory)
  113.         {
  114.             hkCriticalSectionLock lock( &m_section );
  115.             if (maxMemory==0)
  116.             {
  117.                 m_softLimit = 0;
  118.                 return;
  119.             }
  120.             HK_ASSERT(0x3424344,!(m_hardLimit && maxMemory > m_hardLimit));
  121.             if (m_hardLimit && maxMemory > m_hardLimit) { return; }
  122.             m_softLimit = maxMemory;
  123.         }
  124.         virtual hk_size_t getMemorySoftLimit() { return m_softLimit; }
  125. protected:
  126. void printMemoryReport();
  127. virtual void* internalAllocate(int nbytes, HK_MEMORY_CLASS, int flags, int alignment=16);
  128. virtual void internalFree(void* p, int bytesToFree, int flags);
  129. void outputString(const char* s)
  130. {
  131. (*m_outputStringFunc)(s, m_outputStringArg);
  132. }
  133. public:
  134.             /// Overriding hkDebugMemory
  135.         virtual void setAllocationMark(int mark);
  136.         virtual int getAllocationMark() { return m_mark; }
  137.         virtual void getSnapshot(int mark,hkBool mask,hkDebugMemorySnapshot& snapshot);
  138.         virtual hkBool getPointerInfo(const void* ptr,PointerInfo& out);
  139. #if defined ( HK_PLATFORM_WIN32 ) && (HK_COMPILER_MSVC_VERSION >= 1400)
  140. typedef std::map<void*, PointerInfo, std::less<void*>, hkAllocator< std::pair <const void*, PointerInfo> > > Map;
  141. #else
  142. typedef std::map<void*, PointerInfo, std::less<void*> > Map;
  143. #endif
  144. protected:
  145. Map m_activePointers;
  146. OutputStringFunc m_outputStringFunc;
  147. void* m_outputStringArg;
  148. hkUint32 m_maxStackTrace;
  149. hkStackTracer m_tracer;
  150. mutable hkCriticalSection m_section;
  151.         int m_mark;
  152.         /// All the statistics of the same style as the old stats collector
  153.         int m_numSysAllocs;
  154.             /// The total number of bytes allocated by the system memory
  155.         int m_sysAllocsSize;
  156.             /// The current maximum of the total number of bytes allocated by the system memory
  157.         int m_sysAllocsHighMark;
  158.             /// The limited memory listener
  159.         hkLimitedMemoryListener* m_listener;
  160.             /// The total amount of memory we're allowing allocation on
  161.         hk_size_t m_softLimit;
  162.         hk_size_t m_hardLimit;
  163. };
  164. /// The implementation.
  165. /// The reason this is not inside of a .cpp file is so that there isn't a dependency in the lib with STL, which is
  166. /// what the implementation uses for block tracking.
  167. hkStlDebugMemory::hkStlDebugMemory( OutputStringFunc func, void* arg, hkUint32 maxStackTrace) :
  168. m_outputStringFunc(func),
  169. m_outputStringArg(arg),
  170. m_maxStackTrace(maxStackTrace),
  171.     m_section(0),
  172.     m_mark(0),
  173.     m_listener(HK_NULL),
  174.     m_softLimit(0),
  175.     m_hardLimit(0)
  176. {
  177.     m_numSysAllocs =0 ;
  178.     m_sysAllocsSize = 0;
  179.     m_sysAllocsHighMark = 0;
  180. }
  181. hkStlDebugMemory::~hkStlDebugMemory()
  182. {
  183. printMemoryReport();
  184. }
  185. void hkStlDebugMemory::setMaxStackTraceDepth(int maxDepth)
  186. {
  187. m_maxStackTrace = maxDepth;
  188. }
  189. hkBool
  190. hkStlDebugMemory::hasMemoryAvailable(hk_size_t size)
  191. {
  192.     hk_size_t limit = m_softLimit?m_softLimit:m_hardLimit;
  193.     if (limit == 0) return true;
  194.         /// Consider 4k as the minimum memory workspace
  195.     if (size ==0) size = 4*1024;
  196.     hk_size_t remaining = limit - m_sysAllocsSize;
  197. return size<remaining;
  198. }
  199. void
  200. hkStlDebugMemory::calculateStatistics(hkMemoryStatistics& stats)
  201. {
  202.     stats.m_allocated = m_sysAllocsSize;
  203.     stats.m_used = m_sysAllocsSize;
  204. // <js.todo.a use :: stylee
  205.     stats.m_available = stats.INFINITE_SIZE;
  206.     stats.m_totalAvailable = stats.INFINITE_SIZE;
  207. stats.m_largestBlock = stats.INFINITE_SIZE;
  208.     if (m_hardLimit != 0)
  209. {
  210.         stats.m_available = m_hardLimit - m_sysAllocsSize;
  211.         stats.m_totalAvailable = m_hardLimit - m_sysAllocsSize;
  212.         stats.m_largestBlock = m_hardLimit - m_sysAllocsSize;
  213. }
  214. }
  215. void // <js.todo.aaa change mask into enum and make it first parameter
  216. hkStlDebugMemory::getSnapshot( int mark, hkBool mask, hkDebugMemorySnapshot& snapshot )
  217. {
  218. hkCriticalSectionLock lock( &m_section );
  219.     snapshot.reset();
  220.     int numAllocs = 0;
  221. // Determine how many pointers pass the mark/mask filter.
  222. const hkStlDebugMemory::Map::iterator m_activePointersEnd = m_activePointers.end();
  223. if( mask && ( mark == 0 ) )
  224. {
  225. // If the mark is a mask with no bits set (0x0000), then all pointers pass the filter.
  226. numAllocs = int(m_activePointers.size());
  227. }
  228. else
  229. {
  230. // Gotta count them manually.
  231. for( hkStlDebugMemory::Map::iterator i = m_activePointers.begin(); i != m_activePointersEnd; ++i )
  232. {
  233. PointerInfo& inInfo = i->second;
  234. if (mask)
  235. {
  236. if (mark == 0 || (mark & inInfo.mark) !=0 ) numAllocs++;
  237. }
  238. else
  239. {
  240. if (inInfo.mark == mark) numAllocs++;
  241. }
  242. }
  243. }
  244. // If we have no objects to report, we're done
  245. if( numAllocs == 0 )
  246. {
  247. return;
  248. }
  249.     // Allocate the memory
  250.     snapshot.m_size = numAllocs;
  251.     snapshot.m_info = (PointerInfo*)hkSystemMalloc(sizeof(PointerInfo)*numAllocs,16);
  252.     snapshot.m_pointers = (void**)hkSystemMalloc(sizeof(void*)*numAllocs,16);
  253. // Fill up the records
  254. PointerInfo* outInfo = snapshot.m_info;
  255. void** ptr = snapshot.m_pointers;
  256.     for( hkStlDebugMemory::Map::iterator i = m_activePointers.begin(); i != m_activePointersEnd; ++i )
  257.     {
  258. PointerInfo& inInfo = i->second;
  259.         if (mask)
  260.         {
  261.             if (mark != 0 && (mark & inInfo.mark)==0) 
  262. {
  263. continue;
  264. }
  265.         }
  266.         else
  267.         {
  268.             if (inInfo.mark != mark) 
  269. {
  270. continue;
  271. }
  272.         }
  273.         *ptr = i->first;
  274.         *outInfo = i->second;
  275. outInfo++;
  276. ptr++;
  277.     }
  278. HK_ASSERT2( 0xdafec31b, outInfo == ( snapshot.m_info + snapshot.m_size ), "Allocated the wrong number of pointer info records." );
  279. }
  280. hkBool
  281. hkStlDebugMemory::getPointerInfo(const void* ptrIn,PointerInfo& out)
  282. {
  283. hkCriticalSectionLock lock( &m_section );
  284. void* ptr = const_cast<void*>(ptrIn);
  285.     hkStlDebugMemory::Map::iterator i = m_activePointers.find(ptr);
  286.     if ( i != m_activePointers.end())
  287.     {
  288.         out = i->second;
  289.         return true;
  290.     }
  291.     return false;
  292. }
  293. void hkStlDebugMemory::printMemoryReport()
  294. {
  295. hkCriticalSectionLock lock( &m_section );
  296. if( m_activePointers.size() != 0)
  297. {
  298.         hkStlDebugMemory::Map::iterator i = m_activePointers.begin();
  299.         hkStlDebugMemory::Map::iterator e = m_activePointers.end();
  300. outputString("**************************************************************n");
  301. outputString("* BEGIN MEMORY LEAK REPORT                                   *n");
  302. outputString("**************************************************************n");
  303. for( ; i!=e; ++i)
  304. {
  305. const PointerInfo& pinfo = i->second;
  306. char buf[256];
  307. hkString::snprintf(buf, 256, "n%i bytes leaked. Data at 0x%p. Stack trace follows:n", pinfo.numBytes, i->first );
  308. outputString(buf);
  309. // skip first two frames - they are always allocateX/internalAllocate
  310. m_tracer.dumpStackTrace( pinfo.stackTraces + 2, pinfo.numStackTrace - 2, m_outputStringFunc, m_outputStringArg );
  311. }
  312. outputString("**************************************************************n");
  313. outputString("* END MEMORY LEAK REPORT                                     *n");
  314. outputString("**************************************************************n");
  315. }
  316. else
  317. {
  318. outputString("**************************************************************n");
  319. outputString("* NO HAVOK MEMORY LEAKS FOUND                                *n");
  320. outputString("**************************************************************n");
  321. }
  322. }
  323. void hkStlDebugMemory::printStatistics(hkOstream* c)
  324. {
  325. hkCriticalSectionLock lock( &m_section );
  326. if(c)
  327. {
  328. c->printf("n");
  329. c->printf("************************************************************************************** *n");
  330. c->printf("* Debug memory doesn't support memory classes. Therefore no statistics available here. *n");
  331. c->printf("************************************************************************************** *n");
  332. c->printf("n");
  333. }
  334. }
  335. static void HK_CALL checkUnderOverrun(void* pfree, const hkDebugMemory::PointerInfo& info)
  336. {
  337. hkUint8* check = static_cast<hkUint8*>(info.realMem);
  338. int prepadBytes = (int)hkUlong( static_cast<char*>(pfree) - static_cast<char*>(info.realMem) );
  339. int i;
  340. for( i = 0; i < prepadBytes; ++i )
  341. {
  342. HK_ASSERT(0x6af0c498, check[i] == hkMemory::s_fillGuardArea);
  343. }
  344. check += prepadBytes + info.numBytes;
  345.     for( i = 0; i < hkStlDebugMemory::MEMORY_PADDING; ++i )
  346. {
  347. HK_ASSERT(0x431a98ae, check[i] == hkMemory::s_fillGuardArea);
  348. }
  349. }
  350. void hkStlDebugMemory::setAllocationMark(int mark)
  351. {
  352.     hkCriticalSectionLock lock( &m_section );
  353.     m_mark = mark;
  354. }
  355. void* hkStlDebugMemory::internalAllocate(int nbytes, HK_MEMORY_CLASS, int flags, int alignment )
  356. {
  357. if( nbytes )
  358. {
  359. hkCriticalSectionLock lock( &m_section );
  360.         if (m_hardLimit&&m_sysAllocsSize + hk_size_t(nbytes) > m_hardLimit)
  361.         {
  362.                 /// Say we can't allocate
  363.             if (m_listener)
  364.             {
  365.                 m_listener->cannotAllocate(this,nbytes);
  366.                 /// See if the callback helped... if not we fail
  367.                 if (m_sysAllocsSize + hk_size_t(nbytes) > m_hardLimit)
  368.                 {
  369.                     /// Inform we failed
  370.                     m_listener->allocationFailure(this,nbytes);
  371.                     /// Return NULL
  372.                     return HK_NULL;
  373.                 }
  374.             }
  375.             else
  376.             {
  377.                 // We failed
  378.                 return HK_NULL;
  379.             }
  380.         }
  381. PointerInfo pointerinfo;
  382. pointerinfo.numStackTrace = m_tracer.getStackTrace(pointerinfo.stackTraces, m_maxStackTrace);
  383. pointerinfo.numBytes = nbytes;
  384. pointerinfo.flags = flags;
  385.         pointerinfo.mark = m_mark;
  386. HK_ASSERT( 0x1be63280, MEMORY_PADDING >= 4 );
  387. HK_ASSERT( 0x1be63281, (MEMORY_PADDING % sizeof(int)) == 0 );
  388. HK_ASSERT( 0x1be63282, (alignment % sizeof(int)) == 0 );
  389. // allocate a little more (MEMORY_PADDING) at each end
  390. hk_size_t postpad = MEMORY_PADDING;
  391. // if alignment greater than padding is requested we need to be careful
  392. hk_size_t prepad = (MEMORY_PADDING >= alignment) ? MEMORY_PADDING : alignment;
  393. pointerinfo.realMem = hkSystemMalloc( int(nbytes + prepad + postpad), alignment);
  394. char* realMem = static_cast<char*>(pointerinfo.realMem);
  395. // scrub memory
  396. hkString::memSet( realMem, s_fillGuardArea, int(prepad) );
  397. hkString::memSet( realMem + prepad, s_fillReturnedToUser, nbytes );
  398. hkString::memSet( realMem + prepad + nbytes, s_fillGuardArea, int(postpad) );
  399. //
  400. /////
  401. //char* start = realMem + prepad;
  402. //char* end   = start + nbytes;
  403. //char* start4 = (char*)HK_NEXT_MULTIPLE_OF(4, hkUlong(start));
  404. //char* end4   = (char*)HK_NEXT_MULTIPLE_OF(4, hkUlong(end+1)) - 4;
  405. //start4 = hkMath::min2(start4, end);
  406. //end4   = hkMath::max2(end4, start);
  407. //HK_ASSERT2(0xad8750dd, (start4 <= end4) ^ ((hkUlong(start4) & 0x3) || (hkUlong(end4) & 0x3)), "Hmm");
  408. //if (start4 <= end4)
  409. //{
  410. // hkString::memSet(start, s_fillReturnedToUser, start4-start);
  411. // hkReal max = HK_REAL_MAX; or use nans
  412. // hkString::memSet4(start4, (int&)(max), (end4-start4)>>2);
  413. // hkString::memSet(end4, s_fillReturnedToUser, end-end4);
  414. //}
  415. //else
  416. //{
  417. // hkString::memSet( realMem + prepad, s_fillReturnedToUser, nbytes );
  418. //}
  419. /////
  420. void* memory = realMem + prepad;
  421. m_activePointers[memory] = pointerinfo;
  422. m_numSysAllocs += 1;
  423. m_sysAllocsSize += nbytes;
  424. if( m_sysAllocsSize > m_sysAllocsHighMark )
  425. {
  426. m_sysAllocsHighMark = m_sysAllocsSize;
  427. }
  428. return memory;
  429. }
  430. else
  431. {
  432. return HK_NULL;
  433. }
  434. }
  435. void hkStlDebugMemory::internalFree(void* pfree, int bytesToFree, int flags)
  436. {
  437. hkCriticalSectionLock lock( &m_section );
  438.     hkStlDebugMemory::Map::iterator i = m_activePointers.find(pfree);
  439. HK_ASSERT2( 0x356976c1, i != m_activePointers.end(), "Freeing junk pointer");
  440. const PointerInfo& info = i->second;
  441. HK_ASSERT2( 0xaf53fe12, info.m_lockCount <= 0, "Freeing locked memory block.");
  442. HK_ASSERT2( 0x5861b912, (info.flags & MEM_ALIGNED) == (flags & MEM_ALIGNED), "Mismatched aligned methods");
  443. HK_ASSERT2( 0x5861b913, (info.flags & MEM_CHUNK) == (flags & MEM_CHUNK), "Mismatched chunk methods");
  444. if(bytesToFree == -1)
  445. {
  446. HK_ASSERT2( 0x5861b911, (flags & MEM_CHUNK) == 0, "Calling deallocate on a chunk");
  447. }
  448. else
  449. {
  450. HK_ASSERT2( 0x743ce000, info.numBytes == bytesToFree, "Freeing chunk of wrong size");
  451. }
  452. checkUnderOverrun(pfree, info);
  453. { // scrub area
  454. int prepadBytes = (int)hkUlong( static_cast<char*>(pfree) - static_cast<char*>(info.realMem) );
  455. hkString::memSet( info.realMem, s_fillFreeSpace, prepadBytes + info.numBytes + MEMORY_PADDING );
  456. }
  457. m_numSysAllocs -= 1;
  458. m_sysAllocsSize -= bytesToFree;
  459. hkSystemFree( info.realMem );
  460. m_activePointers.erase(i);
  461. }
  462. void* hkStlDebugMemory::allocateChunk(int nbytes, HK_MEMORY_CLASS c)
  463. {
  464. return internalAllocate(nbytes, c, MEM_CHUNK);
  465. }
  466. void hkStlDebugMemory::deallocateChunk(void* p, int nbytes, HK_MEMORY_CLASS cl)
  467. {
  468. if(p)
  469. {
  470. internalFree(p, nbytes, MEM_CHUNK);
  471. }
  472. }
  473. hkBool hkStlDebugMemory::isOk() const
  474. {
  475. hkCriticalSectionLock lock( &m_section );
  476.     hkStlDebugMemory::Map::const_iterator i = m_activePointers.begin();
  477.     hkStlDebugMemory::Map::const_iterator e = m_activePointers.end();
  478. for( ; i!=e; ++i)
  479. {
  480. checkUnderOverrun( i->first, i->second );
  481. }
  482. return true;
  483. }
  484. # include <Common/Base/Fwd/hkwindows.h>
  485. void HK_CALL hkStlDebugMemory::defaultOutputStringFunc( const char* s, void* context)
  486. {
  487. OutputDebugStringA(s);
  488. printf("%s",s); // Also output to console for automated testing
  489. }
  490. void hkStlDebugMemory::preAllocateRuntimeBlock(int nbytes, HK_MEMORY_CLASS cl)
  491. {
  492. }
  493. void* hkStlDebugMemory::allocateRuntimeBlock(int nbytes, HK_MEMORY_CLASS cl)
  494. {
  495. void* memory = allocateChunk(nbytes, cl);
  496. return memory;
  497. }
  498. void hkStlDebugMemory::deallocateRuntimeBlock(void* p, int nbytes, HK_MEMORY_CLASS cl)
  499. {
  500. deallocateChunk(p, nbytes, cl);
  501. }
  502. void hkStlDebugMemory::provideRuntimeBlock(void*, int nbytes, HK_MEMORY_CLASS cl)
  503. {
  504. }
  505. void hkStlDebugMemory::registerStaticAddress(void* address, int nbytes)
  506. {
  507. PointerInfo pointerinfo;
  508. {
  509. pointerinfo.numBytes      = nbytes;
  510. pointerinfo.flags         = MEM_CHUNK;
  511. pointerinfo.mark          = m_mark;
  512. pointerinfo.realMem       = address;
  513. }
  514. m_activePointers[address] = pointerinfo;
  515. }
  516. void hkStlDebugMemory::freeRuntimeBlocks()
  517. {
  518. }
  519. void* hkStlDebugMemory::findBaseAddress(void* p, int nbytes)
  520. {
  521. // try to use p as a base address
  522. {
  523.         hkStlDebugMemory::Map::iterator i = m_activePointers.find(p);
  524. if ( i != m_activePointers.end())
  525. {
  526. HK_ON_DEBUG( const PointerInfo& pinfo = i->second; )
  527. HK_ASSERT2( 0xf0457ef5, hkAddByteOffset(p, nbytes) <= hkAddByteOffset(i->first, pinfo.numBytes), "Invalid Block" );
  528. return i->first;
  529. }
  530. }
  531. // try to walk backward from p
  532. {
  533. void* q = (void*)(HK_NEXT_MULTIPLE_OF(16, hkUlong(p)));
  534. for (int n = 0; n < 50; n++)
  535. {
  536. q = hkAddByteOffset(q, hkUlong(-16));
  537.             hkStlDebugMemory::Map::iterator i = m_activePointers.find(q);
  538. if ( i != m_activePointers.end())
  539. {
  540. HK_ON_DEBUG( const PointerInfo& pinfo = i->second; )
  541. HK_ASSERT2( 0xf0457ef5, hkAddByteOffset(p, nbytes) <= hkAddByteOffset(i->first, pinfo.numBytes), "Invalid Block" );
  542. return i->first;
  543. }
  544. }
  545. }
  546. // search the full list
  547. {
  548.         hkStlDebugMemory::Map::iterator i = m_activePointers.begin();
  549.         hkStlDebugMemory::Map::iterator e = m_activePointers.end();
  550. for( ; i!=e; ++i)
  551. {
  552. const PointerInfo& pinfo = i->second;
  553. if ( i->first <= p && hkAddByteOffset(p, nbytes) <= hkAddByteOffset(i->first, pinfo.numBytes) )
  554. {
  555. return i->first;
  556. }
  557. }
  558. }
  559. HK_ASSERT2(0xaf543fe2, false, "Invalid memory block.");
  560. return HK_NULL;
  561. }
  562. void hkStlDebugMemory::lockBlock(void* p)
  563. {
  564.     hkStlDebugMemory::Map::iterator i = m_activePointers.find(p);
  565. PointerInfo& pinfo = i->second;
  566. pinfo.m_lockCount++;
  567. }
  568. void hkStlDebugMemory::unlockBlock(void* p)
  569. {
  570.     hkStlDebugMemory::Map::iterator i = m_activePointers.find(p);
  571. PointerInfo& pinfo = i->second;
  572. pinfo.m_lockCount--;
  573. }
  574. #endif // HK_STL_DEBUG_MEMORY_H
  575. /*
  576. * Havok SDK - NO SOURCE PC DOWNLOAD, BUILD(#20090216)
  577. * Confidential Information of Havok.  (C) Copyright 1999-2009
  578. * Telekinesys Research Limited t/a Havok. All Rights Reserved. The Havok
  579. * Logo, and the Havok buzzsaw logo are trademarks of Havok.  Title, ownership
  580. * rights, and intellectual property rights in the Havok software remain in
  581. * Havok and/or its suppliers.
  582. * Use of this software for evaluation purposes is subject to and indicates
  583. * acceptance of the End User licence Agreement for this product. A copy of
  584. * the license is included with this software and is also available at www.havok.com/tryhavok.
  585. */