mirror of
https://github.com/wolfpld/tracy.git
synced 2024-11-10 10:41:50 +00:00
Implement callstack tree of memory allocations.
This commit is contained in:
parent
c2c0f887aa
commit
df14cf5330
@ -171,6 +171,16 @@ struct CallstackFrame
|
|||||||
|
|
||||||
enum { CallstackFrameSize = sizeof( CallstackFrame ) };
|
enum { CallstackFrameSize = sizeof( CallstackFrame ) };
|
||||||
|
|
||||||
|
struct CallstackFrameTree
|
||||||
|
{
|
||||||
|
uint64_t frame;
|
||||||
|
uint64_t allocExclusive, allocInclusive;
|
||||||
|
uint32_t countExclusive, countInclusive;
|
||||||
|
std::vector<CallstackFrameTree> children;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { CallstackFrameTreeSize = sizeof( CallstackFrameTree ) };
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
|
|
||||||
|
@ -6006,6 +6006,47 @@ void View::ListMemData( T ptr, T end, std::function<void(T&)> DrawAddress, const
|
|||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline CallstackFrameTree* GetFrameTreeItem( std::vector<CallstackFrameTree>& tree, uint64_t idx )
|
||||||
|
{
|
||||||
|
auto it = std::find_if( tree.begin(), tree.end(), [idx] ( const auto& v ) { return v.frame == idx; } );
|
||||||
|
if( it == tree.end() )
|
||||||
|
{
|
||||||
|
tree.emplace_back( CallstackFrameTree { idx } );
|
||||||
|
return &tree.back();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return &*it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<CallstackFrameTree> View::GetCallstackFrameTree( const MemData& mem ) const
|
||||||
|
{
|
||||||
|
std::vector<CallstackFrameTree> root;
|
||||||
|
for( auto& ev : mem.data )
|
||||||
|
{
|
||||||
|
if( ev.csAlloc == 0 ) continue;
|
||||||
|
auto& cs = m_worker.GetCallstack( ev.csAlloc );
|
||||||
|
|
||||||
|
auto base = cs.back();
|
||||||
|
auto treePtr = GetFrameTreeItem( root, base );
|
||||||
|
treePtr->countInclusive++;
|
||||||
|
treePtr->allocInclusive += ev.size;
|
||||||
|
|
||||||
|
for( int i = int( cs.size() ) - 2; i >= 0; i-- )
|
||||||
|
{
|
||||||
|
treePtr = GetFrameTreeItem( treePtr->children, cs[i] );
|
||||||
|
treePtr->countInclusive++;
|
||||||
|
treePtr->allocInclusive += ev.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
treePtr->countExclusive++;
|
||||||
|
treePtr->allocExclusive += ev.size;
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
enum { ChunkBits = 10 };
|
enum { ChunkBits = 10 };
|
||||||
enum { PageBits = 10 };
|
enum { PageBits = 10 };
|
||||||
enum { PageSize = 1 << PageBits };
|
enum { PageSize = 1 << PageBits };
|
||||||
@ -6265,9 +6306,93 @@ void View::DrawMemory()
|
|||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
if( ImGui::TreeNode( "Call stack tree" ) )
|
||||||
|
{
|
||||||
|
ImGui::TextDisabled( "Press ctrl key to display allocation info tooltip." );
|
||||||
|
|
||||||
|
auto& mem = m_worker.GetMemData();
|
||||||
|
auto tree = GetCallstackFrameTree( mem );
|
||||||
|
|
||||||
|
DrawFrameTreeLevel( tree );
|
||||||
|
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void View::DrawFrameTreeLevel( std::vector<CallstackFrameTree>& tree ) const
|
||||||
|
{
|
||||||
|
auto& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
pdqsort_branchless( tree.begin(), tree.end(), [] ( const auto& lhs, const auto& rhs ) { return lhs.allocInclusive > rhs.allocInclusive; } );
|
||||||
|
for( auto& v : tree )
|
||||||
|
{
|
||||||
|
auto frame = m_worker.GetCallstackFrame( v.frame );
|
||||||
|
bool expand = false;
|
||||||
|
if( v.children.empty() )
|
||||||
|
{
|
||||||
|
ImGui::Indent( ImGui::GetTreeNodeToLabelSpacing() );
|
||||||
|
ImGui::Text( "%s", m_worker.GetString( frame->name ) );
|
||||||
|
ImGui::Unindent( ImGui::GetTreeNodeToLabelSpacing() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui::PushID( idx++ );
|
||||||
|
expand = ImGui::TreeNode( m_worker.GetString( frame->name ) );
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( io.KeyCtrl && ImGui::IsItemHovered() )
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
|
||||||
|
ImGui::TextColored( ImVec4( 0.4, 0.4, 0.1, 1.0 ), "Inclusive alloc size:" );
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextColored( ImVec4( 0.8, 0.8, 0.2, 1.0 ), "%s", MemSizeToString( v.allocInclusive ) );
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextColored( ImVec4( 0.4, 0.4, 0.1, 1.0 ), "count:" );
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextColored( ImVec4( 0.8, 0.8, 0.2, 1.0 ), "%s", RealToString( v.countInclusive, true ) );
|
||||||
|
|
||||||
|
ImGui::TextColored( ImVec4( 0.1, 0.4, 0.4, 1.0 ), "Exclusive alloc size:" );
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextColored( ImVec4( 0.2, 0.8, 0.8, 1.0 ), "%s", MemSizeToString( v.allocExclusive ) );
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextColored( ImVec4( 0.1, 0.4, 0.4, 1.0 ), "count:" );
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextColored( ImVec4( 0.2, 0.8, 0.8, 1.0 ), "%s", RealToString( v.countExclusive, true ) );
|
||||||
|
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( v.allocExclusive != v.allocInclusive )
|
||||||
|
{
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextDisabled( "%s:%i", m_worker.GetString( frame->file ), frame->line );
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextColored( ImVec4( 0.4, 0.4, 0.1, 1.0 ), "I:" );
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextColored( ImVec4( 0.8, 0.8, 0.2, 1.0 ), "%s (%s)", MemSizeToString( v.allocInclusive ), RealToString( v.countInclusive, true ) );
|
||||||
|
}
|
||||||
|
if( v.allocExclusive != 0 )
|
||||||
|
{
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextColored( ImVec4( 0.1, 0.4, 0.4, 1.0 ), "E:" );
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextColored( ImVec4( 0.2, 0.8, 0.8, 1.0 ), "%s (%s)", MemSizeToString( v.allocExclusive ), RealToString( v.countExclusive, true ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( expand )
|
||||||
|
{
|
||||||
|
DrawFrameTreeLevel( v.children );
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<int8_t*, size_t> View::GetMemoryPages() const
|
std::pair<int8_t*, size_t> View::GetMemoryPages() const
|
||||||
{
|
{
|
||||||
const auto& mem = m_worker.GetMemData();
|
const auto& mem = m_worker.GetMemData();
|
||||||
|
@ -90,6 +90,9 @@ private:
|
|||||||
template<class T>
|
template<class T>
|
||||||
void ListMemData( T ptr, T end, std::function<void(T&)> DrawAddress, const char* id = nullptr );
|
void ListMemData( T ptr, T end, std::function<void(T&)> DrawAddress, const char* id = nullptr );
|
||||||
|
|
||||||
|
std::vector<CallstackFrameTree> GetCallstackFrameTree( const MemData& mem ) const;
|
||||||
|
void DrawFrameTreeLevel( std::vector<CallstackFrameTree>& tree ) const;
|
||||||
|
|
||||||
void DrawInfoWindow();
|
void DrawInfoWindow();
|
||||||
void DrawZoneInfoWindow();
|
void DrawZoneInfoWindow();
|
||||||
void DrawGpuInfoWindow();
|
void DrawGpuInfoWindow();
|
||||||
|
Loading…
Reference in New Issue
Block a user