Guest User

Untitled

a guest
Jul 18th, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.48 KB | None | 0 0
  1. #include "AntlerMalloc.h"
  2. #include "AntlerAtomic.h"
  3. #include <string.h>
  4.  
  5. #if defined(_DEBUG) || defined(DEBUG) || defined(_DEVELOPMENT)
  6.  
  7. typedef struct Antler_Malloc_Info
  8. {
  9. const char* file;
  10. int line;
  11. size_t size;
  12. size_t index;
  13. }Antler_Malloc_Info;
  14.  
  15. typedef struct AllocVector{
  16. Antler_Malloc_Info** items;
  17. size_t capacity;
  18. size_t count;
  19. size_t itemSize;
  20. }AllocVector;
  21.  
  22. static AllocVector* vector = NULL;
  23.  
  24. static AllocVector* MallocVector_Create(size_t _itemSize, size_t _startCapacity)
  25. {
  26. AllocVector* vector = malloc(sizeof(*vector));
  27. if (vector) {
  28. vector->capacity = _startCapacity;
  29. vector->count = 0;
  30. // vector->mutex = Antler_Mutex_Create();
  31. vector->itemSize = _itemSize;
  32. vector->items = malloc(_itemSize*vector->capacity);
  33. }
  34. else {
  35. vector = NULL;
  36. // out of memory
  37. }
  38. return vector;
  39. }
  40.  
  41. static void AllocVector_Resize(AllocVector* _vec, size_t _capacity)
  42. {
  43. Antler_Malloc_Info **items = realloc(_vec->items, _vec->itemSize * _capacity);
  44. if (items) {
  45. _vec->items = items;
  46. _vec->capacity = _capacity;
  47. }
  48. }
  49.  
  50. static void AllocVector_Push(AllocVector* _vec, Antler_Malloc_Info* _item)
  51. {
  52. if (_vec->capacity == _vec->count)
  53. AllocVector_Resize(_vec, _vec->capacity * 2);
  54. _vec->items[_vec->count++] = _item;
  55. }
  56.  
  57. static void AllocVector_Remove(AllocVector* _vec, size_t _index)
  58. {
  59. if (_vec != NULL){
  60. Antler_Assert(_index >= 0);
  61. Antler_Assert(_index < _vec->count);
  62. size_t i = _index;
  63. for (i = _index; i < _vec->count - 1; i++) {
  64. _vec->items[i+1]->index = _vec->items[i+1]->index-1;
  65. _vec->items[i] = _vec->items[i + 1];
  66. }
  67. _vec->count--;
  68. if (_vec->count == _vec->capacity / 4)
  69. AllocVector_Resize(_vec, _vec->capacity / 2);
  70. }
  71. }
  72.  
  73. void *Antler_Malloc_Impl(size_t sz, const char *file, int line)
  74. {
  75. if (vector == NULL)
  76. vector = MallocVector_Create(sizeof(Antler_Malloc_Info*), 5);
  77. Antler_Malloc_Info* info = malloc(sz + sizeof(*info));
  78. if (info == NULL) return info;
  79. info->file = file;
  80. info->line = line;
  81. info->size = sz;
  82. AllocVector_Push(vector, info);
  83. info->index = vector->count - 1;
  84. return info+1;
  85. }
  86.  
  87. void *Antler_Calloc_Impl(size_t _nitems, size_t _sz, const char *_file, int _line)
  88. {
  89. size_t size = _nitems * _sz;
  90. void *ptr = Antler_Malloc_Impl(size, _file, _line);
  91. memset(ptr, 0, size);
  92. return ptr;
  93. }
  94.  
  95. void Antler_Free_Impl(void *_ptr)
  96. {
  97. if (_ptr != NULL) {
  98. Antler_Malloc_Info *info = (Antler_Malloc_Info *)_ptr - 1;
  99. AllocVector_Remove(vector, info->index);
  100. free(info);
  101. if (vector->count == 0){
  102. free(vector->items);
  103. free(vector);
  104. vector = NULL;
  105. }
  106. }
  107. }
  108.  
  109. void *Antler_Realloc_Impl(void *_ptr, size_t _sz, const char *_file, int _line)
  110. {
  111. if (_ptr == NULL) {
  112. return Antler_Malloc_Impl(_sz, _file, _line);
  113. }
  114. else if (_sz == 0) {
  115. Antler_Free_Impl(_ptr);
  116. return NULL;
  117. }
  118. else {
  119. Antler_Malloc_Info *info = (Antler_Malloc_Info *)_ptr - 1;
  120. if (_sz <= info->size)
  121. return _ptr;
  122. else {
  123. void *q = Antler_Malloc_Impl(_sz, _file, _line);
  124. if (q) {
  125. memcpy(q, _ptr, info->size);
  126. Antler_Free_Impl(_ptr);
  127. }
  128. return q;
  129. }
  130. }
  131. }
  132.  
  133. static void Malloc_LeakPrint(const char *reason, const char *file, int line, size_t size, void *ptr)
  134. {
  135. #if (defined(_MSC_VER) && _MSC_VER < 1900) /* 1900=VS 2015 */ || defined(__MINGW32__)
  136. // Compilers that use the old MS C runtime library don't have %zd
  137. // and the older ones don't even have %lld either... however, the old compilers
  138. // without "long long" don't support 64-bit targets either, so here's the
  139. // compromise:
  140. #if defined(_MSC_VER) && _MSC_VER < 1400 // before VS 2005
  141. printf("%-6s: %s (%4d): %8d bytes at %p\n", reason, file, line, (int)size, ptr);
  142. #else
  143. printf("%-6s: %s (%4d): %8lld bytes at %p\n", reason, file, line, (long long)size, ptr);
  144. #endif
  145. #else
  146. // Assume we have %zd on other targets.
  147. printf("%-6s: %s (%4d): %zd bytes at %p\n", reason, file, line, size, ptr);
  148. #endif
  149. }
  150.  
  151. static void Malloc_Summary(const char *reason, int errcnt, size_t size)
  152. {
  153. #if (defined(_MSC_VER) && _MSC_VER < 1900) /* 1900=VS 2015 */ || defined(__MINGW32__)
  154. // Compilers that use the old MS C runtime library don't have %zd
  155. // and the older ones don't even have %lld either... however, the old compilers
  156. // without "long long" don't support 64-bit targets either, so here's the
  157. // compromise:
  158. #if defined(_MSC_VER) && _MSC_VER < 1400 // before VS 2005
  159. printf("%-6s: %6d items totalling %8d bytes\n", reason, errcnt, (int)size);
  160. #else
  161. printf("%-6s: %6d items totalling %8lld bytes\n", reason, errcnt, (long long)size);
  162. #endif
  163. #else
  164. // Assume we have %zd on other targets.
  165. printf("%-6s: %6d items totalling %zd bytes\n", reason, errcnt, size);
  166. #endif
  167. }
  168.  
  169.  
  170.  
  171. #endif
  172.  
  173. size_t Antler_Malloc_NumLeaks(void)
  174. {
  175. #if defined(_DEBUG) || defined(DEBUG) || defined(_DEVELOPMENT)
  176. if (vector == NULL ) return 0;
  177. return vector->count;
  178. #else
  179. return 0;
  180. #endif
  181. }
  182.  
  183. void Antler_Malloc_GetLeak(size_t _index, Antler_MallocLeak* _leak)
  184. {
  185. #if defined(_DEBUG) || defined(DEBUG) || defined(_DEVELOPMENT)
  186. if (vector == NULL) return;
  187. Antler_Assert(_index >= 0);
  188. Antler_Assert(_index < vector->count);
  189. Antler_Malloc_Info *info = vector->items[_index];
  190. _leak->file = info->file;
  191. _leak->line = info->line;
  192. _leak->size = info->size;
  193. _leak->address = info + 1;
  194. #endif
  195. }
  196.  
  197. void Antler_Malloc_LeakDump()
  198. {
  199. #if defined(_DEBUG) || defined(DEBUG) || defined(_DEVELOPMENT)
  200. size_t i = 0;
  201. size_t size = 0;
  202. for (; i < Antler_Malloc_NumLeaks(); ++i){
  203. Antler_MallocLeak leak;
  204. Antler_Malloc_GetLeak(i, &leak);
  205. Malloc_LeakPrint("LEAKED", leak.file, leak.line, leak.size, leak.address);
  206. size += leak.size;
  207. }
  208. if(size) Malloc_Summary("LEAKED", Antler_Malloc_NumLeaks(), size);
  209. #endif
  210. }
Add Comment
Please, Sign In to add comment