Replace frame pointers with callstack frame ids.

This commit is contained in:
Bartosz Taudul 2019-03-03 16:50:18 +01:00
parent 664847211c
commit 9fc022346b
5 changed files with 91 additions and 40 deletions

View File

@ -197,7 +197,7 @@ enum { CallstackFrameIdSize = sizeof( CallstackFrameId ) };
struct CallstackFrameTree
{
uint64_t frame;
CallstackFrameId frame;
uint64_t alloc;
uint32_t count;
std::vector<CallstackFrameTree> children;

View File

@ -7,7 +7,7 @@ namespace Version
{
enum { Major = 0 };
enum { Minor = 4 };
enum { Patch = 5 };
enum { Patch = 6 };
}
}

View File

@ -4040,7 +4040,7 @@ void DrawZoneTrace( T zone, const std::vector<T>& trace, const Worker& worker, B
bool found = false;
for( auto& cf : currCs )
{
if( cf == pf )
if( cf.data == pf.data )
{
idx--;
found = true;
@ -6509,7 +6509,7 @@ void View::DrawFindZone()
{
ImGui::TextDisabled( "%i.", fidx++ );
ImGui::SameLine();
ImGui::Text( "%p", (void*)entry );
ImGui::Text( "%p", (void*)m_worker.GetCanonicalPointer( entry ) );
}
else
{
@ -7499,7 +7499,7 @@ void View::DrawCallstackWindow()
ImGui::Text( "%i", fidx++ );
ImGui::NextColumn();
char buf[32];
sprintf( buf, "%p", (void*)entry );
sprintf( buf, "%p", (void*)m_worker.GetCanonicalPointer( entry ) );
ImGui::TextUnformatted( buf );
if( ImGui::IsItemClicked() )
{
@ -8564,7 +8564,7 @@ void View::ListMemData( T ptr, T end, std::function<void(T&)> DrawAddress, const
ImGui::EndChild();
}
static tracy_force_inline CallstackFrameTree* GetFrameTreeItem( std::vector<CallstackFrameTree>& tree, uint64_t idx, const Worker& worker, bool groupByName )
static tracy_force_inline CallstackFrameTree* GetFrameTreeItem( std::vector<CallstackFrameTree>& tree, CallstackFrameId idx, const Worker& worker, bool groupByName )
{
std::vector<CallstackFrameTree>::iterator it;
if( groupByName )
@ -8581,7 +8581,7 @@ static tracy_force_inline CallstackFrameTree* GetFrameTreeItem( std::vector<Call
}
else
{
it = std::find_if( tree.begin(), tree.end(), [idx] ( const auto& v ) { return v.frame == idx; } );
it = std::find_if( tree.begin(), tree.end(), [idx] ( const auto& v ) { return v.frame.data == idx.data; } );
}
if( it == tree.end() )
{
@ -9515,7 +9515,7 @@ void View::CallstackTooltip( uint32_t idx )
{
ImGui::TextDisabled( "%i.", fidx++ );
ImGui::SameLine();
ImGui::Text( "%p", (void*)entry );
ImGui::Text( "%p", (void*)m_worker.GetCanonicalPointer( entry ) );
}
else
{

View File

@ -1018,24 +1018,69 @@ Worker::Worker( FileRead& f, EventType::Type eventMask )
s_loadProgress.progress.store( LoadProgress::CallStacks, std::memory_order_relaxed );
f.Read( sz );
m_data.callstackPayload.reserve( sz );
for( uint64_t i=0; i<sz; i++ )
if( fileVer >= FileVersion( 0, 4, 6 ) )
{
uint8_t csz;
f.Read( csz );
for( uint64_t i=0; i<sz; i++ )
{
uint8_t csz;
f.Read( csz );
const auto memsize = sizeof( VarArray<uint64_t> ) + csz * sizeof( uint64_t );
auto mem = (char*)m_slab.AllocRaw( memsize );
const auto memsize = sizeof( VarArray<CallstackFrameId> ) + csz * sizeof( CallstackFrameId );
auto mem = (char*)m_slab.AllocRaw( memsize );
auto data = (uint64_t*)mem;
f.Read( data, csz * sizeof( uint64_t ) );
auto data = (CallstackFrameId*)mem;
f.Read( data, csz * sizeof( CallstackFrameId ) );
auto arr = (VarArray<uint64_t>*)( mem + csz * sizeof( uint64_t ) );
new(arr) VarArray<uint64_t>( csz, data );
auto arr = (VarArray<CallstackFrameId>*)( mem + csz * sizeof( CallstackFrameId ) );
new(arr) VarArray<CallstackFrameId>( csz, data );
m_data.callstackPayload.push_back_no_space_check( arr );
m_data.callstackPayload.push_back_no_space_check( arr );
}
}
else
{
for( uint64_t i=0; i<sz; i++ )
{
uint8_t csz;
f.Read( csz );
const auto memsize = sizeof( VarArray<CallstackFrameId> ) + csz * sizeof( CallstackFrameId );
auto mem = (char*)m_slab.AllocRaw( memsize );
auto data = (CallstackFrameId*)mem;
for( uint8_t j=0; j<csz; j++ )
{
uint64_t ptr;
f.Read( ptr );
data[j] = PackPointer( ptr );
}
auto arr = (VarArray<CallstackFrameId>*)( mem + csz * sizeof( CallstackFrameId ) );
new(arr) VarArray<CallstackFrameId>( csz, data );
m_data.callstackPayload.push_back_no_space_check( arr );
}
}
if( fileVer >= FileVersion( 0, 4, 3 ) )
if( fileVer >= FileVersion( 0, 4, 6 ) )
{
f.Read( sz );
m_data.callstackFrameMap.reserve( sz );
for( uint64_t i=0; i<sz; i++ )
{
CallstackFrameId id;
f.Read( id );
auto frameData = m_slab.Alloc<CallstackFrameData>();
f.Read( frameData->size );
frameData->data = m_slab.Alloc<CallstackFrame>( frameData->size );
f.Read( frameData->data, sizeof( CallstackFrame ) * frameData->size );
m_data.callstackFrameMap.emplace( id, frameData );
}
}
else if( fileVer >= FileVersion( 0, 4, 3 ) )
{
f.Read( sz );
m_data.callstackFrameMap.reserve( sz );
@ -1050,7 +1095,7 @@ Worker::Worker( FileRead& f, EventType::Type eventMask )
frameData->data = m_slab.Alloc<CallstackFrame>( frameData->size );
f.Read( frameData->data, sizeof( CallstackFrame ) * frameData->size );
m_data.callstackFrameMap.emplace( ptr, frameData );
m_data.callstackFrameMap.emplace( PackPointer( ptr ), frameData );
}
}
else
@ -1068,7 +1113,7 @@ Worker::Worker( FileRead& f, EventType::Type eventMask )
frameData->data = m_slab.Alloc<CallstackFrame>();
f.Read( frameData->data, sizeof( CallstackFrame ) );
m_data.callstackFrameMap.emplace( ptr, frameData );
m_data.callstackFrameMap.emplace( PackPointer( ptr ), frameData );
}
}
@ -1259,7 +1304,7 @@ std::pair <int, int> Worker::GetFrameRange( const FrameData& fd, int64_t from, i
return std::make_pair( zbegin, zend );
}
const CallstackFrameData* Worker::GetCallstackFrame( uint64_t ptr ) const
const CallstackFrameData* Worker::GetCallstackFrame( const CallstackFrameId& ptr ) const
{
auto it = m_data.callstackFrameMap.find( ptr );
if( it == m_data.callstackFrameMap.end() )
@ -1775,7 +1820,7 @@ uint32_t Worker::ShrinkSourceLocation( uint64_t srcloc )
uint32_t Worker::NewShrinkedSourceLocation( uint64_t srcloc )
{
const auto sz = m_data.sourceLocationExpand.size();
const auto sz = int32_t( m_data.sourceLocationExpand.size() );
m_data.sourceLocationExpand.push_back( srcloc );
#ifndef TRACY_NO_STATISTICS
m_data.sourceLocationZones.emplace( sz, SourceLocationZones() );
@ -2036,18 +2081,24 @@ uint64_t Worker::GetCanonicalPointer( const CallstackFrameId& id ) const
return ( id.idx & 0x7FFFFFFFFFFFFFFF ) | ( ( id.idx & 0x4000000000000000 ) << 1 );
}
void Worker::AddCallstackPayload( uint64_t ptr, char* _data, size_t sz )
void Worker::AddCallstackPayload( uint64_t ptr, char* _data, size_t _sz )
{
assert( m_pendingCallstacks.find( ptr ) == m_pendingCallstacks.end() );
const auto memsize = sizeof( VarArray<uint64_t> ) + sz;
const auto sz = _sz / sizeof( uint64_t );
const auto memsize = sizeof( VarArray<CallstackFrameId> ) + sz * sizeof( CallstackFrameId );
auto mem = (char*)m_slab.AllocRaw( memsize );
auto data = (uint64_t*)mem;
memcpy( data, _data, sz );
auto data = (CallstackFrameId*)mem;
auto dst = data;
auto src = (uint64_t*)_data;
for( size_t i=0; i<sz; i++ )
{
*dst++ = PackPointer( *src++ );
}
auto arr = (VarArray<uint64_t>*)( mem + sz );
new(arr) VarArray<uint64_t>( sz / sizeof( uint64_t ), data );
auto arr = (VarArray<CallstackFrameId>*)( mem + sz * sizeof( CallstackFrameId ) );
new(arr) VarArray<CallstackFrameId>( sz, data );
uint32_t idx;
auto it = m_data.callstackMap.find( arr );
@ -2063,7 +2114,7 @@ void Worker::AddCallstackPayload( uint64_t ptr, char* _data, size_t sz )
if( fit == m_data.callstackFrameMap.end() )
{
m_pendingCallstackFrames++;
ServerQuery( ServerQueryCallstackFrame, frame );
ServerQuery( ServerQueryCallstackFrame, GetCanonicalPointer( frame ) );
}
}
}
@ -3073,7 +3124,7 @@ void Worker::ProcessCallstackFrameSize( const QueueCallstackFrameSize& ev )
m_pendingCallstackSubframes = ev.size;
// Frames may be duplicated due to recursion
auto fmit = m_data.callstackFrameMap.find( ev.ptr );
auto fmit = m_data.callstackFrameMap.find( PackPointer( ev.ptr ) );
if( fmit == m_data.callstackFrameMap.end() )
{
m_callstackFrameStaging = m_slab.Alloc<CallstackFrameData>();
@ -3103,8 +3154,8 @@ void Worker::ProcessCallstackFrame( const QueueCallstackFrame& ev )
if( --m_pendingCallstackSubframes == 0 )
{
assert( m_data.callstackFrameMap.find( m_callstackFrameStagingPtr ) == m_data.callstackFrameMap.end() );
m_data.callstackFrameMap.emplace( m_callstackFrameStagingPtr, m_callstackFrameStaging );
assert( m_data.callstackFrameMap.find( PackPointer( m_callstackFrameStagingPtr ) ) == m_data.callstackFrameMap.end() );
m_data.callstackFrameMap.emplace( PackPointer( m_callstackFrameStagingPtr ), m_callstackFrameStaging );
m_callstackFrameStaging = nullptr;
}
}
@ -3803,14 +3854,14 @@ void Worker::Write( FileWrite& f )
auto cs = m_data.callstackPayload[i];
uint8_t csz = cs->size();
f.Write( &csz, sizeof( csz ) );
f.Write( cs->data(), sizeof( uint64_t ) * csz );
f.Write( cs->data(), sizeof( CallstackFrameId ) * csz );
}
sz = m_data.callstackFrameMap.size();
f.Write( &sz, sizeof( sz ) );
for( auto& frame : m_data.callstackFrameMap )
{
f.Write( &frame.first, sizeof( uint64_t ) );
f.Write( &frame.first, sizeof( CallstackFrameId ) );
f.Write( &frame.second->size, sizeof( frame.second->size ) );
f.Write( frame.second->data, sizeof( CallstackFrame ) * frame.second->size );
}

View File

@ -143,9 +143,9 @@ private:
flat_hash_map<int32_t, uint64_t> sourceLocationZonesCnt;
#endif
flat_hash_map<VarArray<uint64_t>*, uint32_t, VarArrayHasherPOT<uint64_t>, VarArrayComparator<uint64_t>> callstackMap;
Vector<VarArray<uint64_t>*> callstackPayload;
flat_hash_map<uint64_t, CallstackFrameData*> callstackFrameMap;
flat_hash_map<VarArray<CallstackFrameId>*, uint32_t, VarArrayHasherPOT<CallstackFrameId>, VarArrayComparator<CallstackFrameId>> callstackMap;
Vector<VarArray<CallstackFrameId>*> callstackPayload;
flat_hash_map<CallstackFrameId, CallstackFrameData*, CallstackFrameIdHash, CallstackFrameIdCompare> callstackFrameMap;
std::map<uint32_t, LockMap> lockMap;
@ -244,8 +244,8 @@ public:
const Vector<ThreadData*>& GetThreadData() const { return m_data.threads; }
const MemData& GetMemData() const { return m_data.memory; }
const VarArray<uint64_t>& GetCallstack( uint32_t idx ) const { return *m_data.callstackPayload[idx]; }
const CallstackFrameData* GetCallstackFrame( uint64_t ptr ) const;
const VarArray<CallstackFrameId>& GetCallstack( uint32_t idx ) const { return *m_data.callstackPayload[idx]; }
const CallstackFrameData* GetCallstackFrame( const CallstackFrameId& ptr ) const;
uint64_t GetCanonicalPointer( const CallstackFrameId& id ) const;
const CrashEvent& GetCrashEvent() const { return m_data.m_crashEvent; }