gh-138122: Convert GIL/GC/exception stats from tiles to progress bars (#143177)

This commit is contained in:
ivonastojanovic 2025-12-25 19:22:54 +01:00 committed by GitHub
parent b9a4806430
commit 59ede34c8c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 110 additions and 90 deletions

View file

@ -405,21 +405,18 @@ .summary-label {
text-overflow: ellipsis;
}
/* Efficiency Bar */
.efficiency-section {
margin-top: 10px;
padding-top: 10px;
border-top: 1px solid var(--border);
}
/* --------------------------------------------------------------------------
Progress Bars
-------------------------------------------------------------------------- */
.efficiency-header {
.bar-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 5px;
}
.efficiency-label {
.bar-label {
font-size: 9px;
font-weight: 600;
color: var(--text-secondary);
@ -427,21 +424,21 @@ .efficiency-label {
letter-spacing: 0.2px;
}
.efficiency-value {
.bar-value {
font-family: var(--font-mono);
font-size: 11px;
font-weight: 700;
color: var(--accent);
}
.efficiency-bar {
.bar {
height: 6px;
background: var(--bg-tertiary);
border-radius: 3px;
overflow: hidden;
}
.efficiency-fill {
.bar-fill {
height: 100%;
background: linear-gradient(90deg, #28a745 0%, #20c997 50%, #17a2b8 100%);
border-radius: 3px;
@ -450,7 +447,7 @@ .efficiency-fill {
overflow: hidden;
}
.efficiency-fill::after {
.bar-fill::after {
content: '';
position: absolute;
top: 0;
@ -467,68 +464,56 @@ .efficiency-fill::after {
}
/* --------------------------------------------------------------------------
Thread Stats Grid (in Sidebar)
Efficiency Section Container
-------------------------------------------------------------------------- */
.efficiency-section {
margin-top: 10px;
padding-top: 10px;
border-top: 1px solid var(--border);
}
/* --------------------------------------------------------------------------
Thread Stats Progress Bars (in Sidebar)
-------------------------------------------------------------------------- */
.thread-stats-section {
display: block;
}
.stats-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
.stats-container {
display: flex;
flex-direction: column;
gap: 10px;
}
.stat-tile {
background: var(--bg-primary);
border-radius: 8px;
padding: 10px;
text-align: center;
border: 2px solid var(--border);
transition: all var(--transition-fast);
.stat-item {
animation: fadeIn 0.4s ease-out backwards;
animation-delay: calc(var(--i, 0) * 0.05s);
}
.stat-tile:nth-child(1) { --i: 0; }
.stat-tile:nth-child(2) { --i: 1; }
.stat-tile:nth-child(3) { --i: 2; }
.stat-tile:nth-child(4) { --i: 3; }
.stat-item:nth-child(1) { --i: 0; }
.stat-item:nth-child(2) { --i: 1; }
.stat-item:nth-child(3) { --i: 2; }
.stat-item:nth-child(4) { --i: 3; }
.stat-item:nth-child(5) { --i: 4; }
.stat-tile:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-sm);
/* Color variants for bar-fill */
.bar-fill--green {
background: linear-gradient(90deg, #28a745 0%, #20c997 100%);
}
.stat-tile-value {
font-family: var(--font-mono);
font-size: 16px;
font-weight: 700;
color: var(--text-primary);
line-height: 1.2;
.bar-fill--yellow {
background: linear-gradient(90deg, #ffc107 0%, #ffdb4d 100%);
}
.stat-tile-label {
font-size: 9px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.3px;
color: var(--text-muted);
margin-top: 2px;
.bar-fill--purple {
background: linear-gradient(90deg, #6f42c1 0%, #9b6dd6 100%);
}
/* Stat tile color variants */
.stat-tile--green { --tile-color: 40, 167, 69; --tile-text: #28a745; }
.stat-tile--red { --tile-color: 220, 53, 69; --tile-text: #dc3545; }
.stat-tile--yellow { --tile-color: 255, 193, 7; --tile-text: #d39e00; }
.stat-tile--purple { --tile-color: 111, 66, 193; --tile-text: #6f42c1; }
.stat-tile[class*="--"] {
border-color: rgba(var(--tile-color), 0.4);
background: linear-gradient(135deg, rgba(var(--tile-color), 0.08) 0%, var(--bg-primary) 100%);
.bar-fill--red {
background: linear-gradient(90deg, #dc3545 0%, #ff6b7a 100%);
}
.stat-tile[class*="--"] .stat-tile-value { color: var(--tile-text); }
/* --------------------------------------------------------------------------
Hotspot Cards
@ -985,10 +970,6 @@ @media (max-width: 600px) {
.brand-info {
display: none;
}
.stats-grid {
grid-template-columns: 1fr;
}
}
/* --------------------------------------------------------------------------

View file

@ -742,24 +742,38 @@ function populateThreadStats(data, selectedThreadId = null) {
if (gilReleasedStat) gilReleasedStat.style.display = 'block';
if (gilWaitingStat) gilWaitingStat.style.display = 'block';
const gilHeldPct = threadStats.has_gil_pct || 0;
const gilHeldPctElem = document.getElementById('gil-held-pct');
if (gilHeldPctElem) gilHeldPctElem.textContent = `${(threadStats.has_gil_pct || 0).toFixed(1)}%`;
if (gilHeldPctElem) gilHeldPctElem.textContent = `${gilHeldPct.toFixed(1)}%`;
const gilHeldFill = document.getElementById('gil-held-fill');
if (gilHeldFill) gilHeldFill.style.width = `${gilHeldPct}%`;
const gilReleasedPctElem = document.getElementById('gil-released-pct');
// GIL Released = not holding GIL and not waiting for it
const gilReleasedPct = Math.max(0, 100 - (threadStats.has_gil_pct || 0) - (threadStats.gil_requested_pct || 0));
const gilReleasedPctElem = document.getElementById('gil-released-pct');
if (gilReleasedPctElem) gilReleasedPctElem.textContent = `${gilReleasedPct.toFixed(1)}%`;
const gilReleasedFill = document.getElementById('gil-released-fill');
if (gilReleasedFill) gilReleasedFill.style.width = `${gilReleasedPct}%`;
const gilWaitingPct = threadStats.gil_requested_pct || 0;
const gilWaitingPctElem = document.getElementById('gil-waiting-pct');
if (gilWaitingPctElem) gilWaitingPctElem.textContent = `${(threadStats.gil_requested_pct || 0).toFixed(1)}%`;
if (gilWaitingPctElem) gilWaitingPctElem.textContent = `${gilWaitingPct.toFixed(1)}%`;
const gilWaitingFill = document.getElementById('gil-waiting-fill');
if (gilWaitingFill) gilWaitingFill.style.width = `${gilWaitingPct}%`;
}
const gcPct = threadStats.gc_pct || 0;
const gcPctElem = document.getElementById('gc-pct');
if (gcPctElem) gcPctElem.textContent = `${(threadStats.gc_pct || 0).toFixed(1)}%`;
if (gcPctElem) gcPctElem.textContent = `${gcPct.toFixed(1)}%`;
const gcFill = document.getElementById('gc-fill');
if (gcFill) gcFill.style.width = `${gcPct}%`;
// Exception stats
const excPct = threadStats.has_exception_pct || 0;
const excPctElem = document.getElementById('exc-pct');
if (excPctElem) excPctElem.textContent = `${(threadStats.has_exception_pct || 0).toFixed(1)}%`;
if (excPctElem) excPctElem.textContent = `${excPct.toFixed(1)}%`;
const excFill = document.getElementById('exc-fill');
if (excFill) excFill.style.width = `${excPct}%`;
}
// ============================================================================

View file

@ -159,21 +159,21 @@ <h3 class="section-title">Profile Summary</h3>
</div>
<!-- Efficiency Bar -->
<div class="efficiency-section" id="efficiency-section" style="display: none;">
<div class="efficiency-header">
<span class="efficiency-label">Sampling Efficiency</span>
<span class="efficiency-value" id="stat-efficiency">--</span>
<div class="bar-header">
<span class="bar-label">Sampling Efficiency</span>
<span class="bar-value" id="stat-efficiency">--</span>
</div>
<div class="efficiency-bar">
<div class="efficiency-fill" id="efficiency-fill"></div>
<div class="bar">
<div class="bar-fill" id="efficiency-fill"></div>
</div>
<div class="missed-samples-header">
<span class="efficiency-label">Missed samples</span>
<span class="efficiency-value" id="stat-missed-samples">--</span>
<div class="bar-header">
<span class="bar-label">Missed samples</span>
<span class="bar-value" id="stat-missed-samples">--</span>
</div>
<div class="efficiency-bar">
<div class="efficiency-fill" id="missed-samples-fill"></div>
<div class="bar">
<div class="bar-fill" id="missed-samples-fill"></div>
</div>
</div>
</div>
</section>
@ -187,26 +187,51 @@ <h3 class="section-title">Runtime Stats</h3>
</svg>
</button>
<div class="section-content">
<div class="stats-grid">
<div class="stat-tile stat-tile--green" id="gil-held-stat">
<div class="stat-tile-value" id="gil-held-pct">--</div>
<div class="stat-tile-label">GIL Held</div>
<div class="stats-container">
<div class="stat-item" id="gil-held-stat">
<div class="bar-header">
<span class="bar-label">GIL Held</span>
<span class="bar-value" id="gil-held-pct">--</span>
</div>
<div class="bar">
<div class="bar-fill bar-fill--green" id="gil-held-fill"></div>
</div>
</div>
<div class="stat-tile stat-tile--red" id="gil-released-stat">
<div class="stat-tile-value" id="gil-released-pct">--</div>
<div class="stat-tile-label">GIL Released</div>
<div class="stat-item" id="gil-released-stat">
<div class="bar-header">
<span class="bar-label">GIL Released</span>
<span class="bar-value" id="gil-released-pct">--</span>
</div>
<div class="bar">
<div class="bar-fill bar-fill--red" id="gil-released-fill"></div>
</div>
</div>
<div class="stat-tile stat-tile--yellow" id="gil-waiting-stat">
<div class="stat-tile-value" id="gil-waiting-pct">--</div>
<div class="stat-tile-label">Waiting GIL</div>
<div class="stat-item" id="gil-waiting-stat">
<div class="bar-header">
<span class="bar-label">Waiting GIL</span>
<span class="bar-value" id="gil-waiting-pct">--</span>
</div>
<div class="bar">
<div class="bar-fill bar-fill--yellow" id="gil-waiting-fill"></div>
</div>
</div>
<div class="stat-tile stat-tile--purple" id="gc-stat">
<div class="stat-tile-value" id="gc-pct">--</div>
<div class="stat-tile-label">GC</div>
<div class="stat-item" id="gc-stat">
<div class="bar-header">
<span class="bar-label">GC</span>
<span class="bar-value" id="gc-pct">--</span>
</div>
<div class="bar">
<div class="bar-fill bar-fill--purple" id="gc-fill"></div>
</div>
</div>
<div class="stat-tile stat-tile--red" id="exc-stat">
<div class="stat-tile-value" id="exc-pct">--</div>
<div class="stat-tile-label">Exception</div>
<div class="stat-item" id="exc-stat">
<div class="bar-header">
<span class="bar-label">Exception</span>
<span class="bar-value" id="exc-pct">--</span>
</div>
<div class="bar">
<div class="bar-fill bar-fill--red" id="exc-fill"></div>
</div>
</div>
</div>
</div>