0
0
mirror of https://github.com/yse/easy_profiler.git synced 2024-12-27 08:41:02 +08:00

#37 Replaced std::string with char* for NonscopedBlock with manual memory management

This commit is contained in:
Victor Zarubkin 2017-06-07 20:50:16 +03:00
parent 43b6d1312b
commit 48fb240ca0
2 changed files with 31 additions and 9 deletions

View File

@ -592,28 +592,50 @@ public:
//////////////////////////////////////////////////////////////////////////
NonscopedBlock::NonscopedBlock(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName, bool)
: profiler::Block(_desc, _runtimeName, false)
: profiler::Block(_desc, _runtimeName, false), m_runtimeName(nullptr)
{
}
NonscopedBlock::~NonscopedBlock()
{
// Actually destructor should not be invoked because StackBuffer do manual memory management
m_end = m_begin; // to restrict profiler::Block to invoke profiler::endBlock() on destructor.
free(m_runtimeName);
}
void NonscopedBlock::copyname()
{
if ((m_status & profiler::ON) != 0 && m_name[0] != 0)
// Here we need to copy m_name to m_runtimeName to ensure that
// it would be alive to the moment we will serialize the block
if ((m_status & profiler::ON) == 0)
return;
if (*m_name != 0)
{
m_runtimeName = m_name;
m_name = m_runtimeName.c_str();
auto len = strlen(m_name);
m_runtimeName = static_cast<char*>(malloc(len + 1));
// memcpy should be faster than strncpy because we know
// actual bytes number and both strings have the same size
memcpy(m_runtimeName, m_name, len);
m_runtimeName[len] = 0;
m_name = m_runtimeName;
}
else
{
m_name = "";
}
}
void NonscopedBlock::destroy()
{
std::string().swap(m_runtimeName); // free memory used by m_runtimeName
// free memory used by m_runtimeName
free(m_runtimeName);
m_name = "";
}
//////////////////////////////////////////////////////////////////////////

View File

@ -299,7 +299,7 @@ public:
class NonscopedBlock : public profiler::Block
{
std::string m_runtimeName; ///< a copy of _runtimeName to make it safe to begin block in one function and end it in another
char* m_runtimeName; ///< a copy of _runtimeName to make it safe to begin block in one function and end it in another
NonscopedBlock() = delete;
NonscopedBlock(const NonscopedBlock&) = delete;
@ -348,7 +348,7 @@ class StackBuffer
public:
StackBuffer(uint32_t N) : m_buffer((T*)malloc(N * sizeof(T))), m_size(0), m_capacity(N), m_maxcapacity(N)
StackBuffer(uint32_t N) : m_buffer(static_cast<T*>(malloc(N * sizeof(T)))), m_size(0), m_capacity(N), m_maxcapacity(N)
{
}
@ -370,7 +370,7 @@ public:
return *(::new (m_buffer + m_size++) T(_args...));
m_overflow.emplace_back();
const uint32_t cap = m_capacity + (uint32_t)m_overflow.size();
const uint32_t cap = m_capacity + static_cast<uint32_t>(m_overflow.size());
if (m_maxcapacity < cap)
m_maxcapacity = cap;
@ -389,7 +389,7 @@ public:
// When stack gone empty we can resize buffer to use enough space in the future
free(m_buffer);
m_maxcapacity = m_capacity = std::max(m_maxcapacity, m_capacity << 1);
m_buffer = (T*)malloc(m_capacity * sizeof(T));
m_buffer = static_cast<T*>(malloc(m_buffer, m_capacity * sizeof(T)));
}
return;