@memlab/core 1.1.5 → 1.1.9
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/dist/__tests__/parser/HeapParser.test.d.ts +1 -1
- package/dist/__tests__/parser/HeapParser.test.js +3 -3
- package/dist/__tests__/parser/NodeHeap.test.d.ts +1 -1
- package/dist/__tests__/parser/NodeHeap.test.js +6 -6
- package/dist/__tests__/parser/StringNode.test.d.ts +1 -1
- package/dist/__tests__/parser/StringNode.test.js +2 -2
- package/dist/__tests__/parser/traverse/HeapNodeTraverse.test.d.ts +1 -1
- package/dist/__tests__/parser/traverse/HeapNodeTraverse.test.js +3 -3
- package/dist/__tests__/utils/utils.test.d.ts +1 -1
- package/dist/__tests__/utils/utils.test.js +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +6 -3
- package/dist/lib/BaseOption.d.ts +1 -1
- package/dist/lib/BaseOption.js +1 -1
- package/dist/lib/BrowserInfo.d.ts +1 -1
- package/dist/lib/BrowserInfo.js +1 -1
- package/dist/lib/Config.d.ts +11 -2
- package/dist/lib/Config.js +25 -5
- package/dist/lib/Console.d.ts +1 -1
- package/dist/lib/Console.js +1 -1
- package/dist/lib/Constant.d.ts +1 -1
- package/dist/lib/Constant.js +1 -1
- package/dist/lib/FileManager.d.ts +1 -1
- package/dist/lib/FileManager.js +5 -3
- package/dist/lib/HeapAnalyzer.d.ts +1 -1
- package/dist/lib/HeapAnalyzer.js +26 -10
- package/dist/lib/HeapParser.d.ts +2 -2
- package/dist/lib/HeapParser.js +2 -2
- package/dist/lib/InternalValueSetter.d.ts +1 -1
- package/dist/lib/InternalValueSetter.js +1 -1
- package/dist/lib/NodeHeap.d.ts +53 -10
- package/dist/lib/NodeHeap.js +73 -22
- package/dist/lib/PackageInfoLoader.js +2 -2
- package/dist/lib/ProcessManager.d.ts +1 -1
- package/dist/lib/ProcessManager.js +1 -1
- package/dist/lib/Serializer.d.ts +1 -1
- package/dist/lib/Serializer.js +49 -26
- package/dist/lib/StringLoader.d.ts +2 -2
- package/dist/lib/StringLoader.js +2 -2
- package/dist/lib/Types.d.ts +111 -36
- package/dist/lib/Types.js +1 -1
- package/dist/lib/Utils.d.ts +1 -1
- package/dist/lib/Utils.js +55 -31
- package/dist/lib/heap-data/HeapEdge.d.ts +2 -2
- package/dist/lib/heap-data/HeapEdge.js +2 -2
- package/dist/lib/heap-data/HeapLocation.d.ts +2 -2
- package/dist/lib/heap-data/HeapLocation.js +2 -2
- package/dist/lib/heap-data/HeapNode.d.ts +3 -2
- package/dist/lib/heap-data/HeapNode.js +6 -2
- package/dist/lib/heap-data/HeapSnapshot.d.ts +3 -2
- package/dist/lib/heap-data/HeapSnapshot.js +6 -33
- package/dist/lib/heap-data/HeapStringNode.d.ts +2 -2
- package/dist/lib/heap-data/HeapStringNode.js +4 -2
- package/dist/lib/heap-data/HeapUtils.d.ts +2 -2
- package/dist/lib/heap-data/HeapUtils.js +2 -2
- package/dist/lib/heap-data/MemLabTagStore.d.ts +23 -0
- package/dist/lib/heap-data/MemLabTagStore.js +110 -0
- package/dist/lib/leak-filters/BaseLeakFilter.rule.d.ts +1 -1
- package/dist/lib/leak-filters/BaseLeakFilter.rule.js +1 -1
- package/dist/lib/leak-filters/LeakFilterRuleList.d.ts +1 -1
- package/dist/lib/leak-filters/LeakFilterRuleList.js +1 -1
- package/dist/lib/leak-filters/LeakObjectFilter.d.ts +1 -1
- package/dist/lib/leak-filters/LeakObjectFilter.js +1 -1
- package/dist/lib/leak-filters/rules/FilterByExternalFilter.rule.d.ts +1 -1
- package/dist/lib/leak-filters/rules/FilterByExternalFilter.rule.js +1 -1
- package/dist/lib/leak-filters/rules/FilterDetachedDOMElement.rule.d.ts +1 -1
- package/dist/lib/leak-filters/rules/FilterDetachedDOMElement.rule.js +1 -1
- package/dist/lib/leak-filters/rules/FilterHermesNode.rule.d.ts +1 -1
- package/dist/lib/leak-filters/rules/FilterHermesNode.rule.js +1 -1
- package/dist/lib/leak-filters/rules/FilterOverSizedNodeAsLeak.rule.d.ts +1 -1
- package/dist/lib/leak-filters/rules/FilterOverSizedNodeAsLeak.rule.js +1 -1
- package/dist/lib/leak-filters/rules/FilterStackTraceFrame.rule.d.ts +1 -1
- package/dist/lib/leak-filters/rules/FilterStackTraceFrame.rule.js +1 -1
- package/dist/lib/leak-filters/rules/FilterTrivialNode.rule.d.ts +1 -1
- package/dist/lib/leak-filters/rules/FilterTrivialNode.rule.js +1 -1
- package/dist/lib/leak-filters/rules/FilterUnmountedFiberNode.rule.d.ts +1 -1
- package/dist/lib/leak-filters/rules/FilterUnmountedFiberNode.rule.js +1 -1
- package/dist/logger/LeakClusterLogger.d.ts +1 -1
- package/dist/logger/LeakClusterLogger.js +1 -1
- package/dist/logger/LeakTraceDetailsLogger.d.ts +1 -1
- package/dist/logger/LeakTraceDetailsLogger.js +1 -1
- package/dist/modes/BaseMode.d.ts +1 -1
- package/dist/modes/BaseMode.js +1 -1
- package/dist/modes/InteractionTestMode.d.ts +1 -1
- package/dist/modes/InteractionTestMode.js +1 -1
- package/dist/modes/MeasureMode.d.ts +1 -1
- package/dist/modes/MeasureMode.js +1 -1
- package/dist/modes/RunningModes.d.ts +1 -1
- package/dist/modes/RunningModes.js +1 -1
- package/dist/paths/TraceFinder.d.ts +1 -1
- package/dist/paths/TraceFinder.js +41 -42
- package/dist/trace-cluster/ClusterUtils.d.ts +1 -1
- package/dist/trace-cluster/ClusterUtils.js +1 -1
- package/dist/trace-cluster/ClusterUtilsHelper.d.ts +1 -1
- package/dist/trace-cluster/ClusterUtilsHelper.js +1 -1
- package/dist/trace-cluster/ClusteringHeuristics.d.ts +1 -1
- package/dist/trace-cluster/ClusteringHeuristics.js +1 -1
- package/dist/trace-cluster/EvalutationMetric.d.ts +1 -1
- package/dist/trace-cluster/EvalutationMetric.js +1 -1
- package/dist/trace-cluster/SequentialClustering.d.ts +17 -0
- package/dist/trace-cluster/SequentialClustering.js +47 -0
- package/dist/trace-cluster/TraceBucket.d.ts +2 -1
- package/dist/trace-cluster/TraceBucket.js +10 -2
- package/dist/trace-cluster/TraceElement.d.ts +3 -1
- package/dist/trace-cluster/TraceElement.js +7 -1
- package/dist/trace-cluster/strategies/MLTraceSimilarityStrategy.d.ts +15 -0
- package/dist/trace-cluster/strategies/MLTraceSimilarityStrategy.js +61 -0
- package/dist/trace-cluster/strategies/TraceAsClusterStrategy.d.ts +1 -1
- package/dist/trace-cluster/strategies/TraceAsClusterStrategy.js +1 -1
- package/dist/trace-cluster/strategies/TraceSimilarityStrategy.d.ts +1 -1
- package/dist/trace-cluster/strategies/TraceSimilarityStrategy.js +1 -1
- package/dist/trace-cluster/strategies/machine-learning/DistanceMatrix.d.ts +11 -0
- package/dist/trace-cluster/strategies/machine-learning/DistanceMatrix.js +54 -0
- package/dist/trace-cluster/strategies/machine-learning/HAC.d.ts +17 -0
- package/dist/trace-cluster/strategies/machine-learning/HAC.js +122 -0
- package/dist/trace-cluster/strategies/machine-learning/Ngram.d.ts +11 -0
- package/dist/trace-cluster/strategies/machine-learning/Ngram.js +22 -0
- package/dist/trace-cluster/strategies/machine-learning/TfidfVectorizer.d.ts +38 -0
- package/dist/trace-cluster/strategies/machine-learning/TfidfVectorizer.js +144 -0
- package/package.json +1 -1
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* This source code is licensed under the MIT license found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*
|
|
8
|
-
* @emails oncall+ws_labs
|
|
9
8
|
* @format
|
|
9
|
+
* @oncall ws_labs
|
|
10
10
|
*/
|
|
11
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @emails oncall+ws_labs
|
|
8
7
|
* @format
|
|
8
|
+
* @oncall ws_labs
|
|
9
9
|
*/
|
|
10
10
|
import BaseMode from './BaseMode';
|
|
11
11
|
import type { Page } from 'puppeteer';
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* This source code is licensed under the MIT license found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*
|
|
8
|
-
* @emails oncall+ws_labs
|
|
9
8
|
* @format
|
|
9
|
+
* @oncall ws_labs
|
|
10
10
|
*/
|
|
11
11
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
12
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @emails oncall+ws_labs
|
|
8
7
|
* @format
|
|
8
|
+
* @oncall ws_labs
|
|
9
9
|
*/
|
|
10
10
|
import type { Config, IRunningMode } from '../lib/Types';
|
|
11
11
|
declare const _default: {
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* This source code is licensed under the MIT license found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*
|
|
8
|
-
* @emails oncall+ws_labs
|
|
9
8
|
* @format
|
|
9
|
+
* @oncall ws_labs
|
|
10
10
|
*/
|
|
11
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @emails oncall+ws_labs
|
|
8
7
|
* @format
|
|
8
|
+
* @oncall ws_labs
|
|
9
9
|
*/
|
|
10
10
|
import type { AnyOptions, HeapNodeIdSet, IHeapEdge, IHeapNode, IHeapSnapshot, LeakTracePathItem, Nullable, Optional, Predicator } from '../lib/Types';
|
|
11
11
|
declare class TraceFinder {
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* This source code is licensed under the MIT license found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*
|
|
8
|
-
* @emails oncall+ws_labs
|
|
9
8
|
* @format
|
|
9
|
+
* @oncall ws_labs
|
|
10
10
|
*/
|
|
11
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
@@ -89,15 +89,17 @@ class TraceFinder {
|
|
|
89
89
|
let nodesToVisitLength = 0;
|
|
90
90
|
const node = snapshot.nodes.get(ROOT_NODE_INDEX);
|
|
91
91
|
for (const edge of node.references) {
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
const toNode = edge.toNode;
|
|
93
|
+
const type = edge.type;
|
|
94
|
+
if (type === 'element') {
|
|
95
|
+
if (Utils_1.default.isDocumentDOMTreesRoot(toNode)) {
|
|
94
96
|
continue;
|
|
95
97
|
}
|
|
96
98
|
}
|
|
97
|
-
else if (
|
|
99
|
+
else if (type === 'shortcut') {
|
|
98
100
|
continue;
|
|
99
101
|
}
|
|
100
|
-
const childNodeIndex =
|
|
102
|
+
const childNodeIndex = toNode.nodeIndex;
|
|
101
103
|
nodesToVisit[nodesToVisitLength++] = childNodeIndex;
|
|
102
104
|
flags[childNodeIndex] |= flag;
|
|
103
105
|
}
|
|
@@ -303,11 +305,11 @@ class TraceFinder {
|
|
|
303
305
|
let newDominatorIndex = emptySlot;
|
|
304
306
|
let isOrphanNode = true;
|
|
305
307
|
const node = nodes.get(nodeIndex);
|
|
306
|
-
|
|
308
|
+
node.forEachReferrer((edge) => {
|
|
307
309
|
const referrerEdgeType = edge.type;
|
|
308
310
|
const referrerNodeIndex = edge.fromNode.nodeIndex;
|
|
309
311
|
if (!Utils_1.default.isEssentialEdge(referrerNodeIndex, referrerEdgeType, ROOT_NODE_INDEX)) {
|
|
310
|
-
|
|
312
|
+
return;
|
|
311
313
|
}
|
|
312
314
|
isOrphanNode = false;
|
|
313
315
|
const referrerNodeFlag = flags[referrerNodeIndex] & flag;
|
|
@@ -317,10 +319,10 @@ class TraceFinder {
|
|
|
317
319
|
if (referrerNodeIndex !== ROOT_NODE_INDEX &&
|
|
318
320
|
nodeFlag &&
|
|
319
321
|
!referrerNodeFlag) {
|
|
320
|
-
|
|
322
|
+
return;
|
|
321
323
|
}
|
|
322
324
|
if (!this.shouldTraverseEdge(edge)) {
|
|
323
|
-
|
|
325
|
+
return;
|
|
324
326
|
}
|
|
325
327
|
let referrerPostOrderIndex = nodeIndex2PostOrderIndex[referrerNodeIndex];
|
|
326
328
|
if (dominators[referrerPostOrderIndex] !== emptySlot) {
|
|
@@ -339,10 +341,10 @@ class TraceFinder {
|
|
|
339
341
|
}
|
|
340
342
|
// no need to check any further if reaching the root node
|
|
341
343
|
if (newDominatorIndex === rootPostOrderedIndex) {
|
|
342
|
-
|
|
344
|
+
return { stop: true };
|
|
343
345
|
}
|
|
344
346
|
}
|
|
345
|
-
}
|
|
347
|
+
});
|
|
346
348
|
// set root node as the dominator of orphan nodes
|
|
347
349
|
if (isOrphanNode) {
|
|
348
350
|
newDominatorIndex = rootPostOrderedIndex;
|
|
@@ -384,13 +386,12 @@ class TraceFinder {
|
|
|
384
386
|
return retainedSizes;
|
|
385
387
|
}
|
|
386
388
|
shouldIgnoreEdgeInTraceFinding(edge) {
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
}
|
|
389
|
+
const fromNode = edge.fromNode;
|
|
390
|
+
const toNode = edge.toNode;
|
|
390
391
|
return (Config_1.default.hideBrowserLeak &&
|
|
391
|
-
(Utils_1.default.isBlinkRootNode(
|
|
392
|
-
Utils_1.default.isPendingActivityNode(
|
|
393
|
-
Utils_1.default.isDetachedDOMNode(
|
|
392
|
+
(Utils_1.default.isBlinkRootNode(fromNode) ||
|
|
393
|
+
Utils_1.default.isPendingActivityNode(fromNode)) &&
|
|
394
|
+
Utils_1.default.isDetachedDOMNode(toNode));
|
|
394
395
|
}
|
|
395
396
|
shouldTraverseEdge(edge, options = {}) {
|
|
396
397
|
if (this.isBlockListedEdge(edge)) {
|
|
@@ -400,31 +401,22 @@ class TraceFinder {
|
|
|
400
401
|
}
|
|
401
402
|
// remove edges that are already part of reported leaked paths
|
|
402
403
|
isBlockListedEdge(edge) {
|
|
403
|
-
|
|
404
|
-
return false;
|
|
405
|
-
}
|
|
406
|
-
const isStrName = typeof edge.name_or_index === 'string';
|
|
404
|
+
const nameOrIndex = edge.name_or_index;
|
|
407
405
|
if (!Config_1.default.traverseDevToolsConsole &&
|
|
408
406
|
edge.type === 'internal' &&
|
|
409
|
-
|
|
410
|
-
|
|
407
|
+
typeof nameOrIndex === 'string' &&
|
|
408
|
+
nameOrIndex.indexOf('DevTools console') >= 0) {
|
|
411
409
|
return true;
|
|
412
410
|
}
|
|
413
|
-
if (Config_1.default.edgeNameBlockList.has(String(
|
|
411
|
+
if (Config_1.default.edgeNameBlockList.has(String(nameOrIndex))) {
|
|
414
412
|
return true;
|
|
415
413
|
}
|
|
416
414
|
return false;
|
|
417
415
|
}
|
|
418
416
|
isLessPreferableEdge(edge) {
|
|
419
|
-
if (!edge) {
|
|
420
|
-
return false;
|
|
421
|
-
}
|
|
422
417
|
return Config_1.default.edgeNameGreyList.has(String(edge.name_or_index));
|
|
423
418
|
}
|
|
424
419
|
isLessPreferableNode(node) {
|
|
425
|
-
if (!node) {
|
|
426
|
-
return false;
|
|
427
|
-
}
|
|
428
420
|
return Config_1.default.nodeNameGreyList.has(node.name);
|
|
429
421
|
}
|
|
430
422
|
// each edge is indexed by fromNode's ID, toNode's ID, edge name, and edge type
|
|
@@ -434,16 +426,21 @@ class TraceFinder {
|
|
|
434
426
|
return `${fromNode.id}|${edge.name_or_index}|${edge.type}|${toNode.id}`;
|
|
435
427
|
}
|
|
436
428
|
calculateAllNodesRetainedSizes(snapshot) {
|
|
437
|
-
Console_1.default.overwrite('calculating dominators and retained sizes
|
|
429
|
+
Console_1.default.overwrite('calculating dominators and retained sizes .');
|
|
438
430
|
// step 1: build post order index
|
|
439
431
|
const flags = new Uint32Array(snapshot.nodes.length);
|
|
432
|
+
Console_1.default.overwrite('calculating dominators and retained sizes ..');
|
|
440
433
|
this.flagReachableNodesFromWindow(snapshot, flags, PAGE_OBJECT_FLAG);
|
|
434
|
+
Console_1.default.overwrite('calculating dominators and retained sizes ...');
|
|
441
435
|
const postOrderInfo = this.buildPostOrderIndex(snapshot, flags);
|
|
442
436
|
// step 2: build dominator relations
|
|
437
|
+
Console_1.default.overwrite('calculating dominators and retained sizes .');
|
|
443
438
|
const dominatorInfo = this.calculateDominatorNodesFromPostOrder(snapshot.nodes, snapshot.edges, postOrderInfo, flags);
|
|
444
439
|
// step 3: calculate retained sizes
|
|
440
|
+
Console_1.default.overwrite('calculating dominators and retained sizes ..');
|
|
445
441
|
const retainedSizes = this.calculateRetainedSizesFromDominatorNodes(snapshot.nodes, dominatorInfo, postOrderInfo);
|
|
446
442
|
// step 4: assign retained sizes and dominators to nodes
|
|
443
|
+
Console_1.default.overwrite('calculating dominators and retained sizes ...');
|
|
447
444
|
for (let i = 0; i < retainedSizes.length; i++) {
|
|
448
445
|
const node = snapshot.nodes.get(i);
|
|
449
446
|
node.retainedSize = retainedSizes[i];
|
|
@@ -473,8 +470,9 @@ class TraceFinder {
|
|
|
473
470
|
const node = curQueue.pop();
|
|
474
471
|
visited[node.nodeIndex] = 1;
|
|
475
472
|
for (const edge of node.references) {
|
|
473
|
+
const toNode = edge.toNode;
|
|
476
474
|
// skip nodes that already have a parent
|
|
477
|
-
if (
|
|
475
|
+
if (toNode.hasPathEdge) {
|
|
478
476
|
continue;
|
|
479
477
|
}
|
|
480
478
|
if (!this.shouldTraverseEdge(edge, traverseOption)) {
|
|
@@ -491,31 +489,32 @@ class TraceFinder {
|
|
|
491
489
|
}
|
|
492
490
|
// postpone traversing edges and nodes that are less preferable
|
|
493
491
|
if (this.isLessPreferableEdge(edge) ||
|
|
494
|
-
this.isLessPreferableNode(
|
|
492
|
+
this.isLessPreferableNode(toNode)) {
|
|
495
493
|
postponeQueue.push(edge);
|
|
496
494
|
}
|
|
497
495
|
else {
|
|
498
|
-
|
|
499
|
-
nextQueue.push(
|
|
496
|
+
toNode.pathEdge = edge;
|
|
497
|
+
nextQueue.push(toNode);
|
|
500
498
|
}
|
|
501
|
-
queued[
|
|
499
|
+
queued[toNode.nodeIndex] = 1;
|
|
502
500
|
}
|
|
503
501
|
}
|
|
504
502
|
// if no other preferable traces available
|
|
505
503
|
// traverse the postpone queue
|
|
506
504
|
while (nextQueue.length === 0 && postponeQueue.length > 0) {
|
|
507
505
|
const edge = postponeQueue.pop();
|
|
508
|
-
|
|
506
|
+
const toNode = edge.toNode;
|
|
507
|
+
if (toNode.hasPathEdge) {
|
|
509
508
|
continue;
|
|
510
509
|
}
|
|
511
|
-
|
|
512
|
-
nextQueue.push(
|
|
510
|
+
toNode.pathEdge = edge;
|
|
511
|
+
nextQueue.push(toNode);
|
|
513
512
|
}
|
|
514
513
|
// if no other preferable traces available
|
|
515
514
|
// consider the low priority root nodes
|
|
516
515
|
while (nextQueue.length === 0 && lowPriRootLists.length > 0) {
|
|
517
516
|
const root = lowPriRootLists.pop();
|
|
518
|
-
if (root.
|
|
517
|
+
if (root.hasPathEdge) {
|
|
519
518
|
continue;
|
|
520
519
|
}
|
|
521
520
|
nextQueue.push(root);
|
|
@@ -524,11 +523,11 @@ class TraceFinder {
|
|
|
524
523
|
}
|
|
525
524
|
}
|
|
526
525
|
getPathToGCRoots(_snapshot, node) {
|
|
527
|
-
if (!node || !node.
|
|
526
|
+
if (!node || !node.hasPathEdge) {
|
|
528
527
|
return null;
|
|
529
528
|
}
|
|
530
529
|
let path = { node };
|
|
531
|
-
while (node && node.
|
|
530
|
+
while (node && node.hasPathEdge) {
|
|
532
531
|
const edge = node.pathEdge;
|
|
533
532
|
path = { node: edge.fromNode, edge, next: path };
|
|
534
533
|
node = edge.fromNode;
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @emails oncall+ws_labs
|
|
8
7
|
* @format
|
|
8
|
+
* @oncall ws_labs
|
|
9
9
|
*/
|
|
10
10
|
declare const _default: {
|
|
11
11
|
isSimilarTrace: (t1: import("..").LeakTrace, t2: import("..").LeakTrace) => boolean;
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* This source code is licensed under the MIT license found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*
|
|
8
|
-
* @emails oncall+ws_labs
|
|
9
8
|
* @format
|
|
9
|
+
* @oncall ws_labs
|
|
10
10
|
*/
|
|
11
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @emails oncall+ws_labs
|
|
8
7
|
* @format
|
|
8
|
+
* @oncall ws_labs
|
|
9
9
|
*/
|
|
10
10
|
import type { AnyValue, LeakTraceElement, LeakTrace } from '../lib/Types';
|
|
11
11
|
declare type NameWeightMapType = Map<string | RegExp | number, number>;
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* This source code is licensed under the MIT license found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*
|
|
8
|
-
* @emails oncall+ws_labs
|
|
9
8
|
* @format
|
|
9
|
+
* @oncall ws_labs
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.debugTraceElementSimilarityStats = exports.debugLog = void 0;
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* This source code is licensed under the MIT license found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*
|
|
8
|
-
* @emails oncall+ws_labs
|
|
9
8
|
* @format
|
|
9
|
+
* @oncall ws_labs
|
|
10
10
|
*/
|
|
11
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @emails oncall+ws_labs
|
|
8
7
|
* @format
|
|
8
|
+
* @oncall ws_labs
|
|
9
9
|
*/
|
|
10
10
|
declare type ClusteredLeakTraces = Record<string, string>;
|
|
11
11
|
declare const _default: {
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* This source code is licensed under the MIT license found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*
|
|
8
|
-
* @emails oncall+ws_labs
|
|
9
8
|
* @format
|
|
9
|
+
* @oncall ws_labs
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
////////////////////////
|
|
@@ -0,0 +1,17 @@
|
|
|
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 ws_labs
|
|
9
|
+
*/
|
|
10
|
+
import type { LeakTrace } from '../lib/Types';
|
|
11
|
+
export default class SequentialClustering {
|
|
12
|
+
private existingRepresentativeTraces;
|
|
13
|
+
private traceSimilarity;
|
|
14
|
+
constructor();
|
|
15
|
+
cluster(newLeakTraces: LeakTrace[]): LeakTrace[][];
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=SequentialClustering.d.ts.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall ws_labs
|
|
10
|
+
*/
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const ClusterUtils_1 = __importDefault(require("./ClusterUtils"));
|
|
16
|
+
const TraceSimilarityStrategy_1 = __importDefault(require("./strategies/TraceSimilarityStrategy"));
|
|
17
|
+
const MLTraceSimilarityStrategy_1 = __importDefault(require("./strategies/MLTraceSimilarityStrategy"));
|
|
18
|
+
const Config_1 = __importDefault(require("../lib/Config"));
|
|
19
|
+
class SequentialClustering {
|
|
20
|
+
constructor() {
|
|
21
|
+
this.existingRepresentativeTraces = [];
|
|
22
|
+
this.traceSimilarity = Config_1.default.isMLClustering
|
|
23
|
+
? new MLTraceSimilarityStrategy_1.default()
|
|
24
|
+
: new TraceSimilarityStrategy_1.default();
|
|
25
|
+
}
|
|
26
|
+
cluster(newLeakTraces) {
|
|
27
|
+
const { allClusters: clusters } = this.traceSimilarity.diffTraces(newLeakTraces, []);
|
|
28
|
+
const representativeTracesToAdd = [];
|
|
29
|
+
// Second round of clustering and relabeling
|
|
30
|
+
outer: for (let i = 0; i < clusters.length; i++) {
|
|
31
|
+
const newRepTrace = clusters[i][0];
|
|
32
|
+
for (const exRepTrace of this.existingRepresentativeTraces) {
|
|
33
|
+
if (ClusterUtils_1.default.isSimilarTrace(exRepTrace, newRepTrace)) {
|
|
34
|
+
clusters[i].unshift(exRepTrace);
|
|
35
|
+
continue outer;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
representativeTracesToAdd.push(newRepTrace);
|
|
39
|
+
}
|
|
40
|
+
this.existingRepresentativeTraces = [
|
|
41
|
+
...this.existingRepresentativeTraces,
|
|
42
|
+
...representativeTracesToAdd,
|
|
43
|
+
];
|
|
44
|
+
return clusters;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.default = SequentialClustering;
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @emails oncall+ws_labs
|
|
8
7
|
* @format
|
|
8
|
+
* @oncall ws_labs
|
|
9
9
|
*/
|
|
10
10
|
import type { IHeapNode, IHeapSnapshot, LeakTrace, LeakTracePathItem, Optional, TraceCluster, TraceClusterDiff, IClusterStrategy } from '../lib/Types';
|
|
11
11
|
import type { NormalizedTraceElement } from './TraceElement';
|
|
@@ -25,6 +25,7 @@ export default class NormalizedTrace {
|
|
|
25
25
|
private static diffTraces;
|
|
26
26
|
static diffClusters(newClusters: TraceCluster[], existingClusters: TraceCluster[]): TraceClusterDiff;
|
|
27
27
|
static clusterLeakTraces(leakTraces: LeakTrace[]): Record<string, string>;
|
|
28
|
+
static clusteredLeakTracesToRecord(allClusters: LeakTrace[][]): Record<string, string>;
|
|
28
29
|
static filterClusters(clusters: TraceCluster[]): TraceCluster[];
|
|
29
30
|
static clusterPaths(paths: LeakTracePathItem[], snapshot: IHeapSnapshot, aggregateDominatorMetrics: AggregateNodeCb, option?: {
|
|
30
31
|
strategy?: IClusterStrategy;
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* This source code is licensed under the MIT license found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*
|
|
8
|
-
* @emails oncall+ws_labs
|
|
9
8
|
* @format
|
|
9
|
+
* @oncall ws_labs
|
|
10
10
|
*/
|
|
11
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
@@ -20,6 +20,7 @@ const Utils_1 = __importDefault(require("../lib/Utils"));
|
|
|
20
20
|
const TraceElement_1 = require("./TraceElement");
|
|
21
21
|
const TraceSimilarityStrategy_1 = __importDefault(require("./strategies/TraceSimilarityStrategy"));
|
|
22
22
|
const TraceAsClusterStrategy_1 = __importDefault(require("./strategies/TraceAsClusterStrategy"));
|
|
23
|
+
const MLTraceSimilarityStrategy_1 = __importDefault(require("./strategies/MLTraceSimilarityStrategy"));
|
|
23
24
|
// sync up with html/intern/js/webspeed/memlab/lib/LeakCluster.js
|
|
24
25
|
class NormalizedTrace {
|
|
25
26
|
constructor(p = null, snapshot = null) {
|
|
@@ -157,7 +158,14 @@ class NormalizedTrace {
|
|
|
157
158
|
};
|
|
158
159
|
}
|
|
159
160
|
static clusterLeakTraces(leakTraces) {
|
|
160
|
-
const { allClusters } = NormalizedTrace.diffTraces(leakTraces, []
|
|
161
|
+
const { allClusters } = NormalizedTrace.diffTraces(leakTraces, [], {
|
|
162
|
+
strategy: Config_1.default.isMLClustering
|
|
163
|
+
? new MLTraceSimilarityStrategy_1.default()
|
|
164
|
+
: undefined,
|
|
165
|
+
});
|
|
166
|
+
return NormalizedTrace.clusteredLeakTracesToRecord(allClusters);
|
|
167
|
+
}
|
|
168
|
+
static clusteredLeakTracesToRecord(allClusters) {
|
|
161
169
|
const lastNodeFromTrace = (trace) => trace[trace.length - 1];
|
|
162
170
|
const labaledLeakTraces = allClusters.reduce((acc, bucket) => {
|
|
163
171
|
const lastNodeFromFirstTrace = lastNodeFromTrace(bucket[0]);
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @emails oncall+ws_labs
|
|
8
7
|
* @format
|
|
8
|
+
* @oncall ws_labs
|
|
9
9
|
*/
|
|
10
10
|
import type { EdgeIterationCallback, IHeapEdge, IHeapLocation, IHeapNode, IHeapSnapshot, IHeapStringNode, Nullable } from '../lib/Types';
|
|
11
11
|
export declare class NodeRecord implements IHeapNode {
|
|
@@ -37,6 +37,8 @@ export declare class NodeRecord implements IHeapNode {
|
|
|
37
37
|
findAnyReference(): Nullable<IHeapEdge>;
|
|
38
38
|
findAnyReferrer(): Nullable<IHeapEdge>;
|
|
39
39
|
findReferrers(): IHeapEdge[];
|
|
40
|
+
set hasPathEdge(f: boolean);
|
|
41
|
+
get hasPathEdge(): boolean;
|
|
40
42
|
set pathEdge(r: IHeapEdge);
|
|
41
43
|
get pathEdge(): IHeapEdge;
|
|
42
44
|
set dominatorNode(r: IHeapNode);
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* This source code is licensed under the MIT license found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*
|
|
8
|
-
* @emails oncall+ws_labs
|
|
9
8
|
* @format
|
|
9
|
+
* @oncall ws_labs
|
|
10
10
|
*/
|
|
11
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
@@ -79,6 +79,12 @@ class NodeRecord {
|
|
|
79
79
|
findReferrers() {
|
|
80
80
|
throw new Error('NodeRecord.findReferrers is not implemented');
|
|
81
81
|
}
|
|
82
|
+
set hasPathEdge(f) {
|
|
83
|
+
throw new Error('NodeRecord.hasPathEdge cannot be assigned');
|
|
84
|
+
}
|
|
85
|
+
get hasPathEdge() {
|
|
86
|
+
throw new Error('NodeRecord.hasPathEdge cannot be read');
|
|
87
|
+
}
|
|
82
88
|
set pathEdge(r) {
|
|
83
89
|
throw new Error('NodeRecord.pathEdge cannot be assigned');
|
|
84
90
|
}
|
|
@@ -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 ws_labs
|
|
9
|
+
*/
|
|
10
|
+
import type { IClusterStrategy, LeakTrace, TraceDiff } from '../../lib/Types';
|
|
11
|
+
export default class MLTraceSimilarityStrategy implements IClusterStrategy {
|
|
12
|
+
diffTraces(newLeakTraces: LeakTrace[]): TraceDiff;
|
|
13
|
+
traceToDoc(trace: LeakTrace): string;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=MLTraceSimilarityStrategy.d.ts.map
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall ws_labs
|
|
10
|
+
*/
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const Config_1 = __importDefault(require("../../lib/Config"));
|
|
16
|
+
const DistanceMatrix_1 = require("./machine-learning/DistanceMatrix");
|
|
17
|
+
const HAC_1 = require("./machine-learning/HAC");
|
|
18
|
+
const TfidfVectorizer_1 = require("./machine-learning/TfidfVectorizer");
|
|
19
|
+
class MLTraceSimilarityStrategy {
|
|
20
|
+
diffTraces(newLeakTraces) {
|
|
21
|
+
var _a;
|
|
22
|
+
const rawDocuments = newLeakTraces.map(this.traceToDoc);
|
|
23
|
+
const vectorizer = new TfidfVectorizer_1.TfidfVectorizer({ rawDocuments });
|
|
24
|
+
const tfidfs = vectorizer.computeTfidfs();
|
|
25
|
+
const dmatrix = (0, DistanceMatrix_1.distance)(tfidfs);
|
|
26
|
+
const result = (0, HAC_1.cluster)(rawDocuments.length, dmatrix, Config_1.default.mlClusteringLinkageMaxDistance);
|
|
27
|
+
const map = new Map();
|
|
28
|
+
for (let i = 0; i < result.length; i++) {
|
|
29
|
+
const traceIdx = result[i];
|
|
30
|
+
const repTrace = newLeakTraces[traceIdx];
|
|
31
|
+
const trace = newLeakTraces[i];
|
|
32
|
+
if (!map.has(repTrace)) {
|
|
33
|
+
map.set(repTrace, [repTrace]);
|
|
34
|
+
}
|
|
35
|
+
// to please linter
|
|
36
|
+
(_a = map.get(repTrace)) === null || _a === void 0 ? void 0 : _a.push(trace);
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
allClusters: Array.from(map.values()),
|
|
40
|
+
staleClusters: [],
|
|
41
|
+
clustersToAdd: [],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
traceToDoc(trace) {
|
|
45
|
+
const res = [];
|
|
46
|
+
for (const t of trace) {
|
|
47
|
+
let name = t.kind === 'node' ? String(t.name) : String(t.name_or_index);
|
|
48
|
+
if (name === '') {
|
|
49
|
+
name = '_null_';
|
|
50
|
+
}
|
|
51
|
+
name = name.replace(/ /g, '_');
|
|
52
|
+
name = name.replace(/\d/g, '');
|
|
53
|
+
if (name === '') {
|
|
54
|
+
name = '_number_';
|
|
55
|
+
}
|
|
56
|
+
res.push(name);
|
|
57
|
+
}
|
|
58
|
+
return res.join(' ');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.default = MLTraceSimilarityStrategy;
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @emails oncall+ws_labs
|
|
8
7
|
* @format
|
|
8
|
+
* @oncall ws_labs
|
|
9
9
|
*/
|
|
10
10
|
import type { IClusterStrategy, LeakTrace, TraceDiff } from '../../lib/Types';
|
|
11
11
|
export default class TraceAsClusterStrategy implements IClusterStrategy {
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* This source code is licensed under the MIT license found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*
|
|
8
|
-
* @emails oncall+ws_labs
|
|
9
8
|
* @format
|
|
9
|
+
* @oncall ws_labs
|
|
10
10
|
*/
|
|
11
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @emails oncall+ws_labs
|
|
8
7
|
* @format
|
|
8
|
+
* @oncall ws_labs
|
|
9
9
|
*/
|
|
10
10
|
import type { IClusterStrategy, LeakTrace, TraceDiff } from '../../lib/Types';
|
|
11
11
|
export default class TraceSimilarityStrategy implements IClusterStrategy {
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* This source code is licensed under the MIT license found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*
|
|
8
|
-
* @emails oncall+ws_labs
|
|
9
8
|
* @format
|
|
9
|
+
* @oncall ws_labs
|
|
10
10
|
*/
|
|
11
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|