You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/CryEngine/CryCommon/CrtDebugStats.h

161 lines
4.6 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// support for leak dumping and statistics gathering using vs Crt Debug
// should be included in every DLL below DllMain()
#ifndef CRYINCLUDE_CRYCOMMON_CRTDEBUGSTATS_H
#define CRYINCLUDE_CRYCOMMON_CRTDEBUGSTATS_H
#pragma once
#ifdef WIN32
#ifdef _DEBUG
#include <ILog.h>
#include <ISystem.h> // CryLogAlways
#include <crtdbg.h>
// copied from DBGINT.H (not a public header!)
#define nNoMansLandSize 4
typedef struct _CrtMemBlockHeader
{
struct _CrtMemBlockHeader* pBlockHeaderNext;
struct _CrtMemBlockHeader* pBlockHeaderPrev;
char* szFileName;
int nLine;
size_t nDataSize;
int nBlockUse;
long lRequest;
unsigned char gap[nNoMansLandSize];
/* followed by:
* unsigned char data[nDataSize];
* unsigned char anotherGap[nNoMansLandSize];
*/
} _CrtMemBlockHeader;
struct SFileInfo
{
int blocks;
INT_PTR bytes; //AMD Port
SFileInfo(INT_PTR b) { blocks = 1; bytes = b; }; //AMD Port
};
_CrtMemState lastcheckpoint;
bool checkpointset = false;
extern "C" void __declspec(dllexport) CheckPoint()
{
_CrtMemCheckpoint(&lastcheckpoint);
checkpointset = true;
};
bool pairgreater(const std::pair<string, SFileInfo>& elem1, const std::pair<string, SFileInfo>& elem2)
{
return elem1.second.bytes > elem2.second.bytes;
}
extern "C" void __declspec(dllexport) UsageSummary([[maybe_unused]] ILog * log, char* modulename, int* extras)
{
_CrtMemState state;
if (checkpointset)
{
_CrtMemState recent;
_CrtMemCheckpoint(&recent);
_CrtMemDifference(&state, &lastcheckpoint, &recent);
}
else
{
_CrtMemCheckpoint(&state);
};
INT_PTR numblocks = state.lCounts[_NORMAL_BLOCK]; //AMD Port
INT_PTR totalalloc = state.lSizes[_NORMAL_BLOCK]; //AMD Port
check_convert(extras[0]) = totalalloc;
check_convert(extras[1]) = numblocks;
CryLogAlways("$5---------------------------------------------------------------------------------------------------");
if (!numblocks)
{
CryLogAlways("$3Module %s has no memory in use", modulename);
return;
}
;
CryLogAlways("$5Usage summary for module %s", modulename);
CryLogAlways("%d kbytes (peak %d) in %d objects of %d average bytes\n",
totalalloc / 1024, state.lHighWaterCount / 1024, numblocks, numblocks ? totalalloc / numblocks : 0);
CryLogAlways("%d kbytes allocated over time\n", state.lTotalCount / 1024);
typedef std::map<string, SFileInfo> FileMap;
FileMap fm;
for (_CrtMemBlockHeader* h = state.pBlockHeader; h; h = h->pBlockHeaderNext)
{
if (_BLOCK_TYPE(h->nBlockUse) != _NORMAL_BLOCK)
{
continue;
}
string s = h->szFileName ? h->szFileName : "NO_SOURCE";
if (h->nLine > 0)
{
char buf[16];
sprintf_s(buf, "_%d", h->nLine);
s += buf;
}
FileMap::iterator it = fm.find(s);
if (it != fm.end())
{
(*it).second.blocks++;
(*it).second.bytes += h->nDataSize;
}
else
{
fm.insert(FileMap::value_type(s, SFileInfo(h->nDataSize)));
};
}
;
typedef std::vector< std::pair<string, SFileInfo> > FileVector;
FileVector fv;
for (FileMap::iterator it = fm.begin(); it != fm.end(); ++it)
{
fv.push_back((*it));
}
std::sort(fv.begin(), fv.end(), pairgreater);
for (FileVector::iterator it = fv.begin(); it != fv.end(); ++it)
{
CryLogAlways("%6d kbytes / %6d blocks allocated from %s\n",
(*it).second.bytes / 1024, (*it).second.blocks, (*it).first.c_str());
}
;
};
#endif // _DEBUG
#if !defined(_RELEASE) && !defined(_DLL) && defined(HANDLE)
extern "C" HANDLE _crtheap;
extern "C" HANDLE __declspec(dllexport) GetDLLHeap() {
return _crtheap;
};
#endif
#endif // WIN32
#endif // CRYINCLUDE_CRYCOMMON_CRTDEBUGSTATS_H