From 66b8a13e7785e9a497c78aaa4f8fa601cfbd96c8 Mon Sep 17 00:00:00 2001 From: Bartosz Taudul Date: Sun, 3 Mar 2019 17:34:56 +0100 Subject: [PATCH] Store callstack alloc payloads. --- server/TracyWorker.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++ server/TracyWorker.hpp | 33 ++++++++++++++++++ 2 files changed, 109 insertions(+) diff --git a/server/TracyWorker.cpp b/server/TracyWorker.cpp index c06fd331..4b9b45ec 100644 --- a/server/TracyWorker.cpp +++ b/server/TracyWorker.cpp @@ -1772,6 +1772,9 @@ bool Worker::DispatchProcess( const QueueItem& ev, char*& ptr ) case QueueType::FrameName: HandleFrameName( ev.stringTransfer.ptr, ptr, sz ); break; + case QueueType::CallstackAllocPayload: + AddCallstackAllocPayload( ev.stringTransfer.ptr, ptr, sz ); + break; default: assert( false ); break; @@ -2127,6 +2130,79 @@ void Worker::AddCallstackPayload( uint64_t ptr, char* _data, size_t _sz ) 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(); + memcpy( frame, &cf, sizeof( CallstackFrame ) ); + auto frameData = m_slab.Alloc(); + 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 ) + sz * sizeof( CallstackFrameId ); + auto mem = (char*)m_slab.AllocRaw( memsize ); + memcpy( mem, stack, sizeof( CallstackFrameId ) * sz ); + + auto arr = (VarArray*)( mem + sz * sizeof( CallstackFrameId ) ); + new(arr) VarArray( 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 ) { if( plot->data.empty() ) diff --git a/server/TracyWorker.hpp b/server/TracyWorker.hpp index f1e09b98..f69e7570 100644 --- a/server/TracyWorker.hpp +++ b/server/TracyWorker.hpp @@ -111,6 +111,36 @@ private: 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; isize; 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; isize; i++ ) + { + if( memcmp( lhs->data + i, rhs->data + i, sizeof( CallstackFrame ) ) != 0 ) return false; + } + return true; + } + }; + struct DataBlock { DataBlock() : zonesCnt( 0 ), lastTime( 0 ), frameOffset( 0 ), threadLast( std::numeric_limits::max(), 0 ) {} @@ -146,6 +176,7 @@ private: flat_hash_map*, uint32_t, VarArrayHasherPOT, VarArrayComparator> callstackMap; Vector*> callstackPayload; flat_hash_map callstackFrameMap; + flat_hash_map revFrameMap; std::map lockMap; @@ -394,6 +425,7 @@ private: 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 AddCallstackAllocPayload( uint64_t ptr, char* data, size_t sz ); void InsertPlot( PlotData* plot, int64_t time, double val ); void HandlePlotName( uint64_t name, char* str, size_t sz ); @@ -464,6 +496,7 @@ private: CallstackFrameData* m_callstackFrameStaging; uint64_t m_callstackFrameStagingPtr; + uint64_t m_callstackAllocNextIdx = 0; uint64_t m_lastMemActionCallstack; bool m_lastMemActionWasAlloc;