src: replace heap_utils.createHeapSnapshot with v8.getHeapSnapshot · nodejs/node@d075814 (original) (raw)

`@@ -3,14 +3,88 @@

`

3

3

`const assert = require('assert');

`

4

4

`const util = require('util');

`

5

5

``

6

``

`-

let internalTestHeap;

`

``

6

`+

let internalBinding;

`

7

7

`try {

`

8

``

`-

internalTestHeap = require('internal/test/heap');

`

``

8

`+

internalBinding = require('internal/test/binding').internalBinding;

`

9

9

`} catch (e) {

`

10

10

`` console.log('using test/common/heap.js requires --expose-internals');

``

11

11

`throw e;

`

12

12

`}

`

13

``

`-

const { createJSHeapSnapshot, buildEmbedderGraph } = internalTestHeap;

`

``

13

+

``

14

`+

const { buildEmbedderGraph } = internalBinding('heap_utils');

`

``

15

`+

const { getHeapSnapshot } = require('v8');

`

``

16

+

``

17

`+

function createJSHeapSnapshot() {

`

``

18

`+

const stream = getHeapSnapshot();

`

``

19

`+

stream.pause();

`

``

20

`+

const dump = JSON.parse(stream.read());

`

``

21

`+

const meta = dump.snapshot.meta;

`

``

22

+

``

23

`+

const nodes =

`

``

24

`+

readHeapInfo(dump.nodes, meta.node_fields, meta.node_types, dump.strings);

`

``

25

`+

const edges =

`

``

26

`+

readHeapInfo(dump.edges, meta.edge_fields, meta.edge_types, dump.strings);

`

``

27

+

``

28

`+

for (const node of nodes) {

`

``

29

`+

node.incomingEdges = [];

`

``

30

`+

node.outgoingEdges = [];

`

``

31

`+

}

`

``

32

+

``

33

`+

let fromNodeIndex = 0;

`

``

34

`+

let edgeIndex = 0;

`

``

35

`+

for (const { type, name_or_index, to_node } of edges) {

`

``

36

`+

while (edgeIndex === nodes[fromNodeIndex].edge_count) {

`

``

37

`+

edgeIndex = 0;

`

``

38

`+

fromNodeIndex++;

`

``

39

`+

}

`

``

40

`+

const toNode = nodes[to_node / meta.node_fields.length];

`

``

41

`+

const fromNode = nodes[fromNodeIndex];

`

``

42

`+

const edge = {

`

``

43

`+

type,

`

``

44

`+

to: toNode,

`

``

45

`+

from: fromNode,

`

``

46

`+

name: typeof name_or_index === 'string' ? name_or_index : null

`

``

47

`+

};

`

``

48

`+

toNode.incomingEdges.push(edge);

`

``

49

`+

fromNode.outgoingEdges.push(edge);

`

``

50

`+

edgeIndex++;

`

``

51

`+

}

`

``

52

+

``

53

`+

for (const node of nodes) {

`

``

54

`+

assert.strictEqual(node.edge_count, node.outgoingEdges.length,

`

``

55

`` +

${node.edge_count} !== ${node.outgoingEdges.length});

``

``

56

`+

}

`

``

57

`+

return nodes;

`

``

58

`+

}

`

``

59

+

``

60

`+

function readHeapInfo(raw, fields, types, strings) {

`

``

61

`+

const items = [];

`

``

62

+

``

63

`+

for (let i = 0; i < raw.length; i += fields.length) {

`

``

64

`+

const item = {};

`

``

65

`+

for (let j = 0; j < fields.length; j++) {

`

``

66

`+

const name = fields[j];

`

``

67

`+

let type = types[j];

`

``

68

`+

if (Array.isArray(type)) {

`

``

69

`+

item[name] = type[raw[i + j]];

`

``

70

`+

} else if (name === 'name_or_index') { // type === 'string_or_number'

`

``

71

`+

if (item.type === 'element' || item.type === 'hidden')

`

``

72

`+

type = 'number';

`

``

73

`+

else

`

``

74

`+

type = 'string';

`

``

75

`+

}

`

``

76

+

``

77

`+

if (type === 'string') {

`

``

78

`+

item[name] = strings[raw[i + j]];

`

``

79

`+

} else if (type === 'number' || type === 'node') {

`

``

80

`+

item[name] = raw[i + j];

`

``

81

`+

}

`

``

82

`+

}

`

``

83

`+

items.push(item);

`

``

84

`+

}

`

``

85

+

``

86

`+

return items;

`

``

87

`+

}

`

14

88

``

15

89

`function inspectNode(snapshot) {

`

16

90

`return util.inspect(snapshot, { depth: 4 });

`