Skip to content

Commit f49e01e

Browse files
committed
v8: add v8.getCppHeapStatistics() method
Expose `CppHeap` data via `cppgc::CppHeap::CollectStatistics()` in the v8 module.
1 parent cbedcd1 commit f49e01e

File tree

4 files changed

+438
-1
lines changed

4 files changed

+438
-1
lines changed

doc/api/v8.md

+90
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,92 @@ buffers and external strings.
271271
}
272272
```
273273

274+
## `v8.getCppHeapStatistics([detailLevel])`
275+
276+
Retrieves [CppHeap][] regarding memory consumption and
277+
utilization statistics using the V8 [`CollectStatistics()`][] function which
278+
may change from one V8 version to the
279+
next.
280+
281+
* `detailLevel` {string|undefined}: **Default:** `'detailed'`.
282+
Specifies the level of detail in the returned statistics.
283+
Accepted values are:
284+
* `'brief'`: Brief statistics contain only the top-level
285+
allocated and used
286+
memory statistics for the entire heap.
287+
* `'detailed'`: Detailed statistics also contain a break
288+
down per space and page, as well as freelist statistics
289+
and object type histograms.
290+
291+
It returns an object with a structure similar to the
292+
[`cppgc::HeapStatistics`][] object. See the [V8 documentation][`cppgc::HeapStatistics struct`]
293+
for more information about the properties of the object.
294+
295+
```js
296+
// Detailed
297+
({
298+
committed_size_bytes: 131072,
299+
resident_size_bytes: 131072,
300+
used_size_bytes: 152,
301+
space_statistics: [
302+
{
303+
name: 'NormalPageSpace0',
304+
committed_size_bytes: 0,
305+
resident_size_bytes: 0,
306+
used_size_bytes: 0,
307+
page_stats: [{}],
308+
free_list_stats: {},
309+
},
310+
{
311+
name: 'NormalPageSpace1',
312+
committed_size_bytes: 131072,
313+
resident_size_bytes: 131072,
314+
used_size_bytes: 152,
315+
page_stats: [{}],
316+
free_list_stats: {},
317+
},
318+
{
319+
name: 'NormalPageSpace2',
320+
committed_size_bytes: 0,
321+
resident_size_bytes: 0,
322+
used_size_bytes: 0,
323+
page_stats: [{}],
324+
free_list_stats: {},
325+
},
326+
{
327+
name: 'NormalPageSpace3',
328+
committed_size_bytes: 0,
329+
resident_size_bytes: 0,
330+
used_size_bytes: 0,
331+
page_stats: [{}],
332+
free_list_stats: {},
333+
},
334+
{
335+
name: 'LargePageSpace',
336+
committed_size_bytes: 0,
337+
resident_size_bytes: 0,
338+
used_size_bytes: 0,
339+
page_stats: [{}],
340+
free_list_stats: {},
341+
},
342+
],
343+
type_names: [],
344+
detail_level: 'detailed',
345+
});
346+
```
347+
348+
```js
349+
// Brief
350+
({
351+
committed_size_bytes: 131072,
352+
resident_size_bytes: 131072,
353+
used_size_bytes: 128864,
354+
space_statistics: [],
355+
type_names: [],
356+
detail_level: 'brief',
357+
});
358+
```
359+
274360
## `v8.queryObjects(ctor[, options])`
275361

276362
<!-- YAML
@@ -1304,12 +1390,14 @@ setTimeout(() => {
13041390
}, 1000);
13051391
```
13061392

1393+
[CppHeap]: https://v8docs.nodesource.com/node-22.4/d9/dc4/classv8_1_1_cpp_heap.html
13071394
[HTML structured clone algorithm]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
13081395
[Hook Callbacks]: #hook-callbacks
13091396
[V8]: https://developers.google.com/v8/
13101397
[`--heapsnapshot-near-heap-limit`]: cli.md#--heapsnapshot-near-heap-limitmax_count
13111398
[`AsyncLocalStorage`]: async_context.md#class-asynclocalstorage
13121399
[`Buffer`]: buffer.md
1400+
[`CollectStatistics()`]: https://v8docs.nodesource.com/node-22.4/d9/dc4/classv8_1_1_cpp_heap.html#a3a5d09567758e608fffde50eeabc2feb
13131401
[`DefaultDeserializer`]: #class-v8defaultdeserializer
13141402
[`DefaultSerializer`]: #class-v8defaultserializer
13151403
[`Deserializer`]: #class-v8deserializer
@@ -1323,6 +1411,8 @@ setTimeout(() => {
13231411
[`async_hooks`]: async_hooks.md
13241412
[`before` callback]: #beforepromise
13251413
[`buffer.constants.MAX_LENGTH`]: buffer.md#bufferconstantsmax_length
1414+
[`cppgc::HeapStatistics struct`]: https://v8docs.nodesource.com/node-22.4/df/d2f/structcppgc_1_1_heap_statistics.html
1415+
[`cppgc::HeapStatistics`]: https://v8docs.nodesource.com/node-22.4/d7/d51/heap-statistics_8h_source.html
13261416
[`deserializer._readHostObject()`]: #deserializer_readhostobject
13271417
[`deserializer.transferArrayBuffer()`]: #deserializertransferarraybufferid-arraybuffer
13281418
[`init` callback]: #initpromise-parent

lib/v8.js

+21-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@ const {
3737
} = primordials;
3838

3939
const { Buffer } = require('buffer');
40-
const { validateString, validateUint32 } = require('internal/validators');
40+
const {
41+
validateString,
42+
validateUint32,
43+
validateOneOf,
44+
} = require('internal/validators');
4145
const {
4246
Serializer,
4347
Deserializer,
@@ -145,6 +149,8 @@ const {
145149
heapStatisticsBuffer,
146150
heapCodeStatisticsBuffer,
147151
heapSpaceStatisticsBuffer,
152+
getCppHeapStatistics: _getCppHeapStatistics,
153+
detailLevel,
148154
} = binding;
149155

150156
const kNumberOfHeapSpaces = kHeapSpaces.length;
@@ -259,6 +265,19 @@ function setHeapSnapshotNearHeapLimit(limit) {
259265
_setHeapSnapshotNearHeapLimit(limit);
260266
}
261267

268+
const detailLevelDict = {
269+
__proto__: null,
270+
detailed: detailLevel.DETAILED,
271+
brief: detailLevel.BRIEF,
272+
};
273+
274+
function getCppHeapStatistics(type = 'detailed') {
275+
validateOneOf(type, 'type', ['brief', 'detailed']);
276+
const result = _getCppHeapStatistics(detailLevelDict[type]);
277+
result.detail_level = type;
278+
return result;
279+
}
280+
262281
/* V8 serialization API */
263282

264283
/* JS methods for the base objects */
@@ -430,6 +449,7 @@ module.exports = {
430449
getHeapStatistics,
431450
getHeapSpaceStatistics,
432451
getHeapCodeStatistics,
452+
getCppHeapStatistics,
433453
setFlagsFromString,
434454
Serializer,
435455
Deserializer,

0 commit comments

Comments
 (0)