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 struct CallstackFrameTree
{ {
uint64_t frame; CallstackFrameId frame;
uint64_t alloc; uint64_t alloc;
uint32_t count; uint32_t count;
std::vector<CallstackFrameTree> children; std::vector<CallstackFrameTree> children;

View File

@ -7,7 +7,7 @@ namespace Version
{ {
enum { Major = 0 }; enum { Major = 0 };
enum { Minor = 4 }; 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; bool found = false;
for( auto& cf : currCs ) for( auto& cf : currCs )
{ {
if( cf == pf ) if( cf.data == pf.data )
{ {
idx--; idx--;
found = true; found = true;
@ -6509,7 +6509,7 @@ void View::DrawFindZone()
{ {
ImGui::TextDisabled( "%i.", fidx++ ); ImGui::TextDisabled( "%i.", fidx++ );
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text( "%p", (void*)entry ); ImGui::Text( "%p", (void*)m_worker.GetCanonicalPointer( entry ) );
} }
else else
{ {
@ -7499,7 +7499,7 @@ void View::DrawCallstackWindow()
ImGui::Text( "%i", fidx++ ); ImGui::Text( "%i", fidx++ );
ImGui::NextColumn(); ImGui::NextColumn();
char buf[32]; char buf[32];
sprintf( buf, "%p", (void*)entry ); sprintf( buf, "%p", (void*)m_worker.GetCanonicalPointer( entry ) );
ImGui::TextUnformatted( buf ); ImGui::TextUnformatted( buf );
if( ImGui::IsItemClicked() ) if( ImGui::IsItemClicked() )
{ {
@ -8564,7 +8564,7 @@ void View::ListMemData( T ptr, T end, std::function<void(T&)> DrawAddress, const
ImGui::EndChild(); 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; std::vector<CallstackFrameTree>::iterator it;
if( groupByName ) if( groupByName )
@ -8581,7 +8581,7 @@ static tracy_force_inline CallstackFrameTree* GetFrameTreeItem( std::vector<Call
} }
else 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() ) if( it == tree.end() )
{ {
@ -9515,7 +9515,7 @@ void View::CallstackTooltip( uint32_t idx )
{ {
ImGui::TextDisabled( "%i.", fidx++ ); ImGui::TextDisabled( "%i.", fidx++ );
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text( "%p", (void*)entry ); ImGui::Text( "%p", (void*)m_worker.GetCanonicalPointer( entry ) );
} }
else else
{ {

View File

@ -1018,24 +1018,69 @@ Worker::Worker( FileRead& f, EventType::Type eventMask )
s_loadProgress.progress.store( LoadProgress::CallStacks, std::memory_order_relaxed ); s_loadProgress.progress.store( LoadProgress::CallStacks, std::memory_order_relaxed );
f.Read( sz ); f.Read( sz );
m_data.callstackPayload.reserve( sz ); m_data.callstackPayload.reserve( sz );
if( fileVer >= FileVersion( 0, 4, 6 ) )
{
for( uint64_t i=0; i<sz; i++ ) for( uint64_t i=0; i<sz; i++ )
{ {
uint8_t csz; uint8_t csz;
f.Read( csz ); f.Read( csz );
const auto memsize = sizeof( VarArray<uint64_t> ) + csz * sizeof( uint64_t ); const auto memsize = sizeof( VarArray<CallstackFrameId> ) + csz * sizeof( CallstackFrameId );
auto mem = (char*)m_slab.AllocRaw( memsize ); auto mem = (char*)m_slab.AllocRaw( memsize );
auto data = (uint64_t*)mem; auto data = (CallstackFrameId*)mem;
f.Read( data, csz * sizeof( uint64_t ) ); f.Read( data, csz * sizeof( CallstackFrameId ) );
auto arr = (VarArray<uint64_t>*)( mem + csz * sizeof( uint64_t ) ); auto arr = (VarArray<CallstackFrameId>*)( mem + csz * sizeof( CallstackFrameId ) );
new(arr) VarArray<uint64_t>( csz, data ); 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 );
if( fileVer >= FileVersion( 0, 4, 3 ) ) 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, 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 ); f.Read( sz );
m_data.callstackFrameMap.reserve( 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 ); frameData->data = m_slab.Alloc<CallstackFrame>( frameData->size );
f.Read( frameData->data, sizeof( 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 else
@ -1068,7 +1113,7 @@ Worker::Worker( FileRead& f, EventType::Type eventMask )
frameData->data = m_slab.Alloc<CallstackFrame>(); frameData->data = m_slab.Alloc<CallstackFrame>();
f.Read( frameData->data, sizeof( 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 ); 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 ); auto it = m_data.callstackFrameMap.find( ptr );
if( it == m_data.callstackFrameMap.end() ) if( it == m_data.callstackFrameMap.end() )
@ -1775,7 +1820,7 @@ uint32_t Worker::ShrinkSourceLocation( uint64_t srcloc )
uint32_t Worker::NewShrinkedSourceLocation( 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 ); m_data.sourceLocationExpand.push_back( srcloc );
#ifndef TRACY_NO_STATISTICS #ifndef TRACY_NO_STATISTICS
m_data.sourceLocationZones.emplace( sz, SourceLocationZones() ); 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 ); 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() ); 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 mem = (char*)m_slab.AllocRaw( memsize );
auto data = (uint64_t*)mem; auto data = (CallstackFrameId*)mem;
memcpy( data, _data, sz ); 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 ); auto arr = (VarArray<CallstackFrameId>*)( mem + sz * sizeof( CallstackFrameId ) );
new(arr) VarArray<uint64_t>( sz / sizeof( uint64_t ), data ); new(arr) VarArray<CallstackFrameId>( sz, data );
uint32_t idx; uint32_t idx;
auto it = m_data.callstackMap.find( arr ); 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() ) if( fit == m_data.callstackFrameMap.end() )
{ {
m_pendingCallstackFrames++; m_pendingCallstackFrames++;
ServerQuery( ServerQueryCallstackFrame, frame ); ServerQuery( ServerQueryCallstackFrame, GetCanonicalPointer( frame ) );
} }
} }
} }
@ -3073,7 +3124,7 @@ void Worker::ProcessCallstackFrameSize( const QueueCallstackFrameSize& ev )
m_pendingCallstackSubframes = ev.size; m_pendingCallstackSubframes = ev.size;
// Frames may be duplicated due to recursion // 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() ) if( fmit == m_data.callstackFrameMap.end() )
{ {
m_callstackFrameStaging = m_slab.Alloc<CallstackFrameData>(); m_callstackFrameStaging = m_slab.Alloc<CallstackFrameData>();
@ -3103,8 +3154,8 @@ void Worker::ProcessCallstackFrame( const QueueCallstackFrame& ev )
if( --m_pendingCallstackSubframes == 0 ) if( --m_pendingCallstackSubframes == 0 )
{ {
assert( m_data.callstackFrameMap.find( m_callstackFrameStagingPtr ) == m_data.callstackFrameMap.end() ); assert( m_data.callstackFrameMap.find( PackPointer( m_callstackFrameStagingPtr ) ) == m_data.callstackFrameMap.end() );
m_data.callstackFrameMap.emplace( m_callstackFrameStagingPtr, m_callstackFrameStaging ); m_data.callstackFrameMap.emplace( PackPointer( m_callstackFrameStagingPtr ), m_callstackFrameStaging );
m_callstackFrameStaging = nullptr; m_callstackFrameStaging = nullptr;
} }
} }
@ -3803,14 +3854,14 @@ void Worker::Write( FileWrite& f )
auto cs = m_data.callstackPayload[i]; auto cs = m_data.callstackPayload[i];
uint8_t csz = cs->size(); uint8_t csz = cs->size();
f.Write( &csz, sizeof( csz ) ); 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(); sz = m_data.callstackFrameMap.size();
f.Write( &sz, sizeof( sz ) ); f.Write( &sz, sizeof( sz ) );
for( auto& frame : m_data.callstackFrameMap ) 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->size, sizeof( frame.second->size ) );
f.Write( frame.second->data, sizeof( CallstackFrame ) * 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; flat_hash_map<int32_t, uint64_t> sourceLocationZonesCnt;
#endif #endif
flat_hash_map<VarArray<uint64_t>*, uint32_t, VarArrayHasherPOT<uint64_t>, VarArrayComparator<uint64_t>> callstackMap; flat_hash_map<VarArray<CallstackFrameId>*, uint32_t, VarArrayHasherPOT<CallstackFrameId>, VarArrayComparator<CallstackFrameId>> callstackMap;
Vector<VarArray<uint64_t>*> callstackPayload; Vector<VarArray<CallstackFrameId>*> callstackPayload;
flat_hash_map<uint64_t, CallstackFrameData*> callstackFrameMap; flat_hash_map<CallstackFrameId, CallstackFrameData*, CallstackFrameIdHash, CallstackFrameIdCompare> callstackFrameMap;
std::map<uint32_t, LockMap> lockMap; std::map<uint32_t, LockMap> lockMap;
@ -244,8 +244,8 @@ public:
const Vector<ThreadData*>& GetThreadData() const { return m_data.threads; } const Vector<ThreadData*>& GetThreadData() const { return m_data.threads; }
const MemData& GetMemData() const { return m_data.memory; } const MemData& GetMemData() const { return m_data.memory; }
const VarArray<uint64_t>& GetCallstack( uint32_t idx ) const { return *m_data.callstackPayload[idx]; } const VarArray<CallstackFrameId>& GetCallstack( uint32_t idx ) const { return *m_data.callstackPayload[idx]; }
const CallstackFrameData* GetCallstackFrame( uint64_t ptr ) const; const CallstackFrameData* GetCallstackFrame( const CallstackFrameId& ptr ) const;
uint64_t GetCanonicalPointer( const CallstackFrameId& id ) const; uint64_t GetCanonicalPointer( const CallstackFrameId& id ) const;
const CrashEvent& GetCrashEvent() const { return m_data.m_crashEvent; } const CrashEvent& GetCrashEvent() const { return m_data.m_crashEvent; }