1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 03:28:20 +02:00
Beef/IDEHelper/Compiler/MemReporter.h
Brian Fiete 2f01cc14dd Beefy::String changes, lambda hotswap fixes
Changed some string internals related to StringViewsma
Added an "incompatible capture" error for lambdas when the captures change
2019-09-03 11:17:13 -07:00

191 lines
4.5 KiB
C++

#pragma once
#include "BeefySysLib/Common.h"
#include "BeefySysLib/util/CritSect.h"
#include "BeefySysLib/util/Hash.h"
#include "BeefySysLib/util/String.h"
#include "BeefySysLib/util/BumpAllocator.h"
#include "BeefySysLib/util/Dictionary.h"
#include <vector>
NS_BF_BEGIN
class MemReporter
{
public:
struct Entry
{
Dictionary<String, Entry*> mChildren;
String mName;
int mSize;
int mChildSize;
int mCount;
Entry* mParent;
Entry()
{
mSize = 0;
mChildSize = -1;
mParent = NULL;
mCount = 0;
}
};
BumpAllocator mAlloc;
Entry mRoot;
Entry* mCurEntry;
bool mShowInKB;
public:
int GetChildSizes(Entry* entry);
void Report(int depth, Entry* entry);
public:
MemReporter();
~MemReporter();
void BeginSection(const StringView& name);
void Add(int size);
void Add(const StringView& name, int size);
template <typename T>
void AddVec(const T& vec, bool addContainerSize = true)
{
Add((addContainerSize ? sizeof(T) : 0) + (int)vec.mAllocSize * sizeof(typename T::value_type));
}
template <typename T>
void AddVec(const StringView& name, const T& vec, bool addContainerSize = true)
{
BeginSection(name);
Add((addContainerSize ? sizeof(T) : 0) + (int)vec.mAllocSize * sizeof(typename T::value_type));
EndSection();
}
template <typename T>
void AddVecPtr(const std::vector<T>& vec, bool addContainerSize = true)
{
Add((addContainerSize ? sizeof(T) : 0) +
(int)vec.capacity() * sizeof(T) +
(int)vec.size() * sizeof(typename std::remove_pointer<T>::type)); //-V220
}
template <typename T>
void AddVecPtr(const Array<T>& vec, bool addContainerSize = true)
{
Add((addContainerSize ? sizeof(T) : 0) +
(int)vec.mAllocSize * sizeof(T) +
(int)vec.size() * sizeof(typename std::remove_pointer<T>::type)); //-V220
}
template <typename T>
void AddVecPtr(const StringView& name, const Array<T>& vec, bool addContainerSize = true)
{
Add(name, (addContainerSize ? sizeof(T) : 0) +
(int)vec.mAllocSize * sizeof(T) +
(int)vec.size() * sizeof(typename std::remove_pointer<T>::type)); //-V220
}
template <typename T>
void AddMap(const StringView& name, const T& map, bool addContainerSize = true)
{
Add(name, (addContainerSize ? sizeof(T) : 0) + map.mAllocSize * (sizeof(typename T::EntryPair) + sizeof(typename T::int_cosize)));
}
template <typename T>
void AddMap(const T& map, bool addContainerSize = true)
{
Add((addContainerSize ? sizeof(T) : 0) + map.mAllocSize * (sizeof(typename T::EntryPair) + sizeof(typename T::int_cosize)));
}
template <typename T>
void AddHashSet(const StringView& name, const T& map, bool addContainerSize = true)
{
Add(name, (addContainerSize ? sizeof(T) : 0) + map.mAllocSize * (sizeof(typename T::Entry) + sizeof(typename T::int_cosize)));
}
template <typename T>
void AddHashSet(const T& map, bool addContainerSize = true)
{
Add((addContainerSize ? sizeof(T) : 0) + map.mAllocSize * (sizeof(typename T::Entry) + sizeof(typename T::int_cosize)));
}
void AddStr(const StringImpl& str, bool addContainerSize = true)
{
Add((addContainerSize ? sizeof(StringImpl) : 0) + (int)str.GetAllocSize());
}
void AddStr(const StringView& name, const StringImpl& str, bool addContainerSize = true)
{
Add(name, (addContainerSize ? sizeof(StringImpl) : 0) + (int)str.GetAllocSize());
}
void EndSection();
void Report();
template <typename T>
void AddBumpAlloc(const StringView& name, const T& alloc)
{
BeginSection(name);
int usedSize = alloc.CalcUsedSize();
#ifdef BUMPALLOC_TRACKALLOCS
T* allocPtr = (T*)&alloc;
int usedSizeLeft = usedSize;
Array<Entry> entries;
for (const auto& kv : allocPtr->mTrackedAllocs)
{
const char* str = kv.mKey.c_str();
BumpAllocTrackedEntry trackedEntry = kv.mValue;
String name;
if (strncmp(str, "class ", 6) == 0)
name = str + 6;
else if (strncmp(str, "struct ", 7) == 0)
name = str + 7;
else
name = str;
BeginSection(name);
mCurEntry->mSize += trackedEntry.mSize;
mCurEntry->mCount += trackedEntry.mCount;
EndSection();
usedSizeLeft -= trackedEntry.mSize;
}
if (usedSizeLeft > 0)
Add("Unaccounted", usedSizeLeft);
#else
Add("Used", usedSize);
#endif
Add("Waste", alloc.GetAllocSize() - usedSize);
Add("Unused", alloc.GetTotalAllocSize() - alloc.GetAllocSize());
EndSection();
}
};
class AutoMemReporter
{
public:
MemReporter* mMemReporter;
public:
AutoMemReporter(MemReporter* memReporter, const StringImpl& name)
{
mMemReporter = memReporter;
mMemReporter->BeginSection(name);
}
~AutoMemReporter()
{
mMemReporter->EndSection();
}
};
NS_BF_END