MemReporter.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #pragma once
  2. #include "BeefySysLib/Common.h"
  3. #include "BeefySysLib/util/CritSect.h"
  4. #include "BeefySysLib/util/Hash.h"
  5. #include "BeefySysLib/util/String.h"
  6. #include "BeefySysLib/util/BumpAllocator.h"
  7. #include "BeefySysLib/util/Dictionary.h"
  8. #include <vector>
  9. NS_BF_BEGIN
  10. class MemReporter
  11. {
  12. public:
  13. struct Entry
  14. {
  15. Dictionary<String, Entry*> mChildren;
  16. String mName;
  17. int mSize;
  18. int mChildSize;
  19. int mCount;
  20. Entry* mParent;
  21. Entry()
  22. {
  23. mSize = 0;
  24. mChildSize = -1;
  25. mParent = NULL;
  26. mCount = 0;
  27. }
  28. };
  29. BumpAllocator mAlloc;
  30. Entry mRoot;
  31. Entry* mCurEntry;
  32. bool mShowInKB;
  33. public:
  34. int GetChildSizes(Entry* entry);
  35. void Report(int depth, Entry* entry);
  36. public:
  37. MemReporter();
  38. ~MemReporter();
  39. void BeginSection(const StringView& name);
  40. void Add(int size);
  41. void Add(const StringView& name, int size);
  42. template <typename T>
  43. void AddVec(const T& vec, bool addContainerSize = true)
  44. {
  45. Add((addContainerSize ? sizeof(T) : 0) + (int)vec.mAllocSize * sizeof(typename T::value_type));
  46. }
  47. template <typename T>
  48. void AddVec(const StringView& name, const T& vec, bool addContainerSize = true)
  49. {
  50. BeginSection(name);
  51. Add((addContainerSize ? sizeof(T) : 0) + (int)vec.mAllocSize * sizeof(typename T::value_type));
  52. EndSection();
  53. }
  54. template <typename T>
  55. void AddVecPtr(const std::vector<T>& vec, bool addContainerSize = true)
  56. {
  57. Add((addContainerSize ? sizeof(T) : 0) +
  58. (int)vec.capacity() * sizeof(T) +
  59. (int)vec.size() * sizeof(typename std::remove_pointer<T>::type)); //-V220
  60. }
  61. template <typename T>
  62. void AddVecPtr(const Array<T>& vec, bool addContainerSize = true)
  63. {
  64. Add((addContainerSize ? sizeof(T) : 0) +
  65. (int)vec.mAllocSize * sizeof(T) +
  66. (int)vec.size() * sizeof(typename std::remove_pointer<T>::type)); //-V220
  67. }
  68. template <typename T>
  69. void AddVecPtr(const StringView& name, const Array<T>& vec, bool addContainerSize = true)
  70. {
  71. Add(name, (addContainerSize ? sizeof(T) : 0) +
  72. (int)vec.mAllocSize * sizeof(T) +
  73. (int)vec.size() * sizeof(typename std::remove_pointer<T>::type)); //-V220
  74. }
  75. template <typename T>
  76. void AddMap(const StringView& name, const T& map, bool addContainerSize = true)
  77. {
  78. Add(name, (addContainerSize ? sizeof(T) : 0) + map.mAllocSize * (sizeof(typename T::EntryPair) + sizeof(typename T::int_cosize)));
  79. }
  80. template <typename T>
  81. void AddMap(const T& map, bool addContainerSize = true)
  82. {
  83. Add((addContainerSize ? sizeof(T) : 0) + map.mAllocSize * (sizeof(typename T::EntryPair) + sizeof(typename T::int_cosize)));
  84. }
  85. template <typename T>
  86. void AddHashSet(const StringView& name, const T& map, bool addContainerSize = true)
  87. {
  88. Add(name, (addContainerSize ? sizeof(T) : 0) + map.mAllocSize * (sizeof(typename T::Entry) + sizeof(typename T::int_cosize)));
  89. }
  90. template <typename T>
  91. void AddHashSet(const T& map, bool addContainerSize = true)
  92. {
  93. Add((addContainerSize ? sizeof(T) : 0) + map.mAllocSize * (sizeof(typename T::Entry) + sizeof(typename T::int_cosize)));
  94. }
  95. void AddStr(const StringImpl& str, bool addContainerSize = true)
  96. {
  97. Add((addContainerSize ? sizeof(StringImpl) : 0) + (int)str.GetAllocSize());
  98. }
  99. void AddStr(const StringView& name, const StringImpl& str, bool addContainerSize = true)
  100. {
  101. Add(name, (addContainerSize ? sizeof(StringImpl) : 0) + (int)str.GetAllocSize());
  102. }
  103. void EndSection();
  104. void Report();
  105. template <typename T>
  106. void AddBumpAlloc(const StringView& name, const T& alloc)
  107. {
  108. BeginSection(name);
  109. int usedSize = alloc.CalcUsedSize();
  110. #ifdef BUMPALLOC_TRACKALLOCS
  111. T* allocPtr = (T*)&alloc;
  112. int usedSizeLeft = usedSize;
  113. Array<Entry> entries;
  114. for (const auto& kv : allocPtr->mTrackedAllocs)
  115. {
  116. const char* str = kv.mKey.c_str();
  117. BumpAllocTrackedEntry trackedEntry = kv.mValue;
  118. String name;
  119. if (strncmp(str, "class ", 6) == 0)
  120. name = str + 6;
  121. else if (strncmp(str, "struct ", 7) == 0)
  122. name = str + 7;
  123. else
  124. name = str;
  125. BeginSection(name);
  126. mCurEntry->mSize += trackedEntry.mSize;
  127. mCurEntry->mCount += trackedEntry.mCount;
  128. EndSection();
  129. usedSizeLeft -= trackedEntry.mSize;
  130. }
  131. if (usedSizeLeft > 0)
  132. Add("Unaccounted", usedSizeLeft);
  133. #else
  134. Add("Used", usedSize);
  135. #endif
  136. Add("Waste", alloc.GetAllocSize() - usedSize);
  137. Add("Unused", alloc.GetTotalAllocSize() - alloc.GetAllocSize());
  138. EndSection();
  139. }
  140. };
  141. class AutoMemReporter
  142. {
  143. public:
  144. MemReporter* mMemReporter;
  145. public:
  146. AutoMemReporter(MemReporter* memReporter, const StringImpl& name)
  147. {
  148. mMemReporter = memReporter;
  149. mMemReporter->BeginSection(name);
  150. }
  151. ~AutoMemReporter()
  152. {
  153. mMemReporter->EndSection();
  154. }
  155. };
  156. NS_BF_END