@memlab/mcp-server 2.3.0 → 2.52.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 +18 -14
- package/bin/.eslintrc.js +26 -0
- package/bin/memlab-cli.js +313 -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/guardrail.d.ts.map +1 -1
- package/dist/guardrail.js +13 -0
- package/dist/guardrail.js.map +1 -1
- package/dist/heap-state.d.ts +96 -2
- package/dist/heap-state.d.ts.map +1 -1
- package/dist/heap-state.js +197 -2
- package/dist/heap-state.js.map +1 -1
- package/dist/index.js +41 -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/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/string-index.d.ts +55 -0
- package/dist/string-index.d.ts.map +1 -0
- package/dist/string-index.js +91 -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 +343 -0
- package/dist/tools/analyze-run.js.map +1 -0
- package/dist/tools/app-heap.d.ts +12 -0
- package/dist/tools/app-heap.d.ts.map +1 -0
- package/dist/tools/app-heap.js +140 -0
- package/dist/tools/app-heap.js.map +1 -0
- package/dist/tools/auto-investigate.d.ts.map +1 -1
- package/dist/tools/auto-investigate.js +91 -49
- 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 +168 -0
- package/dist/tools/batch.js.map +1 -0
- package/dist/tools/cache-analysis.d.ts.map +1 -1
- package/dist/tools/cache-analysis.js +156 -5
- package/dist/tools/cache-analysis.js.map +1 -1
- 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-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 +2 -0
- package/dist/tools/detached-dom.d.ts.map +1 -1
- package/dist/tools/detached-dom.js +291 -20
- 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 +466 -23
- 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 +101 -44
- package/dist/tools/diff-snapshots.js.map +1 -1
- 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 +46 -38
- package/dist/tools/duplicated-strings.js.map +1 -1
- package/dist/tools/eval.d.ts +1 -0
- package/dist/tools/eval.d.ts.map +1 -1
- package/dist/tools/eval.js +787 -30
- package/dist/tools/eval.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 +170 -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 +22 -0
- package/dist/tools/finding-index.d.ts.map +1 -0
- package/dist/tools/finding-index.js +247 -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-references.d.ts.map +1 -1
- package/dist/tools/get-references.js +35 -6
- package/dist/tools/get-references.js.map +1 -1
- package/dist/tools/get-referrers.d.ts.map +1 -1
- package/dist/tools/get-referrers.js +52 -6
- package/dist/tools/get-referrers.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 +221 -0
- package/dist/tools/hypothesis.js.map +1 -0
- package/dist/tools/intern-opportunities.d.ts.map +1 -1
- package/dist/tools/intern-opportunities.js +721 -75
- package/dist/tools/intern-opportunities.js.map +1 -1
- 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 +43 -16
- package/dist/tools/largest-objects.js.map +1 -1
- package/dist/tools/leak-report.d.ts +12 -0
- package/dist/tools/leak-report.d.ts.map +1 -0
- package/dist/tools/leak-report.js +256 -0
- package/dist/tools/leak-report.js.map +1 -0
- package/dist/tools/load-snapshot.d.ts +78 -0
- package/dist/tools/load-snapshot.d.ts.map +1 -1
- package/dist/tools/load-snapshot.js +519 -29
- 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/object-shape.d.ts.map +1 -1
- package/dist/tools/object-shape.js +92 -30
- 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/quick-diagnosis.d.ts.map +1 -1
- package/dist/tools/quick-diagnosis.js +12 -4
- package/dist/tools/quick-diagnosis.js.map +1 -1
- 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 +1 -0
- package/dist/tools/retainer-summary.d.ts.map +1 -1
- package/dist/tools/retainer-summary.js +128 -32
- 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 +105 -25
- package/dist/tools/retainer-trace.js.map +1 -1
- 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 +49 -0
- package/dist/tools/sequence-analysis.d.ts.map +1 -1
- package/dist/tools/sequence-analysis.js +268 -78
- package/dist/tools/sequence-analysis.js.map +1 -1
- 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 +22 -4
- package/dist/tools/sliced-strings.js.map +1 -1
- package/dist/tools/snapshot-header.d.ts +28 -0
- package/dist/tools/snapshot-header.d.ts.map +1 -0
- package/dist/tools/snapshot-header.js +111 -0
- package/dist/tools/snapshot-header.js.map +1 -0
- package/dist/tools/string-patterns.d.ts.map +1 -1
- package/dist/tools/string-patterns.js +5 -4
- 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 +342 -0
- package/dist/tools/tools-index.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 +211 -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/utils.d.ts +204 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +478 -8
- package/dist/utils.js.map +1 -1
- package/package.json +5 -4
|
@@ -0,0 +1,211 @@
|
|
|
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, 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
|
+
'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). ' +
|
|
114
|
+
'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. ' +
|
|
115
|
+
'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.', {
|
|
116
|
+
metric_kind: z
|
|
117
|
+
.enum(['collection_length', 'class_count', 'pending_chain'])
|
|
118
|
+
.describe('What to measure on every rung of both arms.'),
|
|
119
|
+
locator: z
|
|
120
|
+
.string()
|
|
121
|
+
.describe('For collection_length / pending_chain: "<OwnerClass>.<property>" (deeper paths allowed). For class_count: the class name alone.'),
|
|
122
|
+
before_paths: z
|
|
123
|
+
.array(z.string())
|
|
124
|
+
.describe('Ordered rungs of the UNFIXED arm, oldest first. A single ["ladder:<name>"] element expands to a saved ladder.'),
|
|
125
|
+
after_paths: z
|
|
126
|
+
.array(z.string())
|
|
127
|
+
.describe('Ordered rungs of the FIXED arm, oldest first.'),
|
|
128
|
+
cycles: z
|
|
129
|
+
.number()
|
|
130
|
+
.describe('Interaction cycles driven between consecutive rungs. Must be the same for both arms — otherwise the rates are not comparable.'),
|
|
131
|
+
expected_reduction: z
|
|
132
|
+
.number()
|
|
133
|
+
.optional()
|
|
134
|
+
.default(0.9)
|
|
135
|
+
.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.'),
|
|
136
|
+
chain_edge: z
|
|
137
|
+
.string()
|
|
138
|
+
.optional()
|
|
139
|
+
.default('next')
|
|
140
|
+
.describe('Edge name to follow for metric_kind "pending_chain" (default "next").'),
|
|
141
|
+
max_file_size_mb: z
|
|
142
|
+
.number()
|
|
143
|
+
.optional()
|
|
144
|
+
.describe('Per-file size limit override (MB).'),
|
|
145
|
+
}, async ({ metric_kind, locator, before_paths, after_paths, cycles, expected_reduction, chain_edge, max_file_size_mb, }) => {
|
|
146
|
+
try {
|
|
147
|
+
const before = resolveLadderPaths(before_paths).paths;
|
|
148
|
+
const after = resolveLadderPaths(after_paths).paths;
|
|
149
|
+
for (const [label, arm] of [
|
|
150
|
+
['before_paths', before],
|
|
151
|
+
['after_paths', after],
|
|
152
|
+
]) {
|
|
153
|
+
if (arm.length < 2) {
|
|
154
|
+
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.`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (cycles <= 0) {
|
|
158
|
+
return errorResult('cycles must be greater than 0.');
|
|
159
|
+
}
|
|
160
|
+
if (expected_reduction < 0 || expected_reduction > 1) {
|
|
161
|
+
return errorResult('expected_reduction must be between 0 and 1.');
|
|
162
|
+
}
|
|
163
|
+
const b = await measureArm(before, metric_kind, locator, chain_edge, max_file_size_mb);
|
|
164
|
+
const a = await measureArm(after, metric_kind, locator, chain_edge, max_file_size_mb);
|
|
165
|
+
const beforeRate = perCycleRate(b.values, cycles);
|
|
166
|
+
const afterRate = perCycleRate(a.values, cycles);
|
|
167
|
+
const fmtRate = (r) => Math.abs(r) < 10 ? r.toFixed(2) : formatNumber(Math.round(r));
|
|
168
|
+
const lines = [
|
|
169
|
+
`## Fix verification — \`${metric_kind}\` on \`${locator}\``,
|
|
170
|
+
'',
|
|
171
|
+
markdownTable(['Arm', 'Rungs', 'First', 'Last', 'Net', 'Per cycle'], [
|
|
172
|
+
[
|
|
173
|
+
'before (unfixed)',
|
|
174
|
+
String(b.values.length),
|
|
175
|
+
formatNumber(b.values[0]),
|
|
176
|
+
formatNumber(b.values[b.values.length - 1]),
|
|
177
|
+
formatNumber(b.values[b.values.length - 1] - b.values[0]),
|
|
178
|
+
fmtRate(beforeRate),
|
|
179
|
+
],
|
|
180
|
+
[
|
|
181
|
+
'after (fixed)',
|
|
182
|
+
String(a.values.length),
|
|
183
|
+
formatNumber(a.values[0]),
|
|
184
|
+
formatNumber(a.values[a.values.length - 1]),
|
|
185
|
+
formatNumber(a.values[a.values.length - 1] - a.values[0]),
|
|
186
|
+
fmtRate(afterRate),
|
|
187
|
+
],
|
|
188
|
+
], new Set([1, 2, 3, 4, 5])),
|
|
189
|
+
'',
|
|
190
|
+
`- before series: ${b.values.map(v => formatNumber(v)).join(' → ')}`,
|
|
191
|
+
`- after series: ${a.values.map(v => formatNumber(v)).join(' → ')}`,
|
|
192
|
+
'',
|
|
193
|
+
];
|
|
194
|
+
if (beforeRate <= 0) {
|
|
195
|
+
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.`);
|
|
196
|
+
return toolResult(lines.join('\n'));
|
|
197
|
+
}
|
|
198
|
+
const reduction = (beforeRate - afterRate) / beforeRate;
|
|
199
|
+
const pass = reduction >= expected_reduction;
|
|
200
|
+
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
|
|
201
|
+
? `✅ **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.'}`
|
|
202
|
+
: `❌ **FAIL** — ${(reduction * 100).toFixed(1)}% is short of the expected ${(expected_reduction * 100).toFixed(0)}%. The fixed arm still accumulates ${fmtRate(afterRate)} per cycle.`);
|
|
203
|
+
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._`);
|
|
204
|
+
return toolResult(lines.join('\n'));
|
|
205
|
+
}
|
|
206
|
+
catch (err) {
|
|
207
|
+
return errorResult(err);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
//# 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":"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,kEAAkE;gBAClE,mEAAmE;gBACnE,4DAA4D;gBAC5D,wBAAwB;gBACxB,MAAM,SAAS,GAAgB,EAAE,CAAC;gBAClC,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;oBAClC,IAAI,EAAE,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,KAAK,EAAE,CAAC;wBAC/D,SAAS;oBACX,CAAC;oBACD,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;gBAC5B,CAAC;gBAED,sEAAsE;gBACtE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;oBACjD,MAAM,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;oBACzB,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;oBAC/B,IAAI,GAAG,CAAC,EAAE,IAAI,CAAC;wBAAE,SAAS;oBAC1B,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU;wBAAE,SAAS;oBAClE,OAAO,CAAC,IAAI,CAAC;wBACX,GAAG;wBACH,KAAK;wBACL,WAAW,EAAE,GAAG,CAAC,YAAY;wBAC7B,aAAa,EAAE,KAAK,CAAC,YAAY;qBAClC,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM;YACR,CAAC;YAED,wEAAwE;YACxE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;oBACnC,IACE,IAAI,CAAC,IAAI,KAAK,MAAM;wBACpB,IAAI,CAAC,IAAI,KAAK,UAAU;wBACxB,IAAI,CAAC,IAAI,KAAK,SAAS;wBAEvB,SAAS;oBACX,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;oBAC3B,IAAI,MAAM,CAAC,EAAE,IAAI,CAAC;wBAAE,SAAS;oBAC7B,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU;wBAC3D,SAAS;oBACX,0DAA0D;oBAC1D,uEAAuE;oBACvE,OAAO,CAAC,IAAI,CAAC;wBACX,GAAG,EAAE,MAAM;wBACX,KAAK,EAAE,MAAM;wBACb,WAAW,EAAE,MAAM,CAAC,YAAY;wBAChC,aAAa,EAAE,CAAC;qBACjB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO,UAAU,CACf,YAAY,OAAO,iCAAiC;oBAClD,mEAAmE;oBACnE,+DAA+D;oBAC/D,+BAA+B,OAAO,mCAAmC,CAC5E,CAAC;YACJ,CAAC;YAED,IAAI,OAAO,KAAK,eAAe,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;gBAC1D,OAAO,CAAC,IAAI,CACV,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,CAAC,CAAC,WAAW;oBACb,CAAC,CAAC,aAAa;oBACf,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,aAAa,CAAC,CACpC,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;YAC/D,CAAC;YAED,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YACtC,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;YACpC,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;YACxE,MAAM,kBAAkB,GAAG,OAAO,CAAC,MAAM,CACvC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,aAAa,EAC7B,CAAC,CACF,CAAC;YAEF,MAAM,OAAO,GAAG;gBACd,QAAQ;gBACR,KAAK;gBACL,cAAc;gBACd,UAAU;gBACV,OAAO;gBACP,gBAAgB;aACjB,CAAC;YACF,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAClC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;gBACzB,MAAM,OAAO,GAAG,gBAAgB,CAC9B,CAAC,CAAC,GAAG,CAAC,IAAI,EACV,CAAC,CAAC,GAAG,CAAC,IAAI,EACV,CAAC,CAAC,GAAG,CAAC,SAAS,EACf,EAAE,CACH,CAAC;gBACF,IAAI,SAAiB,CAAC;gBACtB,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC;oBACtB,SAAS,GAAG,WAAW,CAAC;gBAC1B,CAAC;qBAAM,CAAC;oBACN,SAAS,GAAG,gBAAgB,CAC1B,CAAC,CAAC,KAAK,CAAC,IAAI,EACZ,CAAC,CAAC,KAAK,CAAC,IAAI,EACZ,CAAC,CAAC,KAAK,CAAC,SAAS,EACjB,EAAE,CACH,CAAC;oBACF,IAAI,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;wBACrB,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;wBACvC,IAAI,OAAO,EAAE,CAAC;4BACZ,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC;4BAChC,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;wBACtE,CAAC;oBACH,CAAC;gBACH,CAAC;gBACD,OAAO;oBACL,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE;oBACd,GAAG,OAAO,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG;oBAC5B,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;oBAC1B,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE;oBAChB,GAAG,SAAS,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,GAAG;oBAChC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC;iBAC7B,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,MAAM,KAAK,GAAG;gBACZ,YAAY,OAAO,KAAK,YAAY,CAAC,YAAY,CAAC,UAAU;oBAC1D,CAAC,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,iBAAiB,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzD,uBAAuB,WAAW,CAAC,gBAAgB,CAAC,2BAA2B,WAAW,CAAC,kBAAkB,CAAC,EAAE;gBAChH,EAAE;gBACF,aAAa,CAAC,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC;aACxC,CAAC;YAEF,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
package/dist/utils.d.ts
CHANGED
|
@@ -40,12 +40,26 @@ export interface IncomingEdge extends EdgeSummary {
|
|
|
40
40
|
from_node: NodeSummary;
|
|
41
41
|
}
|
|
42
42
|
export declare function truncateDomToTag(name: string): string;
|
|
43
|
+
export declare const BLINK_TEMPLATE_ELISION = "<\u2026>";
|
|
44
|
+
export declare function abbreviateBlinkTypeName(name: string): string;
|
|
43
45
|
export declare function truncateNodeName(name: string, type: string, selfSize: number, maxLen?: number, aggressiveDom?: boolean): string;
|
|
44
46
|
export declare function serializeNodeSummary(node: IHeapNode): NodeSummary;
|
|
45
47
|
export declare function serializeNodeDetail(node: IHeapNode): NodeDetail;
|
|
46
48
|
export declare function serializeOutgoingEdge(edge: IHeapEdge): OutgoingEdge;
|
|
47
49
|
export declare function serializeIncomingEdge(edge: IHeapEdge): IncomingEdge;
|
|
48
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Whether a node is worth showing in a default "interesting objects" listing.
|
|
52
|
+
*
|
|
53
|
+
* `NODE_TYPE_BLOCK_LIST` exists to keep noise out of the DEFAULT view — it is not
|
|
54
|
+
* meant to make those types unreachable. When a caller explicitly asks for one
|
|
55
|
+
* of them (e.g. `largest_objects({node_type: 'array'})`), honour the request:
|
|
56
|
+
* otherwise the filter silently returns zero rows for `array`, `native`, `code`,
|
|
57
|
+
* `synthetic` and `hidden`, which reads as "there are none" on a heap that
|
|
58
|
+
* plainly contains 100k+ of them.
|
|
59
|
+
*/
|
|
60
|
+
export declare function isNodeWorthInspecting(node: IHeapNode, opts?: {
|
|
61
|
+
allowBlockedTypes?: boolean;
|
|
62
|
+
}): boolean;
|
|
49
63
|
/**
|
|
50
64
|
* Property names that mark a "freshness" timestamp on a TTL/warm cache wrapper
|
|
51
65
|
* object (e.g. `{entries, loadedAt}`, `{items, timestamp}`). Their presence next
|
|
@@ -71,6 +85,27 @@ export declare function hasFreshnessTimestampSibling(node: IHeapNode): boolean;
|
|
|
71
85
|
*/
|
|
72
86
|
export declare function looksLikeFailurePayload(value: string): boolean;
|
|
73
87
|
export declare function filterLargestObjects(snapshot: IHeapSnapshot, filter: (node: IHeapNode) => boolean, limit: number): IHeapNode[];
|
|
88
|
+
/**
|
|
89
|
+
* Collapse heap nodes that are merely different VIEWS of the same dominator
|
|
90
|
+
* subtree (e.g. on a single in-flight request: Client → Request → closure →
|
|
91
|
+
* Promise → Context → Map all reporting the SAME retained size). Without this,
|
|
92
|
+
* `largest_objects` returns ~20 rows that are all one subtree — pure noise and
|
|
93
|
+
* wasted tokens (feedback §A.2).
|
|
94
|
+
*
|
|
95
|
+
* Two nodes are treated as the same subtree ONLY when (a) their retained sizes
|
|
96
|
+
* are within `epsilon` of each other AND (b) one dominates the other within a
|
|
97
|
+
* bounded dominator walk — so unrelated objects that merely share a byte count
|
|
98
|
+
* are never collapsed. `candidates` must be pre-sorted by retained size desc;
|
|
99
|
+
* the highest dominator (ancestor) is kept as the representative, annotated with
|
|
100
|
+
* `mergedCount` = how many views were folded into it.
|
|
101
|
+
*/
|
|
102
|
+
export declare function collapseDominatorSubtrees(candidates: IHeapNode[], limit: number, opts?: {
|
|
103
|
+
epsilon?: number;
|
|
104
|
+
maxWalk?: number;
|
|
105
|
+
}): Array<{
|
|
106
|
+
node: IHeapNode;
|
|
107
|
+
mergedCount: number;
|
|
108
|
+
}>;
|
|
74
109
|
export type OutputMode = 'full' | 'count' | 'ids';
|
|
75
110
|
export interface QueryNodesResult {
|
|
76
111
|
total_count: number;
|
|
@@ -107,6 +142,85 @@ export declare function boundedDominatorRetainedSize(ids: HeapNodeIdSet, snapsho
|
|
|
107
142
|
retained: number;
|
|
108
143
|
exact: boolean;
|
|
109
144
|
};
|
|
145
|
+
/**
|
|
146
|
+
* One backing-store slot of a Map/Set/WeakMap: its true FixedArray index
|
|
147
|
+
* (`name_or_index`) and the heap node it points at.
|
|
148
|
+
*/
|
|
149
|
+
export interface BackingSlot {
|
|
150
|
+
idx: number;
|
|
151
|
+
node: IHeapNode;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* One enumerated Map/WeakMap entry. `value` is null when the value slot held an
|
|
155
|
+
* inline SMI (no heap edge) — see `enumerateMapEntries`.
|
|
156
|
+
*/
|
|
157
|
+
export interface CollectionEntry {
|
|
158
|
+
key: IHeapNode;
|
|
159
|
+
value: IHeapNode | null;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Collect the object-valued slots of a Map/Set/WeakMap backing store, sorted by
|
|
163
|
+
* their true FixedArray slot index.
|
|
164
|
+
*
|
|
165
|
+
* V8 stores entries in an OrderedHashMap/OrderedHashSet reachable via the
|
|
166
|
+
* `table` (or `backing_store`) edge. Browser (Chromium) snapshots type the
|
|
167
|
+
* key/value slot edges as `internal` with a numeric name (the array index);
|
|
168
|
+
* Node snapshots type them `element`. The header counts and hash-chain links are
|
|
169
|
+
* inline SMIs, which emit NO edge at all — so the slot indices are NOT
|
|
170
|
+
* contiguous, and the GAPS are meaningful (they mark SMI-valued or deleted
|
|
171
|
+
* slots). Returning the slots WITH their indices lets callers pair by index
|
|
172
|
+
* instead of by position, which is what makes the pairing correct when some
|
|
173
|
+
* values are SMIs (see `enumerateMapEntries`).
|
|
174
|
+
*/
|
|
175
|
+
export declare function collectBackingSlots(node: IHeapNode): BackingSlot[];
|
|
176
|
+
/**
|
|
177
|
+
* Enumerate a Map/WeakMap's (key, value) entries.
|
|
178
|
+
*
|
|
179
|
+
* V8 lays each entry out as consecutive slots `[key, value, chain]` (the chain
|
|
180
|
+
* link is an inline SMI, so it emits no edge). We therefore pair a key with the
|
|
181
|
+
* value in the immediately-following slot INDEX (`key.idx + 1`). When no slot
|
|
182
|
+
* exists at `key.idx + 1`, the value was an inline SMI/primitive and we emit
|
|
183
|
+
* `value: null` — instead of mispairing the key with the NEXT entry's key, which
|
|
184
|
+
* is what naive "consecutive object edges = key,value" pairing does whenever a
|
|
185
|
+
* Map has SMI values (a real correctness bug on browser heaps).
|
|
186
|
+
*/
|
|
187
|
+
export declare function enumerateMapEntries(node: IHeapNode): CollectionEntry[];
|
|
188
|
+
/** Enumerate a Set's elements (every occupied backing-store slot). */
|
|
189
|
+
export declare function enumerateSetElements(node: IHeapNode): IHeapNode[];
|
|
190
|
+
/**
|
|
191
|
+
* Property names that identify an individual record rather than describe its
|
|
192
|
+
* content — always unique per instance, so INCLUDING them in a content
|
|
193
|
+
* signature defeats duplicate detection (every record looks distinct). Excluded
|
|
194
|
+
* by default from `objectContentSignature`. `id`/`__id`/`__ref` are Relay/GraphQL
|
|
195
|
+
* data-id fields; `key`/`clientMutationId` are common per-instance keys.
|
|
196
|
+
*/
|
|
197
|
+
export declare const IDENTITY_PROPS: ReadonlySet<string>;
|
|
198
|
+
/**
|
|
199
|
+
* A stable, shallow content signature for an object: the sorted set of property
|
|
200
|
+
* names, each annotated with its scalar value (strings capped) or a marker for
|
|
201
|
+
* object/array-valued properties. Two objects with the same signature are
|
|
202
|
+
* structurally identical at one level — the basis for duplicate-record
|
|
203
|
+
* detection (`memlab_duplicate_objects`) and ad-hoc dedup checks in eval.
|
|
204
|
+
*
|
|
205
|
+
* By default per-instance identity fields (`IDENTITY_PROPS`: id/__id/__ref/…) are
|
|
206
|
+
* EXCLUDED so records that differ only by their data-id still collapse together
|
|
207
|
+
* — pass `ignoreProps` to override the set (e.g. `new Set()` to include them).
|
|
208
|
+
*
|
|
209
|
+
* String, boolean, null and object-valued properties are captured (objects
|
|
210
|
+
* generically as `o`, so nested content is not compared).
|
|
211
|
+
*
|
|
212
|
+
* Caveat — numeric values are NOT captured: the V8 heap-snapshot format does not
|
|
213
|
+
* store the actual value of a number field (SMI nodes are `smi number`,
|
|
214
|
+
* heap-numbers are `heap number` — the IEEE-754/int value is not accessible; see
|
|
215
|
+
* `tools/get-value.ts`). A numeric property therefore contributes only a generic
|
|
216
|
+
* `<name>=n` marker, so two objects differing ONLY in a numeric field hash to the
|
|
217
|
+
* same signature and are reported as duplicates. Treat numeric-heavy records
|
|
218
|
+
* accordingly (or compare their values via another tool).
|
|
219
|
+
*/
|
|
220
|
+
export declare function objectContentSignature(node: IHeapNode, opts?: {
|
|
221
|
+
maxStringLen?: number;
|
|
222
|
+
ignoreProps?: ReadonlySet<string>;
|
|
223
|
+
}): string;
|
|
110
224
|
/**
|
|
111
225
|
* Best-effort detection of which app a Node snapshot came from, by tallying the
|
|
112
226
|
* `/app(s)/<name>/` segment in bundle paths embedded throughout the heap (string
|
|
@@ -132,8 +246,97 @@ export declare function formatBytes(bytes: number): string;
|
|
|
132
246
|
export declare function formatNumber(n: number): string;
|
|
133
247
|
export declare function markdownTable(headers: string[], rows: string[][], alignRight?: Set<number>): string;
|
|
134
248
|
export declare function formatNodeInline(id: number, name: string, type: string, selfSize?: number): string;
|
|
249
|
+
/**
|
|
250
|
+
* One step of a retainer path, root-first. `edgeName` is the name of the edge
|
|
251
|
+
* that points INTO this node from its retainer (i.e. parent → this node, the
|
|
252
|
+
* property / element / context slot through which the parent holds this node).
|
|
253
|
+
* The GC root (first step) has no incoming edge. `collapsedBefore` records how
|
|
254
|
+
* many uninteresting internal nodes were elided immediately above this node.
|
|
255
|
+
*/
|
|
256
|
+
export interface RetainerTreeStep {
|
|
257
|
+
id: number;
|
|
258
|
+
name: string;
|
|
259
|
+
type: string;
|
|
260
|
+
retainedSize?: number;
|
|
261
|
+
selfSize?: number;
|
|
262
|
+
edgeName?: string;
|
|
263
|
+
collapsedBefore?: number;
|
|
264
|
+
collapsedNote?: string;
|
|
265
|
+
repeatCount?: number;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Collapse runs of consecutive same-class hops in a retainer path into a single
|
|
269
|
+
* step tagged with `repeatCount`.
|
|
270
|
+
*
|
|
271
|
+
* Linked structures (a React hook update queue's `pending → .next → .next → …`,
|
|
272
|
+
* intrusive lists, promise chains) produce paths that are hundreds of identical
|
|
273
|
+
* `Object → Object → Object` hops long. Rendering every hop costs thousands of
|
|
274
|
+
* tokens and tells the reader nothing the count doesn't: the interesting part is
|
|
275
|
+
* the chain's head, its length, and where it attaches. This keeps the first hop
|
|
276
|
+
* of each run (so the edge into the run is preserved) and folds the rest.
|
|
277
|
+
*
|
|
278
|
+
* Only runs of at least `minRun` are collapsed, so ordinary short paths render
|
|
279
|
+
* exactly as before.
|
|
280
|
+
*/
|
|
281
|
+
export declare function collapseRepeatedRuns(steps: RetainerTreeStep[], minRun?: number): RetainerTreeStep[];
|
|
282
|
+
/**
|
|
283
|
+
* Collapse runs of an identical rendered label, for formatters that have already
|
|
284
|
+
* reduced each hop to a string. Mirrors `collapseRepeatedRuns` for chain-style
|
|
285
|
+
* (`A → B → C`) renderers.
|
|
286
|
+
*/
|
|
287
|
+
export declare function collapseRepeatedLabels(labels: string[], minRun?: number): string[];
|
|
288
|
+
/**
|
|
289
|
+
* One-line note describing what a tool's thresholds excluded from its own
|
|
290
|
+
* output. Printing this everywhere a default threshold exists prevents the
|
|
291
|
+
* failure mode where a tool reports "0" or "none found" and the reader takes it
|
|
292
|
+
* as "there is nothing there", when in fact everything interesting was below the
|
|
293
|
+
* cutoff. (A `dev_artifacts` run reporting `0 B` dev-only — because every
|
|
294
|
+
* console-retained string was under the 512 KB default — nearly landed a
|
|
295
|
+
* measurement artifact in a diff as a production leak.)
|
|
296
|
+
*/
|
|
297
|
+
export declare function describeSkipped(examined: number, skipped: number, thresholdLabel: string): string;
|
|
298
|
+
/**
|
|
299
|
+
* Render a retainer path so it reads in a single, unambiguous direction: the GC
|
|
300
|
+
* root is at the top, and **every node is retained by the one above it**. The
|
|
301
|
+
* edge that connects a parent to its child is embedded in the connector
|
|
302
|
+
* (`└─ .prop →` / `└─ [2] →`, ladder: `↓ .prop`), and sizes as `— <bytes>`.
|
|
303
|
+
*
|
|
304
|
+
* Shallow chains use a nested indented tree (one indent level = one hop).
|
|
305
|
+
* **Deep chains automatically switch to a flat `↓` ladder** (controlled by
|
|
306
|
+
* `maxTreeDepth`, default 8) so growing indentation never pushes the leaf node
|
|
307
|
+
* off the right edge of a narrow terminal.
|
|
308
|
+
*
|
|
309
|
+
* This deliberately avoids the older inline style that mixed `←` (retained-by)
|
|
310
|
+
* and `→` (references) arrows on the same line, which made the direction of a
|
|
311
|
+
* trace genuinely hard to read in analysis output and diff summaries. Always
|
|
312
|
+
* prefer this renderer when presenting a retainer chain to a human.
|
|
313
|
+
*/
|
|
314
|
+
export declare function formatRetainerTree(steps: RetainerTreeStep[], opts?: {
|
|
315
|
+
showSizes?: boolean;
|
|
316
|
+
maxTreeDepth?: number;
|
|
317
|
+
}): string;
|
|
135
318
|
export declare function formatNodeSummaryTable(nodes: NodeSummary[]): string;
|
|
319
|
+
/**
|
|
320
|
+
* Legend for elided C++ template arguments, emitted only when something in the
|
|
321
|
+
* rendered output actually carries the marker — an unconditional legend is the
|
|
322
|
+
* same token tax the abbreviation exists to remove.
|
|
323
|
+
*/
|
|
324
|
+
export declare function blinkLegend(rendered: Iterable<string>): string;
|
|
136
325
|
export declare function formatQueryNodesResult(result: QueryNodesResult, offset?: number): string;
|
|
326
|
+
/**
|
|
327
|
+
* Build a name filter from a caller-supplied pattern.
|
|
328
|
+
*
|
|
329
|
+
* Interpreted as a case-insensitive regular expression, falling back to a plain
|
|
330
|
+
* case-insensitive substring test when the pattern is not valid regex — so a
|
|
331
|
+
* literal like `blink::UndoStep` works without escaping and a real pattern
|
|
332
|
+
* still works. An empty/absent pattern matches everything.
|
|
333
|
+
*
|
|
334
|
+
* Why this exists: answering "is `blink::UndoStep` present?" previously meant
|
|
335
|
+
* `class_histogram({node_type: "native", limit: 200})` and reading ~4 KB of
|
|
336
|
+
* table for one row. Filtering at the source is the difference between a
|
|
337
|
+
* yes/no answer and a page of output.
|
|
338
|
+
*/
|
|
339
|
+
export declare function makeNamePatternTest(pattern: string | undefined): (name: string) => boolean;
|
|
137
340
|
export declare function snapshotHeader(): string;
|
|
138
341
|
export declare function textResult(text: string): {
|
|
139
342
|
content: {
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,SAAS,EACT,aAAa,EACb,aAAa,EACd,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|