From 2df739439812c0a2cf8dba5769119275c39cdefe Mon Sep 17 00:00:00 2001 From: Ivona Stojanovic Date: Tue, 14 Apr 2026 19:50:19 +0200 Subject: [PATCH] Fix inverted flamegraph width The inverted view used thread presence as a proxy for self time. This missed self samples on C-level wrapper frames like _run_code, where the node's thread always appears in its children too. Those samples were silently dropped, causing the chart to render narrower than full width. Now uses the explicit self field on each node instead of the thread heuristic. --- .../sampling/_flamegraph_assets/flamegraph.js | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/Lib/profiling/sampling/_flamegraph_assets/flamegraph.js b/Lib/profiling/sampling/_flamegraph_assets/flamegraph.js index d7a8890d4a1ad9..3f884c4c690fd1 100644 --- a/Lib/profiling/sampling/_flamegraph_assets/flamegraph.js +++ b/Lib/profiling/sampling/_flamegraph_assets/flamegraph.js @@ -1063,11 +1063,7 @@ function populateStats(data) { funcname = funcname || 'unknown'; if (filename !== 'unknown' && funcname !== 'unknown' && node.value > 0) { - let childrenValue = 0; - if (node.children) { - childrenValue = node.children.reduce((sum, child) => sum + child.value, 0); - } - const directSamples = Math.max(0, node.value - childrenValue); + const directSamples = node.self || 0; const funcKey = `${filename}:${node.lineno || '?'}:${funcname}`; @@ -1345,14 +1341,13 @@ function processLeaf(invertedRoot, path, leafNode, isDifferential) { } function traverseInvert(path, currentNode, invertedRoot, isDifferential) { - const children = currentNode.children || []; - const childThreads = new Set(children.flatMap(c => c.threads || [])); - const selfThreads = (currentNode.threads || []).filter(t => !childThreads.has(t)); + const selfValue = currentNode.self || 0; - if (selfThreads.length > 0) { - processLeaf(invertedRoot, path, { ...currentNode, threads: selfThreads }, isDifferential); + if (selfValue > 0) { + processLeaf(invertedRoot, path, { ...currentNode, value: selfValue }, isDifferential); } + const children = currentNode.children || []; children.forEach(child => traverseInvert(path.concat([child]), child, invertedRoot, isDifferential)); }