diff --git a/server/TracyEvent.hpp b/server/TracyEvent.hpp index 8e00a90a..cb04a5ad 100644 --- a/server/TracyEvent.hpp +++ b/server/TracyEvent.hpp @@ -619,6 +619,15 @@ struct GhostZone enum { GhostZoneSize = sizeof( GhostZone ) }; + +struct ChildSample +{ + Int48 time; + uint64_t addr; +}; + +enum { ChildSampleSize = sizeof( ChildSample ) }; + #pragma pack() diff --git a/server/TracySourceView.cpp b/server/TracySourceView.cpp index afadc8ae..e9dc544e 100644 --- a/server/TracySourceView.cpp +++ b/server/TracySourceView.cpp @@ -4507,9 +4507,9 @@ void SourceView::GatherAdditionalIpStats( uint64_t baseAddr, AddrStatData& as, c if( as.ipCountAsm.find( ip ) != as.ipCountAsm.end() ) continue; auto cp = worker.GetChildSamples( ip ); if( !cp ) continue; - auto it = std::lower_bound( cp->begin(), cp->end(), view.m_statRange.min, [] ( const auto& lhs, const auto& rhs ) { return lhs.Val() < rhs; } ); + auto it = std::lower_bound( cp->begin(), cp->end(), view.m_statRange.min, [] ( const auto& lhs, const auto& rhs ) { return lhs.time.Val() < rhs; } ); if( it == cp->end() ) continue; - auto end = std::lower_bound( it, cp->end(), view.m_statRange.max, [] ( const auto& lhs, const auto& rhs ) { return lhs.Val() < rhs; } ); + auto end = std::lower_bound( it, cp->end(), view.m_statRange.max, [] ( const auto& lhs, const auto& rhs ) { return lhs.time.Val() < rhs; } ); const auto ccnt = uint64_t( end - it ); as.ipCountAsm.emplace( ip, AddrStat { 0, ccnt } ); as.ipTotalAsm.ext += ccnt; diff --git a/server/TracyWorker.cpp b/server/TracyWorker.cpp index b61e9e2e..45be7d6a 100644 --- a/server/TracyWorker.cpp +++ b/server/TracyWorker.cpp @@ -2067,18 +2067,20 @@ Worker::Worker( FileRead& f, EventType::Type eventMask, bool bgTasks ) it->second.push_back_non_empty( SampleDataRange { time, tid, ip } ); } } + auto childAddr = GetCanonicalPointer( callstack[0] ); for( uint16_t i=1; i( time ) ); + m_data.childSamples.emplace( addr, Vector( ChildSample { time, childAddr } ) ); } else { - it->second.push_back_non_empty( time ); + it->second.push_back_non_empty( ChildSample { time, childAddr } ); } + childAddr = addr; } } } @@ -2088,7 +2090,7 @@ Worker::Worker( FileRead& f, EventType::Type eventMask, bool bgTasks ) } for( auto& v : m_data.childSamples ) { - pdqsort_branchless( v.second.begin(), v.second.end(), []( const auto& lhs, const auto& rhs ) { return lhs.Val() < rhs.Val(); } ); + pdqsort_branchless( v.second.begin(), v.second.end(), []( const auto& lhs, const auto& rhs ) { return lhs.time.Val() < rhs.time.Val(); } ); } std::lock_guard lock( m_data.lock ); m_data.symbolSamplesReady = true; @@ -2501,7 +2503,7 @@ const Vector* Worker::GetSamplesForSymbol( uint64_t symAddr ) c return &it->second; } -const Vector* Worker::GetChildSamples( uint64_t addr ) const +const Vector* Worker::GetChildSamples( uint64_t addr ) const { assert( m_data.symbolSamplesReady ); auto it = m_data.childSamples.find( addr ); @@ -6353,18 +6355,20 @@ void Worker::ProcessCallstackSampleImplStats( const SampleData& sd, ThreadData& } } + auto childAddr = GetCanonicalPointer( cs[0] ); for( uint16_t i=1; i( sd.time ) ); + m_data.childSamples.emplace( addr, Vector( ChildSample { sd.time, childAddr } ) ); } else { - it->second.push_back_non_empty( sd.time ); + it->second.push_back_non_empty( ChildSample { sd.time, childAddr } ); } + childAddr = addr; } const auto framesKnown = UpdateSampleStatistics( callstack, 1, true ); diff --git a/server/TracyWorker.hpp b/server/TracyWorker.hpp index 18edef2e..9e73bce8 100644 --- a/server/TracyWorker.hpp +++ b/server/TracyWorker.hpp @@ -301,7 +301,7 @@ private: unordered_flat_map> instructionPointersMap; unordered_flat_map> symbolSamples; unordered_flat_map, CallstackFrameIdHash, CallstackFrameIdCompare> pendingSymbolSamples; - unordered_flat_map> childSamples; + unordered_flat_map> childSamples; bool newFramesWereReceived = false; bool callstackSamplesReady = false; bool newContextSwitchesReceived = false; @@ -523,7 +523,7 @@ public: const VarArray& GetParentCallstack( uint32_t idx ) const { return *m_data.parentCallstackPayload[idx]; } const CallstackFrameData* GetParentCallstackFrame( const CallstackFrameId& ptr ) const; const Vector* GetSamplesForSymbol( uint64_t symAddr ) const; - const Vector* GetChildSamples( uint64_t addr ) const; + const Vector* GetChildSamples( uint64_t addr ) const; #endif const CrashEvent& GetCrashEvent() const { return m_data.crashEvent; }