Store callstack alloc payloads.

This commit is contained in:
Bartosz Taudul 2019-03-03 17:34:56 +01:00
parent 9fc022346b
commit 66b8a13e77
2 changed files with 109 additions and 0 deletions

View File

@ -1772,6 +1772,9 @@ bool Worker::DispatchProcess( const QueueItem& ev, char*& ptr )
case QueueType::FrameName: case QueueType::FrameName:
HandleFrameName( ev.stringTransfer.ptr, ptr, sz ); HandleFrameName( ev.stringTransfer.ptr, ptr, sz );
break; break;
case QueueType::CallstackAllocPayload:
AddCallstackAllocPayload( ev.stringTransfer.ptr, ptr, sz );
break;
default: default:
assert( false ); assert( false );
break; break;
@ -2127,6 +2130,79 @@ void Worker::AddCallstackPayload( uint64_t ptr, char* _data, size_t _sz )
m_pendingCallstacks.emplace( ptr, idx ); m_pendingCallstacks.emplace( ptr, idx );
} }
void Worker::AddCallstackAllocPayload( uint64_t ptr, char* data, size_t _sz )
{
assert( m_pendingCallstacks.find( ptr ) == m_pendingCallstacks.end() );
CallstackFrameId stack[64];
const auto sz = *(uint32_t*)data; data += 4;
assert( sz <= 64 );
for( uint32_t i=0; i<sz; i++ )
{
uint32_t sz;
CallstackFrame cf;
memcpy( &cf.line, data, 4 ); data += 4;
memcpy( &sz, data, 4 ); data += 4;
cf.name = StoreString( data, sz ).idx; data += sz;
memcpy( &sz, data, 4 ); data += 4;
cf.file = StoreString( data, sz ).idx; data += sz;
CallstackFrameData cfd = { &cf, 1 };
CallstackFrameId id;
auto it = m_data.revFrameMap.find( &cfd );
if( it == m_data.revFrameMap.end() )
{
auto frame = m_slab.Alloc<CallstackFrame>();
memcpy( frame, &cf, sizeof( CallstackFrame ) );
auto frameData = m_slab.Alloc<CallstackFrameData>();
frameData->data = frame;
frameData->size = 1;
id.idx = m_callstackAllocNextIdx++;
id.sel = 1;
m_data.callstackFrameMap.emplace( id, frameData );
m_data.revFrameMap.emplace( frameData, id );
}
else
{
id = it->second;
}
stack[i] = id;
}
const auto memsize = sizeof( VarArray<CallstackFrameId> ) + sz * sizeof( CallstackFrameId );
auto mem = (char*)m_slab.AllocRaw( memsize );
memcpy( mem, stack, sizeof( CallstackFrameId ) * sz );
auto arr = (VarArray<CallstackFrameId>*)( mem + sz * sizeof( CallstackFrameId ) );
new(arr) VarArray<CallstackFrameId>( sz, (CallstackFrameId*)mem );
uint32_t idx;
auto it = m_data.callstackMap.find( arr );
if( it == m_data.callstackMap.end() )
{
idx = m_data.callstackPayload.size();
m_data.callstackMap.emplace( arr, idx );
m_data.callstackPayload.push_back( arr );
for( auto& frame : *arr )
{
auto fit = m_data.callstackFrameMap.find( frame );
if( fit == m_data.callstackFrameMap.end() )
{
m_pendingCallstackFrames++;
ServerQuery( ServerQueryCallstackFrame, GetCanonicalPointer( frame ) );
}
}
}
else
{
idx = it->second;
m_slab.Unalloc( memsize );
}
m_pendingCallstacks.emplace( ptr, idx );
}
void Worker::InsertPlot( PlotData* plot, int64_t time, double val ) void Worker::InsertPlot( PlotData* plot, int64_t time, double val )
{ {
if( plot->data.empty() ) if( plot->data.empty() )

View File

@ -111,6 +111,36 @@ private:
bool operator()( const CallstackFrameId& lhs, const CallstackFrameId& rhs ) { return lhs.data == rhs.data; } bool operator()( const CallstackFrameId& lhs, const CallstackFrameId& rhs ) { return lhs.data == rhs.data; }
}; };
struct RevFrameHash
{
size_t operator()( const CallstackFrameData* data )
{
size_t hash = data->size;
for( uint8_t i=0; i<data->size; i++ )
{
const auto& v = data->data[i];
hash = ( ( hash << 5 ) + hash ) ^ size_t( v.line );
hash = ( ( hash << 5 ) + hash ) ^ size_t( v.file.__data );
hash = ( ( hash << 5 ) + hash ) ^ size_t( v.name.__data );
}
return hash;
}
typedef tracy::power_of_two_hash_policy hash_policy;
};
struct RevFrameComp
{
bool operator()( const CallstackFrameData* lhs, const CallstackFrameData* rhs )
{
if( lhs->size != rhs->size ) return false;
for( uint8_t i=0; i<lhs->size; i++ )
{
if( memcmp( lhs->data + i, rhs->data + i, sizeof( CallstackFrame ) ) != 0 ) return false;
}
return true;
}
};
struct DataBlock struct DataBlock
{ {
DataBlock() : zonesCnt( 0 ), lastTime( 0 ), frameOffset( 0 ), threadLast( std::numeric_limits<uint64_t>::max(), 0 ) {} DataBlock() : zonesCnt( 0 ), lastTime( 0 ), frameOffset( 0 ), threadLast( std::numeric_limits<uint64_t>::max(), 0 ) {}
@ -146,6 +176,7 @@ private:
flat_hash_map<VarArray<CallstackFrameId>*, uint32_t, VarArrayHasherPOT<CallstackFrameId>, VarArrayComparator<CallstackFrameId>> callstackMap; flat_hash_map<VarArray<CallstackFrameId>*, uint32_t, VarArrayHasherPOT<CallstackFrameId>, VarArrayComparator<CallstackFrameId>> callstackMap;
Vector<VarArray<CallstackFrameId>*> callstackPayload; Vector<VarArray<CallstackFrameId>*> callstackPayload;
flat_hash_map<CallstackFrameId, CallstackFrameData*, CallstackFrameIdHash, CallstackFrameIdCompare> callstackFrameMap; flat_hash_map<CallstackFrameId, CallstackFrameData*, CallstackFrameIdHash, CallstackFrameIdCompare> callstackFrameMap;
flat_hash_map<CallstackFrameData*, CallstackFrameId, RevFrameHash, RevFrameComp> revFrameMap;
std::map<uint32_t, LockMap> lockMap; std::map<uint32_t, LockMap> lockMap;
@ -394,6 +425,7 @@ private:
void AddCustomString( uint64_t ptr, char* str, size_t sz ); void AddCustomString( uint64_t ptr, char* str, size_t sz );
tracy_force_inline void AddCallstackPayload( uint64_t ptr, char* data, size_t sz ); tracy_force_inline void AddCallstackPayload( uint64_t ptr, char* data, size_t sz );
tracy_force_inline void AddCallstackAllocPayload( uint64_t ptr, char* data, size_t sz );
void InsertPlot( PlotData* plot, int64_t time, double val ); void InsertPlot( PlotData* plot, int64_t time, double val );
void HandlePlotName( uint64_t name, char* str, size_t sz ); void HandlePlotName( uint64_t name, char* str, size_t sz );
@ -464,6 +496,7 @@ private:
CallstackFrameData* m_callstackFrameStaging; CallstackFrameData* m_callstackFrameStaging;
uint64_t m_callstackFrameStagingPtr; uint64_t m_callstackFrameStagingPtr;
uint64_t m_callstackAllocNextIdx = 0;
uint64_t m_lastMemActionCallstack; uint64_t m_lastMemActionCallstack;
bool m_lastMemActionWasAlloc; bool m_lastMemActionWasAlloc;