Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/test/unit/analyzeSnapshot.js
3520 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
//@ts-check
7
8
// note: we use a fork here since we can't make a worker from the renderer process
9
10
const { fork } = require('child_process');
11
const workerData = process.env.SNAPSHOT_WORKER_DATA;
12
const fs = require('fs');
13
const { pathToFileURL } = require('url');
14
15
if (!workerData) {
16
const { join } = require('path');
17
const { tmpdir } = require('os');
18
19
exports.takeSnapshotAndCountClasses = async (/** @type string */currentTest, /** @type string[] */ classes) => {
20
const cleanTitle = currentTest.replace(/[^\w]+/g, '-');
21
const file = join(tmpdir(), `vscode-test-snap-${cleanTitle}.heapsnapshot`);
22
23
if (typeof process.takeHeapSnapshot !== 'function') {
24
// node.js:
25
const inspector = require('inspector');
26
const session = new inspector.Session();
27
session.connect();
28
29
const fd = fs.openSync(file, 'w');
30
await new Promise((resolve, reject) => {
31
session.on('HeapProfiler.addHeapSnapshotChunk', (m) => {
32
fs.writeSync(fd, m.params.chunk);
33
});
34
35
session.post('HeapProfiler.takeHeapSnapshot', null, (err) => {
36
session.disconnect();
37
fs.closeSync(fd);
38
if (err) {
39
reject(err);
40
} else {
41
resolve();
42
}
43
});
44
});
45
} else {
46
// electron exposes this nice method for us:
47
process.takeHeapSnapshot(file);
48
}
49
50
const worker = fork(__filename, {
51
env: {
52
...process.env,
53
SNAPSHOT_WORKER_DATA: JSON.stringify({
54
path: file,
55
classes,
56
})
57
}
58
});
59
60
const promise = new Promise((resolve, reject) => {
61
worker.on('message', (/** @type any */msg) => {
62
if ('err' in msg) {
63
reject(new Error(msg.err));
64
} else {
65
resolve(msg.counts);
66
}
67
worker.kill();
68
});
69
});
70
71
return { done: promise, file: pathToFileURL(file) };
72
};
73
} else {
74
const { path, classes } = JSON.parse(workerData);
75
const { decode_bytes } = require('@vscode/v8-heap-parser');
76
77
fs.promises.readFile(path)
78
.then(buf => decode_bytes(buf))
79
.then(graph => graph.get_class_counts(classes))
80
.then(
81
counts => process.send({ counts: Array.from(counts) }),
82
err => process.send({ err: String(err.stack || err) })
83
);
84
85
}
86
87