Skip to content

Commit 90cb459

Browse files
committed
add workspace memory analyzer command
1 parent 5664ec7 commit 90cb459

File tree

1 file changed

+179
-0
lines changed

1 file changed

+179
-0
lines changed

src/extension.ts

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ export function activate(context: vscode.ExtensionContext) {
6363
})
6464
);
6565

66+
context.subscriptions.push(
67+
vscode.commands.registerCommand('goMemoryVisualizer.analyzeWorkspace', () => {
68+
analyzeWorkspaceCommand(parser, optimizer);
69+
})
70+
);
71+
6672
// Register providers
6773
context.subscriptions.push(
6874
vscode.languages.registerHoverProvider('go', new MemoryLayoutHoverProvider(parser))
@@ -454,6 +460,179 @@ function generateCSVReport(data: ExportFormat): string {
454460
return csv;
455461
}
456462

463+
interface WorkspaceAnalysisResult {
464+
file: string;
465+
structName: string;
466+
totalSize: number;
467+
totalPadding: number;
468+
paddingPercentage: number;
469+
bytesSaveable: number;
470+
cacheLinesCrossed: number;
471+
hotFields: string[];
472+
}
473+
474+
async function analyzeWorkspaceCommand(parser: GoParser, optimizer: StructOptimizer) {
475+
const workspaceFolders = vscode.workspace.workspaceFolders;
476+
if (!workspaceFolders) {
477+
vscode.window.showErrorMessage('No workspace folder open');
478+
return;
479+
}
480+
481+
const results: WorkspaceAnalysisResult[] = [];
482+
483+
await vscode.window.withProgress({
484+
location: vscode.ProgressLocation.Notification,
485+
title: 'Analyzing Go structs in workspace...',
486+
cancellable: true
487+
}, async (progress, token) => {
488+
const goFiles = await vscode.workspace.findFiles('**/*.go', '**/vendor/**');
489+
490+
let processed = 0;
491+
for (const file of goFiles) {
492+
if (token.isCancellationRequested) {
493+
break;
494+
}
495+
496+
progress.report({
497+
increment: (100 / goFiles.length),
498+
message: `${path.basename(file.fsPath)}`
499+
});
500+
501+
try {
502+
const content = fs.readFileSync(file.fsPath, 'utf8');
503+
const structs = parser.parseStructs(content);
504+
505+
for (const struct of structs) {
506+
const optimization = optimizer.optimizeStruct(struct);
507+
const paddingPct = struct.totalSize > 0 ? (struct.totalPadding / struct.totalSize) * 100 : 0;
508+
509+
// Only include structs with issues
510+
if (optimization.bytesSaved > 0 || paddingPct > 10 || struct.hotFields.length > 0) {
511+
results.push({
512+
file: vscode.workspace.asRelativePath(file),
513+
structName: struct.name,
514+
totalSize: struct.totalSize,
515+
totalPadding: struct.totalPadding,
516+
paddingPercentage: paddingPct,
517+
bytesSaveable: optimization.bytesSaved,
518+
cacheLinesCrossed: struct.cacheLinesCrossed,
519+
hotFields: struct.hotFields
520+
});
521+
}
522+
}
523+
} catch (e) {
524+
// Skip files that can't be read
525+
}
526+
527+
processed++;
528+
}
529+
});
530+
531+
if (results.length === 0) {
532+
vscode.window.showInformationMessage('All structs in workspace are optimally aligned!');
533+
return;
534+
}
535+
536+
// Sort by bytes saveable (most impactful first)
537+
results.sort((a, b) => b.bytesSaveable - a.bytesSaveable);
538+
539+
// Create report panel
540+
const panel = vscode.window.createWebviewPanel(
541+
'workspaceAnalysis',
542+
'Workspace Memory Analysis',
543+
vscode.ViewColumn.One,
544+
{ enableScripts: true }
545+
);
546+
547+
const totalSaveable = results.reduce((sum, r) => sum + r.bytesSaveable, 0);
548+
const totalPadding = results.reduce((sum, r) => sum + r.totalPadding, 0);
549+
const structsWithCacheIssues = results.filter(r => r.hotFields.length > 0).length;
550+
551+
let html = `
552+
<!DOCTYPE html>
553+
<html>
554+
<head>
555+
<style>
556+
body { font-family: var(--vscode-font-family); padding: 20px; color: var(--vscode-foreground); }
557+
h1, h2, h3 { color: var(--vscode-foreground); }
558+
.summary { background: var(--vscode-editor-background); padding: 15px; border-radius: 5px; margin-bottom: 20px; }
559+
.stat { display: inline-block; margin-right: 30px; }
560+
.stat-value { font-size: 24px; font-weight: bold; color: var(--vscode-textLink-foreground); }
561+
.stat-label { font-size: 12px; color: var(--vscode-descriptionForeground); }
562+
table { border-collapse: collapse; width: 100%; margin-top: 20px; }
563+
th, td { border: 1px solid var(--vscode-panel-border); padding: 8px; text-align: left; }
564+
th { background-color: var(--vscode-editor-background); }
565+
.warning { color: #ff6b6b; }
566+
.saveable { color: #4caf50; font-weight: bold; }
567+
tr:hover { background: var(--vscode-list-hoverBackground); }
568+
</style>
569+
</head>
570+
<body>
571+
<h1>📊 Workspace Memory Analysis</h1>
572+
<p>Architecture: <strong>${currentArch}</strong></p>
573+
574+
<div class="summary">
575+
<div class="stat">
576+
<div class="stat-value">${results.length}</div>
577+
<div class="stat-label">Structs with issues</div>
578+
</div>
579+
<div class="stat">
580+
<div class="stat-value saveable">${totalSaveable}B</div>
581+
<div class="stat-label">Total bytes saveable</div>
582+
</div>
583+
<div class="stat">
584+
<div class="stat-value">${totalPadding}B</div>
585+
<div class="stat-label">Total padding</div>
586+
</div>
587+
<div class="stat">
588+
<div class="stat-value warning">${structsWithCacheIssues}</div>
589+
<div class="stat-label">Cache line issues</div>
590+
</div>
591+
</div>
592+
593+
<h2>Optimization Opportunities</h2>
594+
<table>
595+
<tr>
596+
<th>File</th>
597+
<th>Struct</th>
598+
<th>Size</th>
599+
<th>Padding</th>
600+
<th>Saveable</th>
601+
<th>Cache Lines</th>
602+
<th>Hot Fields</th>
603+
</tr>
604+
`;
605+
606+
for (const r of results) {
607+
const hotFieldsStr = r.hotFields.length > 0
608+
? `<span class="warning">${r.hotFields.join(', ')}</span>`
609+
: '-';
610+
const saveableStr = r.bytesSaveable > 0
611+
? `<span class="saveable">${r.bytesSaveable}B</span>`
612+
: '-';
613+
614+
html += `
615+
<tr>
616+
<td>${r.file}</td>
617+
<td><strong>${r.structName}</strong></td>
618+
<td>${r.totalSize}B</td>
619+
<td>${r.totalPadding}B (${r.paddingPercentage.toFixed(1)}%)</td>
620+
<td>${saveableStr}</td>
621+
<td>${r.cacheLinesCrossed}</td>
622+
<td>${hotFieldsStr}</td>
623+
</tr>
624+
`;
625+
}
626+
627+
html += `
628+
</table>
629+
</body>
630+
</html>
631+
`;
632+
633+
panel.webview.html = html;
634+
}
635+
457636
class MemoryLayoutHoverProvider implements vscode.HoverProvider {
458637
constructor(private parser: GoParser) {}
459638

0 commit comments

Comments
 (0)