@memlab/mcp-server 2.18.1 → 2.86.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -16
- package/bin/.eslintrc.js +26 -0
- package/bin/memlab-cli.js +313 -0
- package/dist/anonymized-snapshot.d.ts +75 -0
- package/dist/anonymized-snapshot.d.ts.map +1 -0
- package/dist/anonymized-snapshot.js +101 -0
- package/dist/anonymized-snapshot.js.map +1 -0
- package/dist/artifact-classes.d.ts +86 -0
- package/dist/artifact-classes.d.ts.map +1 -0
- package/dist/artifact-classes.js +261 -0
- package/dist/artifact-classes.js.map +1 -0
- package/dist/capture-mode.d.ts +60 -0
- package/dist/capture-mode.d.ts.map +1 -0
- package/dist/capture-mode.js +39 -0
- package/dist/capture-mode.js.map +1 -0
- package/dist/eval-hints.d.ts +41 -0
- package/dist/eval-hints.d.ts.map +1 -0
- package/dist/eval-hints.js +115 -0
- package/dist/eval-hints.js.map +1 -0
- package/dist/guardrail.d.ts.map +1 -1
- package/dist/guardrail.js +13 -0
- package/dist/guardrail.js.map +1 -1
- package/dist/heap-budget.d.ts +32 -0
- package/dist/heap-budget.d.ts.map +1 -0
- package/dist/heap-budget.js +90 -0
- package/dist/heap-budget.js.map +1 -0
- package/dist/heap-shapes.d.ts +148 -0
- package/dist/heap-shapes.d.ts.map +1 -0
- package/dist/heap-shapes.js +193 -0
- package/dist/heap-shapes.js.map +1 -0
- package/dist/heap-state.d.ts +109 -2
- package/dist/heap-state.d.ts.map +1 -1
- package/dist/heap-state.js +194 -3
- package/dist/heap-state.js.map +1 -1
- package/dist/index.js +102 -1
- package/dist/index.js.map +1 -1
- package/dist/progress.d.ts +25 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +46 -0
- package/dist/progress.js.map +1 -0
- package/dist/react-shapes.d.ts +42 -0
- package/dist/react-shapes.d.ts.map +1 -0
- package/dist/react-shapes.js +149 -0
- package/dist/react-shapes.js.map +1 -0
- package/dist/result-handles.d.ts +11 -0
- package/dist/result-handles.d.ts.map +1 -0
- package/dist/result-handles.js +77 -0
- package/dist/result-handles.js.map +1 -0
- package/dist/server-version.d.ts +19 -0
- package/dist/server-version.d.ts.map +1 -0
- package/dist/server-version.js +19 -0
- package/dist/server-version.js.map +1 -0
- package/dist/snapshot-borrow.d.ts +67 -0
- package/dist/snapshot-borrow.d.ts.map +1 -0
- package/dist/snapshot-borrow.js +113 -0
- package/dist/snapshot-borrow.js.map +1 -0
- package/dist/string-index.d.ts +55 -0
- package/dist/string-index.d.ts.map +1 -0
- package/dist/string-index.js +99 -0
- package/dist/string-index.js.map +1 -0
- package/dist/tool-registry.d.ts +42 -0
- package/dist/tool-registry.d.ts.map +1 -0
- package/dist/tool-registry.js +20 -0
- package/dist/tool-registry.js.map +1 -0
- package/dist/tools/analyze-run.d.ts +12 -0
- package/dist/tools/analyze-run.d.ts.map +1 -0
- package/dist/tools/analyze-run.js +404 -0
- package/dist/tools/analyze-run.js.map +1 -0
- package/dist/tools/anonymize-snapshot.d.ts +12 -0
- package/dist/tools/anonymize-snapshot.d.ts.map +1 -0
- package/dist/tools/anonymize-snapshot.js +159 -0
- package/dist/tools/anonymize-snapshot.js.map +1 -0
- package/dist/tools/app-config.d.ts +12 -0
- package/dist/tools/app-config.d.ts.map +1 -0
- package/dist/tools/app-config.js +217 -0
- package/dist/tools/app-config.js.map +1 -0
- package/dist/tools/app-heap.d.ts +30 -0
- package/dist/tools/app-heap.d.ts.map +1 -0
- package/dist/tools/app-heap.js +106 -0
- package/dist/tools/app-heap.js.map +1 -0
- package/dist/tools/artifact-budget.d.ts +12 -0
- package/dist/tools/artifact-budget.d.ts.map +1 -0
- package/dist/tools/artifact-budget.js +219 -0
- package/dist/tools/artifact-budget.js.map +1 -0
- package/dist/tools/async-census.d.ts +12 -0
- package/dist/tools/async-census.d.ts.map +1 -0
- package/dist/tools/async-census.js +243 -0
- package/dist/tools/async-census.js.map +1 -0
- package/dist/tools/auto-investigate.d.ts.map +1 -1
- package/dist/tools/auto-investigate.js +54 -5
- package/dist/tools/auto-investigate.js.map +1 -1
- package/dist/tools/batch.d.ts +12 -0
- package/dist/tools/batch.d.ts.map +1 -0
- package/dist/tools/batch.js +196 -0
- package/dist/tools/batch.js.map +1 -0
- package/dist/tools/cache-analysis.d.ts +15 -0
- package/dist/tools/cache-analysis.d.ts.map +1 -1
- package/dist/tools/cache-analysis.js +240 -14
- package/dist/tools/cache-analysis.js.map +1 -1
- package/dist/tools/census-diff.d.ts +55 -0
- package/dist/tools/census-diff.d.ts.map +1 -0
- package/dist/tools/census-diff.js +228 -0
- package/dist/tools/census-diff.js.map +1 -0
- package/dist/tools/chain-walk.d.ts +12 -0
- package/dist/tools/chain-walk.d.ts.map +1 -0
- package/dist/tools/chain-walk.js +184 -0
- package/dist/tools/chain-walk.js.map +1 -0
- package/dist/tools/class-histogram.d.ts.map +1 -1
- package/dist/tools/class-histogram.js +14 -3
- package/dist/tools/class-histogram.js.map +1 -1
- package/dist/tools/collection-diff.d.ts +44 -0
- package/dist/tools/collection-diff.d.ts.map +1 -0
- package/dist/tools/collection-diff.js +343 -0
- package/dist/tools/collection-diff.js.map +1 -0
- package/dist/tools/collection-trend.d.ts +55 -0
- package/dist/tools/collection-trend.d.ts.map +1 -0
- package/dist/tools/collection-trend.js +315 -0
- package/dist/tools/collection-trend.js.map +1 -0
- package/dist/tools/detached-dom.d.ts +5 -0
- package/dist/tools/detached-dom.d.ts.map +1 -1
- package/dist/tools/detached-dom.js +368 -22
- package/dist/tools/detached-dom.js.map +1 -1
- package/dist/tools/dev-artifacts.d.ts +62 -6
- package/dist/tools/dev-artifacts.d.ts.map +1 -1
- package/dist/tools/dev-artifacts.js +685 -24
- package/dist/tools/dev-artifacts.js.map +1 -1
- package/dist/tools/diff-snapshots.d.ts.map +1 -1
- package/dist/tools/diff-snapshots.js +18 -2
- package/dist/tools/diff-snapshots.js.map +1 -1
- package/dist/tools/dom-audit.d.ts +37 -0
- package/dist/tools/dom-audit.d.ts.map +1 -0
- package/dist/tools/dom-audit.js +247 -0
- package/dist/tools/dom-audit.js.map +1 -0
- package/dist/tools/dominator-attribution.d.ts +12 -0
- package/dist/tools/dominator-attribution.d.ts.map +1 -0
- package/dist/tools/dominator-attribution.js +189 -0
- package/dist/tools/dominator-attribution.js.map +1 -0
- package/dist/tools/dominator-chain.d.ts +12 -0
- package/dist/tools/dominator-chain.d.ts.map +1 -0
- package/dist/tools/dominator-chain.js +92 -0
- package/dist/tools/dominator-chain.js.map +1 -0
- package/dist/tools/duplicate-objects.d.ts +12 -0
- package/dist/tools/duplicate-objects.d.ts.map +1 -0
- package/dist/tools/duplicate-objects.js +172 -0
- package/dist/tools/duplicate-objects.js.map +1 -0
- package/dist/tools/duplicated-strings.d.ts.map +1 -1
- package/dist/tools/duplicated-strings.js +49 -40
- package/dist/tools/duplicated-strings.js.map +1 -1
- package/dist/tools/eval-across.d.ts +12 -0
- package/dist/tools/eval-across.d.ts.map +1 -0
- package/dist/tools/eval-across.js +135 -0
- package/dist/tools/eval-across.js.map +1 -0
- package/dist/tools/eval.d.ts +79 -0
- package/dist/tools/eval.d.ts.map +1 -1
- package/dist/tools/eval.js +2523 -197
- package/dist/tools/eval.js.map +1 -1
- package/dist/tools/event-listener-leaks.d.ts.map +1 -1
- package/dist/tools/event-listener-leaks.js +42 -17
- package/dist/tools/event-listener-leaks.js.map +1 -1
- package/dist/tools/event-registry.d.ts.map +1 -1
- package/dist/tools/event-registry.js +42 -8
- package/dist/tools/event-registry.js.map +1 -1
- package/dist/tools/explain-delta.d.ts +12 -0
- package/dist/tools/explain-delta.d.ts.map +1 -0
- package/dist/tools/explain-delta.js +221 -0
- package/dist/tools/explain-delta.js.map +1 -0
- package/dist/tools/find-nodes-by-class.d.ts.map +1 -1
- package/dist/tools/find-nodes-by-class.js +112 -13
- package/dist/tools/find-nodes-by-class.js.map +1 -1
- package/dist/tools/finding-index.d.ts +203 -0
- package/dist/tools/finding-index.d.ts.map +1 -0
- package/dist/tools/finding-index.js +566 -0
- package/dist/tools/finding-index.js.map +1 -0
- package/dist/tools/for-each.d.ts.map +1 -1
- package/dist/tools/for-each.js +15 -3
- package/dist/tools/for-each.js.map +1 -1
- package/dist/tools/get-referrers.d.ts.map +1 -1
- package/dist/tools/get-referrers.js +17 -0
- package/dist/tools/get-referrers.js.map +1 -1
- package/dist/tools/get-value.d.ts +16 -0
- package/dist/tools/get-value.d.ts.map +1 -1
- package/dist/tools/get-value.js +96 -2
- package/dist/tools/get-value.js.map +1 -1
- package/dist/tools/hunt-report.d.ts +12 -0
- package/dist/tools/hunt-report.d.ts.map +1 -0
- package/dist/tools/hunt-report.js +186 -0
- package/dist/tools/hunt-report.js.map +1 -0
- package/dist/tools/hypothesis.d.ts +12 -0
- package/dist/tools/hypothesis.d.ts.map +1 -0
- package/dist/tools/hypothesis.js +280 -0
- package/dist/tools/hypothesis.js.map +1 -0
- package/dist/tools/id-space-audit.d.ts +12 -0
- package/dist/tools/id-space-audit.d.ts.map +1 -0
- package/dist/tools/id-space-audit.js +262 -0
- package/dist/tools/id-space-audit.js.map +1 -0
- package/dist/tools/identify.d.ts +12 -0
- package/dist/tools/identify.d.ts.map +1 -0
- package/dist/tools/identify.js +205 -0
- package/dist/tools/identify.js.map +1 -0
- package/dist/tools/identity-diff.d.ts +12 -0
- package/dist/tools/identity-diff.d.ts.map +1 -0
- package/dist/tools/identity-diff.js +188 -0
- package/dist/tools/identity-diff.js.map +1 -0
- package/dist/tools/intern-opportunities.d.ts.map +1 -1
- package/dist/tools/intern-opportunities.js +116 -50
- package/dist/tools/intern-opportunities.js.map +1 -1
- package/dist/tools/ladder-probe.d.ts +65 -0
- package/dist/tools/ladder-probe.d.ts.map +1 -0
- package/dist/tools/ladder-probe.js +445 -0
- package/dist/tools/ladder-probe.js.map +1 -0
- package/dist/tools/ladder.d.ts +33 -0
- package/dist/tools/ladder.d.ts.map +1 -0
- package/dist/tools/ladder.js +266 -0
- package/dist/tools/ladder.js.map +1 -0
- package/dist/tools/largest-objects.d.ts.map +1 -1
- package/dist/tools/largest-objects.js +6 -2
- package/dist/tools/largest-objects.js.map +1 -1
- package/dist/tools/leak-report.d.ts +35 -0
- package/dist/tools/leak-report.d.ts.map +1 -0
- package/dist/tools/leak-report.js +398 -0
- package/dist/tools/leak-report.js.map +1 -0
- package/dist/tools/load-snapshot.d.ts +29 -0
- package/dist/tools/load-snapshot.d.ts.map +1 -1
- package/dist/tools/load-snapshot.js +294 -23
- package/dist/tools/load-snapshot.js.map +1 -1
- package/dist/tools/map-entries.d.ts +12 -0
- package/dist/tools/map-entries.d.ts.map +1 -0
- package/dist/tools/map-entries.js +139 -0
- package/dist/tools/map-entries.js.map +1 -0
- package/dist/tools/match-object.d.ts +12 -0
- package/dist/tools/match-object.d.ts.map +1 -0
- package/dist/tools/match-object.js +165 -0
- package/dist/tools/match-object.js.map +1 -0
- package/dist/tools/metric.d.ts +13 -0
- package/dist/tools/metric.d.ts.map +1 -0
- package/dist/tools/metric.js +185 -0
- package/dist/tools/metric.js.map +1 -0
- package/dist/tools/module-attribution.d.ts +36 -0
- package/dist/tools/module-attribution.d.ts.map +1 -0
- package/dist/tools/module-attribution.js +235 -0
- package/dist/tools/module-attribution.js.map +1 -0
- package/dist/tools/next-measurement.d.ts +26 -0
- package/dist/tools/next-measurement.d.ts.map +1 -0
- package/dist/tools/next-measurement.js +149 -0
- package/dist/tools/next-measurement.js.map +1 -0
- package/dist/tools/object-cost-breakdown.d.ts.map +1 -1
- package/dist/tools/object-cost-breakdown.js +64 -0
- package/dist/tools/object-cost-breakdown.js.map +1 -1
- package/dist/tools/object-shape.d.ts.map +1 -1
- package/dist/tools/object-shape.js +53 -5
- package/dist/tools/object-shape.js.map +1 -1
- package/dist/tools/population-diff.d.ts +57 -0
- package/dist/tools/population-diff.d.ts.map +1 -0
- package/dist/tools/population-diff.js +338 -0
- package/dist/tools/population-diff.js.map +1 -0
- package/dist/tools/population-vs-owners.d.ts +12 -0
- package/dist/tools/population-vs-owners.d.ts.map +1 -0
- package/dist/tools/population-vs-owners.js +183 -0
- package/dist/tools/population-vs-owners.js.map +1 -0
- package/dist/tools/property-names.d.ts +29 -0
- package/dist/tools/property-names.d.ts.map +1 -0
- package/dist/tools/property-names.js +131 -0
- package/dist/tools/property-names.js.map +1 -0
- package/dist/tools/quick-diagnosis.d.ts.map +1 -1
- package/dist/tools/quick-diagnosis.js +7 -1
- package/dist/tools/quick-diagnosis.js.map +1 -1
- package/dist/tools/react-owners.d.ts +12 -0
- package/dist/tools/react-owners.d.ts.map +1 -0
- package/dist/tools/react-owners.js +167 -0
- package/dist/tools/react-owners.js.map +1 -0
- package/dist/tools/react-update-queues.d.ts +12 -0
- package/dist/tools/react-update-queues.d.ts.map +1 -0
- package/dist/tools/react-update-queues.js +173 -0
- package/dist/tools/react-update-queues.js.map +1 -0
- package/dist/tools/replicate.d.ts +49 -0
- package/dist/tools/replicate.d.ts.map +1 -0
- package/dist/tools/replicate.js +241 -0
- package/dist/tools/replicate.js.map +1 -0
- package/dist/tools/retainer-diff.d.ts +12 -0
- package/dist/tools/retainer-diff.d.ts.map +1 -0
- package/dist/tools/retainer-diff.js +168 -0
- package/dist/tools/retainer-diff.js.map +1 -0
- package/dist/tools/retainer-layers.d.ts +23 -0
- package/dist/tools/retainer-layers.d.ts.map +1 -0
- package/dist/tools/retainer-layers.js +179 -0
- package/dist/tools/retainer-layers.js.map +1 -0
- package/dist/tools/retainer-summary.d.ts +18 -0
- package/dist/tools/retainer-summary.d.ts.map +1 -1
- package/dist/tools/retainer-summary.js +210 -51
- package/dist/tools/retainer-summary.js.map +1 -1
- package/dist/tools/retainer-trace.d.ts.map +1 -1
- package/dist/tools/retainer-trace.js +14 -2
- package/dist/tools/retainer-trace.js.map +1 -1
- package/dist/tools/round-audit.d.ts +66 -0
- package/dist/tools/round-audit.d.ts.map +1 -0
- package/dist/tools/round-audit.js +258 -0
- package/dist/tools/round-audit.js.map +1 -0
- package/dist/tools/round-digest.d.ts +12 -0
- package/dist/tools/round-digest.d.ts.map +1 -0
- package/dist/tools/round-digest.js +190 -0
- package/dist/tools/round-digest.js.map +1 -0
- package/dist/tools/script-census.d.ts +12 -0
- package/dist/tools/script-census.d.ts.map +1 -0
- package/dist/tools/script-census.js +182 -0
- package/dist/tools/script-census.js.map +1 -0
- package/dist/tools/search-nodes.d.ts.map +1 -1
- package/dist/tools/search-nodes.js +5 -1
- package/dist/tools/search-nodes.js.map +1 -1
- package/dist/tools/search-strings.d.ts.map +1 -1
- package/dist/tools/search-strings.js +53 -7
- package/dist/tools/search-strings.js.map +1 -1
- package/dist/tools/sequence-analysis.d.ts +53 -0
- package/dist/tools/sequence-analysis.d.ts.map +1 -1
- package/dist/tools/sequence-analysis.js +313 -89
- package/dist/tools/sequence-analysis.js.map +1 -1
- package/dist/tools/server-status.d.ts.map +1 -1
- package/dist/tools/server-status.js +4 -1
- package/dist/tools/server-status.js.map +1 -1
- package/dist/tools/settle-check.d.ts +12 -0
- package/dist/tools/settle-check.d.ts.map +1 -0
- package/dist/tools/settle-check.js +188 -0
- package/dist/tools/settle-check.js.map +1 -0
- package/dist/tools/shape-histogram.d.ts.map +1 -1
- package/dist/tools/shape-histogram.js +9 -2
- package/dist/tools/shape-histogram.js.map +1 -1
- package/dist/tools/sliced-strings.d.ts.map +1 -1
- package/dist/tools/sliced-strings.js +2 -1
- package/dist/tools/sliced-strings.js.map +1 -1
- package/dist/tools/snapshots.d.ts.map +1 -1
- package/dist/tools/snapshots.js +24 -6
- package/dist/tools/snapshots.js.map +1 -1
- package/dist/tools/sparse-elements.d.ts +12 -0
- package/dist/tools/sparse-elements.d.ts.map +1 -0
- package/dist/tools/sparse-elements.js +215 -0
- package/dist/tools/sparse-elements.js.map +1 -0
- package/dist/tools/stale-collections.d.ts +17 -0
- package/dist/tools/stale-collections.d.ts.map +1 -1
- package/dist/tools/stale-collections.js +28 -0
- package/dist/tools/stale-collections.js.map +1 -1
- package/dist/tools/string-patterns.d.ts.map +1 -1
- package/dist/tools/string-patterns.js +7 -5
- package/dist/tools/string-patterns.js.map +1 -1
- package/dist/tools/tools-index.d.ts +12 -0
- package/dist/tools/tools-index.d.ts.map +1 -0
- package/dist/tools/tools-index.js +492 -0
- package/dist/tools/tools-index.js.map +1 -0
- package/dist/tools/trace-all.d.ts +42 -0
- package/dist/tools/trace-all.d.ts.map +1 -0
- package/dist/tools/trace-all.js +263 -0
- package/dist/tools/trace-all.js.map +1 -0
- package/dist/tools/unit-cost.d.ts +12 -0
- package/dist/tools/unit-cost.d.ts.map +1 -0
- package/dist/tools/unit-cost.js +219 -0
- package/dist/tools/unit-cost.js.map +1 -0
- package/dist/tools/verify-fix.d.ts +23 -0
- package/dist/tools/verify-fix.d.ts.map +1 -0
- package/dist/tools/verify-fix.js +219 -0
- package/dist/tools/verify-fix.js.map +1 -0
- package/dist/tools/weakmap-entries.d.ts.map +1 -1
- package/dist/tools/weakmap-entries.js +6 -1
- package/dist/tools/weakmap-entries.js.map +1 -1
- package/dist/tools/weakref-census.d.ts +15 -0
- package/dist/tools/weakref-census.d.ts.map +1 -0
- package/dist/tools/weakref-census.js +147 -0
- package/dist/tools/weakref-census.js.map +1 -0
- package/dist/tools/what-if.d.ts +12 -0
- package/dist/tools/what-if.d.ts.map +1 -0
- package/dist/tools/what-if.js +285 -0
- package/dist/tools/what-if.js.map +1 -0
- package/dist/utils.d.ts +238 -3
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +507 -15
- package/dist/utils.js.map +1 -1
- package/package.json +7 -6
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
* @oncall memory_lab
|
|
9
|
+
*/
|
|
10
|
+
import fs from 'fs';
|
|
11
|
+
import memlabCore from '@memlab/core';
|
|
12
|
+
import { z } from 'zod';
|
|
13
|
+
import { errorResult, formatNumber, markdownTable, pathsHeader, toolResult, } from '../utils.js';
|
|
14
|
+
import { countEntries, parseLocator, resolvePath } from './collection-trend.js';
|
|
15
|
+
import { resolveLadderPaths } from './ladder.js';
|
|
16
|
+
import { resolveMaxFileSizeMB, resolveSnapshotPath } from './load-snapshot.js';
|
|
17
|
+
const { utils: memlabUtils } = memlabCore;
|
|
18
|
+
// Guard against a corrupt or genuinely circular chain. V8's update queues ARE
|
|
19
|
+
// circular (`queue.pending.next` loops back), so the walk stops on a repeat as
|
|
20
|
+
// well — the cap only catches a chain longer than any real one.
|
|
21
|
+
const MAX_CHAIN = 100_000;
|
|
22
|
+
/**
|
|
23
|
+
* Measure the metric on one parsed snapshot. One scalar per snapshot is the
|
|
24
|
+
* whole point: the arms are compared on a rate, and a rate needs a number per
|
|
25
|
+
* rung, not a report.
|
|
26
|
+
*/
|
|
27
|
+
export function measureMetric(snapshot, kind, locator, chainEdge) {
|
|
28
|
+
if (kind === 'class_count') {
|
|
29
|
+
const want = locator.trim();
|
|
30
|
+
let count = 0;
|
|
31
|
+
snapshot.nodes.forEach(node => {
|
|
32
|
+
if (node.id > 3 && node.name === want)
|
|
33
|
+
count++;
|
|
34
|
+
});
|
|
35
|
+
return count;
|
|
36
|
+
}
|
|
37
|
+
const loc = parseLocator(locator);
|
|
38
|
+
let total = 0;
|
|
39
|
+
snapshot.nodes.forEach(node => {
|
|
40
|
+
if (node.id <= 3 || node.name !== loc.ownerClass)
|
|
41
|
+
return;
|
|
42
|
+
const target = resolvePath(node, loc.path);
|
|
43
|
+
if (target == null)
|
|
44
|
+
return;
|
|
45
|
+
if (kind === 'collection_length') {
|
|
46
|
+
total += countEntries(target) ?? 0;
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// pending_chain: follow the linked list from the head, counting nodes.
|
|
50
|
+
let cur = target;
|
|
51
|
+
const seen = new Set();
|
|
52
|
+
let len = 0;
|
|
53
|
+
while (cur && !seen.has(cur.id) && len < MAX_CHAIN) {
|
|
54
|
+
seen.add(cur.id);
|
|
55
|
+
len++;
|
|
56
|
+
let next = null;
|
|
57
|
+
for (const edge of cur.references) {
|
|
58
|
+
if (edge.type === 'hidden')
|
|
59
|
+
continue;
|
|
60
|
+
if (String(edge.name_or_index) !== chainEdge)
|
|
61
|
+
continue;
|
|
62
|
+
next = edge.toNode.id > 3 ? edge.toNode : null;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
cur = next;
|
|
66
|
+
}
|
|
67
|
+
total += len;
|
|
68
|
+
});
|
|
69
|
+
return total;
|
|
70
|
+
}
|
|
71
|
+
async function measureArm(paths, kind, locator, chainEdge, maxFileSizeMB) {
|
|
72
|
+
const labels = [];
|
|
73
|
+
const values = [];
|
|
74
|
+
for (const p of paths) {
|
|
75
|
+
let local;
|
|
76
|
+
let fetchedFrom = null;
|
|
77
|
+
try {
|
|
78
|
+
const r = resolveSnapshotPath(p);
|
|
79
|
+
local = r.localPath;
|
|
80
|
+
fetchedFrom = r.fetchedFrom;
|
|
81
|
+
}
|
|
82
|
+
catch (e) {
|
|
83
|
+
throw new Error(`Failed to resolve "${p}": ${e instanceof Error ? e.message : String(e)}`);
|
|
84
|
+
}
|
|
85
|
+
if (!fs.existsSync(local))
|
|
86
|
+
throw new Error(`File not found: ${local}`);
|
|
87
|
+
const sizeMB = fs.statSync(local).size / (1024 * 1024);
|
|
88
|
+
const limit = resolveMaxFileSizeMB(maxFileSizeMB, fetchedFrom != null);
|
|
89
|
+
if (sizeMB > limit) {
|
|
90
|
+
throw new Error(`${p} is ${sizeMB.toFixed(0)} MB — exceeds the ${limit} MB per-file safety limit. Raise it with max_file_size_mb: ${Math.ceil(sizeMB + 100)}.`);
|
|
91
|
+
}
|
|
92
|
+
// Light parse: every metric here is read off names and edges, so the
|
|
93
|
+
// dominator/retained-size pass would be paid on every rung of both arms for
|
|
94
|
+
// nothing.
|
|
95
|
+
const snapshot = await memlabUtils.getSnapshotFromFile(local, {
|
|
96
|
+
buildNodeIdIndex: true,
|
|
97
|
+
verbose: false,
|
|
98
|
+
});
|
|
99
|
+
labels.push(fetchedFrom ?? p.replace(/^.*\//, ''));
|
|
100
|
+
values.push(measureMetric(snapshot, kind, locator, chainEdge));
|
|
101
|
+
}
|
|
102
|
+
return { labels, values };
|
|
103
|
+
}
|
|
104
|
+
/** Growth per interaction cycle across an arm's ladder. */
|
|
105
|
+
export function perCycleRate(values, cycles) {
|
|
106
|
+
const steps = values.length - 1;
|
|
107
|
+
if (steps <= 0 || cycles <= 0)
|
|
108
|
+
return 0;
|
|
109
|
+
return (values[values.length - 1] - values[0]) / (steps * cycles);
|
|
110
|
+
}
|
|
111
|
+
export function registerVerifyFix(server) {
|
|
112
|
+
server.tool('memlab_verify_fix', 'Decide whether a fix actually worked, by comparing the per-cycle growth RATE of one metric between a before ladder and an after ladder. hunt_runner --ab drives both arms but nothing analyses them, which is why fix write-ups stall at "A/B pending". ' +
|
|
113
|
+
'NO RUNTIME GATE IS REQUIRED: the two arms are two sets of snapshot files passed as `before_paths` and `after_paths`, so a fix that cannot be put behind a flag — a build-only change, a local patch, a reverted commit — is verified exactly the same way. One session concluded this tool was unusable for an ungated fix and skipped A/B entirely; it is not. ' +
|
|
114
|
+
'Metrics: "collection_length" (entries under "<OwnerClass>.<property>"), "class_count" (instances of a class), "pending_chain" (total length of the linked lists hanging off "<OwnerClass>.<property>", following `next` — the React update-queue shape). ' +
|
|
115
|
+
'Compares RATES, not levels: a build difference, a warmer cache or a longer session all shift the absolute level, and only the slope per interaction says whether the thing still accumulates. Each arm therefore needs at least 2 rungs — a single snapshot per arm is refused rather than compared, because that comparison is confounded. ' +
|
|
116
|
+
'Returns both series, both rates, the reduction, and a PASS/FAIL against expected_reduction. Loads rungs transiently in LIGHT mode, one graph at a time.', {
|
|
117
|
+
metric_kind: z
|
|
118
|
+
.enum(['collection_length', 'class_count', 'pending_chain'])
|
|
119
|
+
.describe('What to measure on every rung of both arms.'),
|
|
120
|
+
locator: z
|
|
121
|
+
.string()
|
|
122
|
+
.describe('For collection_length / pending_chain: "<OwnerClass>.<property>" (deeper paths allowed). For class_count: the class name alone.'),
|
|
123
|
+
before_paths: z
|
|
124
|
+
.array(z.string())
|
|
125
|
+
.describe('Ordered rungs of the UNFIXED arm, oldest first. A single ["ladder:<name>"] element expands to a saved ladder.'),
|
|
126
|
+
after_paths: z
|
|
127
|
+
.array(z.string())
|
|
128
|
+
.describe('Ordered rungs of the FIXED arm, oldest first.'),
|
|
129
|
+
cycles: z
|
|
130
|
+
.number()
|
|
131
|
+
.describe('Interaction cycles driven between consecutive rungs. Must be the same for both arms — otherwise the rates are not comparable.'),
|
|
132
|
+
expected_reduction: z
|
|
133
|
+
.number()
|
|
134
|
+
.optional()
|
|
135
|
+
.default(0.9)
|
|
136
|
+
.describe('Fraction of the before-rate the fix is expected to remove, 0–1 (default 0.9). A leak fix should drive the rate to ~0; a sizing fix will not.'),
|
|
137
|
+
chain_edge: z
|
|
138
|
+
.string()
|
|
139
|
+
.optional()
|
|
140
|
+
.default('next')
|
|
141
|
+
.describe('Edge name to follow for metric_kind "pending_chain" (default "next").'),
|
|
142
|
+
max_file_size_mb: z
|
|
143
|
+
.number()
|
|
144
|
+
.optional()
|
|
145
|
+
.describe('Per-file size limit override (MB).'),
|
|
146
|
+
}, async ({ metric_kind, locator, before_paths, after_paths, cycles, expected_reduction, chain_edge, max_file_size_mb, }) => {
|
|
147
|
+
try {
|
|
148
|
+
const before = resolveLadderPaths(before_paths).paths;
|
|
149
|
+
const after = resolveLadderPaths(after_paths).paths;
|
|
150
|
+
// Name BOTH arms: this tool never reads the resident snapshot, and a
|
|
151
|
+
// fix-validation result labelled with an unrelated capture is the
|
|
152
|
+
// worst place to leave a reader guessing which build was measured.
|
|
153
|
+
const armsHeader = pathsHeader([
|
|
154
|
+
...before.map(p => `before:${p.replace(/^.*\//, '')}`),
|
|
155
|
+
...after.map(p => `after:${p.replace(/^.*\//, '')}`),
|
|
156
|
+
]);
|
|
157
|
+
for (const [label, arm] of [
|
|
158
|
+
['before_paths', before],
|
|
159
|
+
['after_paths', after],
|
|
160
|
+
]) {
|
|
161
|
+
if (arm.length < 2) {
|
|
162
|
+
return errorResult(`${label} has ${arm.length} rung(s); each arm needs at least 2. This tool compares per-cycle RATES, and one snapshot gives a level, not a rate — comparing levels across two builds is confounded by warmup, session length and build differences.`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (cycles <= 0) {
|
|
166
|
+
return errorResult('cycles must be greater than 0.');
|
|
167
|
+
}
|
|
168
|
+
if (expected_reduction < 0 || expected_reduction > 1) {
|
|
169
|
+
return errorResult('expected_reduction must be between 0 and 1.');
|
|
170
|
+
}
|
|
171
|
+
const b = await measureArm(before, metric_kind, locator, chain_edge, max_file_size_mb);
|
|
172
|
+
const a = await measureArm(after, metric_kind, locator, chain_edge, max_file_size_mb);
|
|
173
|
+
const beforeRate = perCycleRate(b.values, cycles);
|
|
174
|
+
const afterRate = perCycleRate(a.values, cycles);
|
|
175
|
+
const fmtRate = (r) => Math.abs(r) < 10 ? r.toFixed(2) : formatNumber(Math.round(r));
|
|
176
|
+
const lines = [
|
|
177
|
+
`## Fix verification — \`${metric_kind}\` on \`${locator}\``,
|
|
178
|
+
'',
|
|
179
|
+
markdownTable(['Arm', 'Rungs', 'First', 'Last', 'Net', 'Per cycle'], [
|
|
180
|
+
[
|
|
181
|
+
'before (unfixed)',
|
|
182
|
+
String(b.values.length),
|
|
183
|
+
formatNumber(b.values[0]),
|
|
184
|
+
formatNumber(b.values[b.values.length - 1]),
|
|
185
|
+
formatNumber(b.values[b.values.length - 1] - b.values[0]),
|
|
186
|
+
fmtRate(beforeRate),
|
|
187
|
+
],
|
|
188
|
+
[
|
|
189
|
+
'after (fixed)',
|
|
190
|
+
String(a.values.length),
|
|
191
|
+
formatNumber(a.values[0]),
|
|
192
|
+
formatNumber(a.values[a.values.length - 1]),
|
|
193
|
+
formatNumber(a.values[a.values.length - 1] - a.values[0]),
|
|
194
|
+
fmtRate(afterRate),
|
|
195
|
+
],
|
|
196
|
+
], new Set([1, 2, 3, 4, 5])),
|
|
197
|
+
'',
|
|
198
|
+
`- before series: ${b.values.map(v => formatNumber(v)).join(' → ')}`,
|
|
199
|
+
`- after series: ${a.values.map(v => formatNumber(v)).join(' → ')}`,
|
|
200
|
+
'',
|
|
201
|
+
];
|
|
202
|
+
if (beforeRate <= 0) {
|
|
203
|
+
lines.push(`⚠ **Inconclusive — the BEFORE arm does not grow** (rate ${fmtRate(beforeRate)}/cycle). There is nothing for the fix to reduce, so this run cannot validate it. The unfixed arm has to reproduce the leak first: check the metric and locator, drive more cycles, or confirm the arm really is running the unfixed build.`);
|
|
204
|
+
return toolResult(lines.join('\n'), armsHeader);
|
|
205
|
+
}
|
|
206
|
+
const reduction = (beforeRate - afterRate) / beforeRate;
|
|
207
|
+
const pass = reduction >= expected_reduction;
|
|
208
|
+
lines.push(`**Reduction: ${(reduction * 100).toFixed(1)}%** of the before-rate (${fmtRate(beforeRate)} → ${fmtRate(afterRate)} per cycle), against an expected ${(expected_reduction * 100).toFixed(0)}%.`, '', pass
|
|
209
|
+
? `✅ **PASS** — the fixed arm accumulates ${(reduction * 100).toFixed(1)}% less per cycle.${afterRate > 0 ? ` It is not zero (${fmtRate(afterRate)}/cycle remains), so state the residual rather than claiming the leak is gone.` : ' The residual rate is zero.'}`
|
|
210
|
+
: `❌ **FAIL** — ${(reduction * 100).toFixed(1)}% is short of the expected ${(expected_reduction * 100).toFixed(0)}%. The fixed arm still accumulates ${fmtRate(afterRate)} per cycle.`);
|
|
211
|
+
lines.push('', `_Both arms must have been driven with the same interaction and the same ${formatNumber(cycles)} cycles between rungs; nothing in a .heapsnapshot records that, so it is the caller's to guarantee — record it with \`memlab_ladder\`. Two rungs per arm give a two-point slope: add rungs if the before-arm series is not monotonic, since a single noisy pair can produce either verdict._`);
|
|
212
|
+
return toolResult(lines.join('\n'), armsHeader);
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
return errorResult(err);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=verify-fix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-fix.js","sourceRoot":"","sources":["../../src/tools/verify-fix.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"weakmap-entries.d.ts","sourceRoot":"","sources":["../../src/tools/weakmap-entries.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAavE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"weakmap-entries.d.ts","sourceRoot":"","sources":["../../src/tools/weakmap-entries.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAavE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAgM9D"}
|
|
@@ -42,10 +42,15 @@ export function registerWeakMapEntries(server) {
|
|
|
42
42
|
if (eName !== 'table' && eName !== 'backing_store')
|
|
43
43
|
continue;
|
|
44
44
|
const table = edge.toNode;
|
|
45
|
+
// The key/value slots are element edges — typed `element` in Node
|
|
46
|
+
// snapshots but `internal` in browser V8 snapshots, so we must NOT
|
|
47
|
+
// skip `internal`. Skip only `hidden` and the table's `map`
|
|
48
|
+
// hidden-class pointer.
|
|
45
49
|
const tableRefs = [];
|
|
46
50
|
for (const te of table.references) {
|
|
47
|
-
if (te.type === '
|
|
51
|
+
if (te.type === 'hidden' || String(te.name_or_index) === 'map') {
|
|
48
52
|
continue;
|
|
53
|
+
}
|
|
49
54
|
tableRefs.push(te.toNode);
|
|
50
55
|
}
|
|
51
56
|
// WeakMap tables store key-value pairs: [key1, val1, key2, val2, ...]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"weakmap-entries.js","sourceRoot":"","sources":["../../src/tools/weakmap-entries.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EACL,WAAW,EACX,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,UAAU,GACX,MAAM,aAAa,CAAC;AAErB,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD,MAAM,CAAC,IAAI,CACT,wBAAwB,EACxB,qYAAqY,EACrY;QACE,OAAO,EAAE,CAAC;aACP,MAAM,EAAE;aACR,QAAQ,CACP,oJAAoJ,CACrJ;QACH,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,OAAO,CAAC,EAAE,CAAC;aACX,QAAQ,CAAC,kDAAkD,CAAC;QAC/D,OAAO,EAAE,CAAC;aACP,IAAI,CAAC,CAAC,eAAe,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;aAC/C,QAAQ,EAAE;aACV,OAAO,CAAC,eAAe,CAAC;aACxB,QAAQ,CACP,yHAAyH,CAC1H;KACJ,EACD,KAAK,EAAE,EAAC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAC,EAAE,EAAE;QAClC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YAC3C,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,WAAW,CAAC,gBAAgB,OAAO,YAAY,CAAC,CAAC;YAC1D,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC5B,OAAO,WAAW,CAChB,IAAI,OAAO,SAAS,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,oBAAoB;oBAC7D,0EAA0E,CAC7E,CAAC;YACJ,CAAC;YAYD,MAAM,OAAO,GAAc,EAAE,CAAC;YAE9B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACnC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;gBACzC,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,eAAe;oBAAE,SAAS;gBAE7D,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;gBAC1B,MAAM,SAAS,GAAgB,EAAE,CAAC;gBAClC,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;oBAClC,IAAI,EAAE,CAAC,IAAI,KAAK,
|
|
1
|
+
{"version":3,"file":"weakmap-entries.js","sourceRoot":"","sources":["../../src/tools/weakmap-entries.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
* @oncall memory_lab
|
|
9
|
+
*/
|
|
10
|
+
import type { IHeapNode } from '@memlab/core';
|
|
11
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
12
|
+
/** True when this WeakRef's referent has already been collected. */
|
|
13
|
+
export declare function isEmptyWeakRef(node: IHeapNode): boolean;
|
|
14
|
+
export declare function registerWeakRefCensus(server: McpServer): void;
|
|
15
|
+
//# sourceMappingURL=weakref-census.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weakref-census.d.ts","sourceRoot":"","sources":["../../src/tools/weakref-census.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAkCvE,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAWvD;AAQD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+G7D"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
* @oncall memory_lab
|
|
9
|
+
*/
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
import { getSnapshot } from '../heap-state.js';
|
|
12
|
+
import { errorResult, formatNumber, markdownTable, toolResult, } from '../utils.js';
|
|
13
|
+
/**
|
|
14
|
+
* The "WeakRef without compaction" leak, which is invisible to every other tool
|
|
15
|
+
* here.
|
|
16
|
+
*
|
|
17
|
+
* The shape: a long-lived list holds `{element: WeakRef, record: {...}}` entries.
|
|
18
|
+
* The WeakRef is correct and does its job — the referent is collected on time —
|
|
19
|
+
* but the RECORD and the ARRAY SLOT are strongly held and nothing ever prunes
|
|
20
|
+
* the entries whose referent has gone. The collection grows forever while
|
|
21
|
+
* looking like careful memory hygiene.
|
|
22
|
+
*
|
|
23
|
+
* Nothing existing catches it. `cache_analysis` sees a legitimately-sized
|
|
24
|
+
* collection. `stale_collections` looks for detached DOM and terminal statuses,
|
|
25
|
+
* not for emptied WeakRefs. A reviewer reading the code sees `WeakRef` and moves
|
|
26
|
+
* on. Measured on one surface: a list at 414 entries where **476 of 481 WeakRefs
|
|
27
|
+
* in the heap were empty** — about 99% dead weight, growing ~2 entries per
|
|
28
|
+
* interaction with no bound.
|
|
29
|
+
*
|
|
30
|
+
* Emptiness is read structurally: a live `WeakRef` has an outgoing edge to its
|
|
31
|
+
* referent, a cleared one has only `__proto__` / `map`. That is a fact about the
|
|
32
|
+
* snapshot format, not a heuristic.
|
|
33
|
+
*/
|
|
34
|
+
const STRUCTURAL_EDGE_NAMES = new Set(['__proto__', 'map', 'constructor']);
|
|
35
|
+
/** True when this WeakRef's referent has already been collected. */
|
|
36
|
+
export function isEmptyWeakRef(node) {
|
|
37
|
+
for (const edge of node.references) {
|
|
38
|
+
const name = String(edge.name_or_index);
|
|
39
|
+
if (STRUCTURAL_EDGE_NAMES.has(name))
|
|
40
|
+
continue;
|
|
41
|
+
const t = edge.toNode;
|
|
42
|
+
if (t == null || t.id <= 3)
|
|
43
|
+
continue;
|
|
44
|
+
// Anything else reachable from the WeakRef is its referent.
|
|
45
|
+
if (t.name === 'WeakRef' && name === '__proto__')
|
|
46
|
+
continue;
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
export function registerWeakRefCensus(server) {
|
|
52
|
+
server.tool('memlab_weakref_census', 'Census every WeakRef in the heap, split LIVE vs EMPTY (referent already collected), and group by the shape of the object holding them. ' +
|
|
53
|
+
'Finds the "WeakRef without compaction" leak, which no other tool here can see: a list of `{element: WeakRef, record}` entries where the WeakRef correctly lets the referent go but the RECORD and the array slot are strongly held and never pruned. The collection grows forever while looking like careful memory hygiene — memlab_cache_analysis sees a normal-sized collection, memlab_stale_collections looks for detached DOM and terminal statuses rather than emptied refs, and a code reviewer sees `WeakRef` and moves on. ' +
|
|
54
|
+
'Measured on one surface: 476 of 481 WeakRefs empty (~99% dead weight) in a list growing ~2 entries per interaction with no bound. ' +
|
|
55
|
+
'A holder shape more than half empty is a near-certain missing-compaction bug; the fix is a prune pass or a FinalizationRegistry.', {
|
|
56
|
+
limit: z
|
|
57
|
+
.number()
|
|
58
|
+
.optional()
|
|
59
|
+
.default(20)
|
|
60
|
+
.describe('Maximum holder shapes to report (default 20).'),
|
|
61
|
+
min_count: z
|
|
62
|
+
.number()
|
|
63
|
+
.optional()
|
|
64
|
+
.default(5)
|
|
65
|
+
.describe('Ignore holder shapes with fewer than this many WeakRefs.'),
|
|
66
|
+
}, async ({ limit, min_count }) => {
|
|
67
|
+
try {
|
|
68
|
+
const snapshot = getSnapshot();
|
|
69
|
+
if (!snapshot) {
|
|
70
|
+
return errorResult('No heap snapshot loaded. Use memlab_load_snapshot first.');
|
|
71
|
+
}
|
|
72
|
+
let total = 0;
|
|
73
|
+
let empty = 0;
|
|
74
|
+
const byHolder = new Map();
|
|
75
|
+
const exampleHolder = new Map();
|
|
76
|
+
snapshot.nodes.forEach((node) => {
|
|
77
|
+
if (node.id <= 3)
|
|
78
|
+
return;
|
|
79
|
+
if (node.name !== 'WeakRef')
|
|
80
|
+
return;
|
|
81
|
+
// The prototype/constructor nodes are also named WeakRef.
|
|
82
|
+
if (node.type !== 'object')
|
|
83
|
+
return;
|
|
84
|
+
total++;
|
|
85
|
+
const isEmpty = isEmptyWeakRef(node);
|
|
86
|
+
if (isEmpty)
|
|
87
|
+
empty++;
|
|
88
|
+
for (const edge of node.referrers) {
|
|
89
|
+
const from = edge.fromNode;
|
|
90
|
+
if (from == null || from.id <= 3)
|
|
91
|
+
continue;
|
|
92
|
+
if (from.name === 'WeakRef')
|
|
93
|
+
continue;
|
|
94
|
+
const keys = [];
|
|
95
|
+
for (const e2 of from.references) {
|
|
96
|
+
if (e2.type !== 'property')
|
|
97
|
+
continue;
|
|
98
|
+
const n = String(e2.name_or_index);
|
|
99
|
+
if (n === '__proto__')
|
|
100
|
+
continue;
|
|
101
|
+
keys.push(n);
|
|
102
|
+
}
|
|
103
|
+
if (keys.length === 0)
|
|
104
|
+
continue;
|
|
105
|
+
const shape = `{${keys.sort().slice(0, 8).join(', ')}}`;
|
|
106
|
+
const s = byHolder.get(shape) ?? { shape, total: 0, empty: 0 };
|
|
107
|
+
s.total++;
|
|
108
|
+
if (isEmpty)
|
|
109
|
+
s.empty++;
|
|
110
|
+
byHolder.set(shape, s);
|
|
111
|
+
if (!exampleHolder.has(shape))
|
|
112
|
+
exampleHolder.set(shape, from.id);
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
const lines = ['## WeakRef census', ''];
|
|
117
|
+
if (total === 0) {
|
|
118
|
+
lines.push('_No WeakRef objects in this snapshot._');
|
|
119
|
+
return toolResult(lines.join('\n'));
|
|
120
|
+
}
|
|
121
|
+
lines.push(`**${formatNumber(total)} WeakRef(s)** — ${formatNumber(total - empty)} live, **${formatNumber(empty)} empty** (${((empty / total) * 100).toFixed(0)}% of referents already collected).`, '');
|
|
122
|
+
const rows = [...byHolder.values()]
|
|
123
|
+
.filter(s => s.total >= min_count)
|
|
124
|
+
.sort((a, b) => b.empty - a.empty || b.total - a.total)
|
|
125
|
+
.slice(0, limit);
|
|
126
|
+
if (rows.length > 0) {
|
|
127
|
+
lines.push(markdownTable(['Holder shape', 'WeakRefs', 'Empty', '% empty', 'Example'], rows.map(s => [
|
|
128
|
+
s.shape.length > 56 ? s.shape.slice(0, 53) + '…' : s.shape,
|
|
129
|
+
formatNumber(s.total),
|
|
130
|
+
formatNumber(s.empty),
|
|
131
|
+
`${((s.empty / s.total) * 100).toFixed(0)}%`,
|
|
132
|
+
`@${exampleHolder.get(s.shape) ?? 0}`,
|
|
133
|
+
]), new Set([1, 2, 3])));
|
|
134
|
+
}
|
|
135
|
+
const suspects = rows.filter(s => s.empty / s.total > 0.5);
|
|
136
|
+
if (suspects.length > 0) {
|
|
137
|
+
lines.push('', `⚠ **${suspects.length} holder shape(s) are more than half empty.** The referents were collected, so the WeakRef is doing its job — but the holder objects and their slots are still strongly held, which means nothing prunes the collection. Fix with a compaction pass over the list (drop entries whose \`deref()\` is undefined) or a \`FinalizationRegistry\`.`, '', '**Next:** `memlab_retainer_trace` an example holder to find the owning collection, then `memlab_collection_trend` on that locator to confirm it is unbounded rather than merely large.');
|
|
138
|
+
}
|
|
139
|
+
lines.push('', '_Emptiness is read from the snapshot structure, not guessed: a live WeakRef has an outgoing edge to its referent and a cleared one has only `__proto__`/`map`. A high empty share is normal immediately after a GC and is only a defect when the HOLDER count grows with it — check that on a ladder._');
|
|
140
|
+
return toolResult(lines.join('\n'));
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
return errorResult(`Failed to census WeakRefs: ${error instanceof Error ? error.message : String(error)}`);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=weakref-census.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weakref-census.js","sourceRoot":"","sources":["../../src/tools/weakref-census.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
* @oncall memory_lab
|
|
9
|
+
*/
|
|
10
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
11
|
+
export declare function registerWhatIf(server: McpServer): void;
|
|
12
|
+
//# sourceMappingURL=what-if.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"what-if.d.ts","sourceRoot":"","sources":["../../src/tools/what-if.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAwGvE,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAqOtD"}
|