Skip to content

Commit bee4733

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

File tree

4 files changed

+435
-1
lines changed

4 files changed

+435
-1
lines changed

doc/api/v8.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,89 @@ 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
278+
[`CollectStatistics()`][] function which may change from one V8 version to the
279+
next.
280+
281+
* `detailLevel` (`'brief'`|`'detailed`): Specifies the level of detail in the
282+
returned statistics.
283+
* `brief`: Brief statistics contain only the top-level allocated and used
284+
memory statistics for the entire heap.
285+
* `detailed`: Detailed statistics also contain a break down per space and
286+
page, as well as freelist statistics and object type histograms.
287+
288+
It returns an object with a structure similar to the
289+
[`cppgc::HeapStatistics`][] object. You can learn more about the properties of the object in
290+
the [V8 documentation][`cppgc::HeapStatistics struct`].
291+
292+
```js
293+
// Detailed
294+
({
295+
committed_size_bytes: 131072,
296+
resident_size_bytes: 131072,
297+
used_size_bytes: 152,
298+
space_statistics: [
299+
{
300+
name: 'NormalPageSpace0',
301+
committed_size_bytes: 0,
302+
resident_size_bytes: 0,
303+
used_size_bytes: 0,
304+
page_stats: [{}],
305+
free_list_stats: {},
306+
},
307+
{
308+
name: 'NormalPageSpace1',
309+
committed_size_bytes: 131072,
310+
resident_size_bytes: 131072,
311+
used_size_bytes: 152,
312+
page_stats: [{}],
313+
free_list_stats: {},
314+
},
315+
{
316+
name: 'NormalPageSpace2',
317+
committed_size_bytes: 0,
318+
resident_size_bytes: 0,
319+
used_size_bytes: 0,
320+
page_stats: [{}],
321+
free_list_stats: {},
322+
},
323+
{
324+
name: 'NormalPageSpace3',
325+
committed_size_bytes: 0,
326+
resident_size_bytes: 0,
327+
used_size_bytes: 0,
328+
page_stats: [{}],
329+
free_list_stats: {},
330+
},
331+
{
332+
name: 'LargePageSpace',
333+
committed_size_bytes: 0,
334+
resident_size_bytes: 0,
335+
used_size_bytes: 0,
336+
page_stats: [{}],
337+
free_list_stats: {},
338+
},
339+
],
340+
type_names: [],
341+
detail_level: 'detailed',
342+
});
343+
```
344+
345+
```js
346+
// Brief
347+
({
348+
committed_size_bytes: 131072,
349+
resident_size_bytes: 131072,
350+
used_size_bytes: 128864,
351+
space_statistics: [],
352+
type_names: [],
353+
detail_level: 'brief',
354+
});
355+
```
356+
274357
## `v8.queryObjects(ctor[, options])`
275358

276359
<!-- YAML
@@ -1304,12 +1387,14 @@ setTimeout(() => {
13041387
}, 1000);
13051388
```
13061389

1390+
[CppHeap]: https://v8docs.nodesource.com/node-22.4/d9/dc4/classv8_1_1_cpp_heap.html
13071391
[HTML structured clone algorithm]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
13081392
[Hook Callbacks]: #hook-callbacks
13091393
[V8]: https://developers.google.com/v8/
13101394
[`--heapsnapshot-near-heap-limit`]: cli.md#--heapsnapshot-near-heap-limitmax_count
13111395
[`AsyncLocalStorage`]: async_context.md#class-asynclocalstorage
13121396
[`Buffer`]: buffer.md
1397+
[`CollectStatistics()`]: https://v8docs.nodesource.com/node-22.4/d9/dc4/classv8_1_1_cpp_heap.html#a3a5d09567758e608fffde50eeabc2feb
13131398
[`DefaultDeserializer`]: #class-v8defaultdeserializer
13141399
[`DefaultSerializer`]: #class-v8defaultserializer
13151400
[`Deserializer`]: #class-v8deserializer
@@ -1323,6 +1408,8 @@ setTimeout(() => {
13231408
[`async_hooks`]: async_hooks.md
13241409
[`before` callback]: #beforepromise
13251410
[`buffer.constants.MAX_LENGTH`]: buffer.md#bufferconstantsmax_length
1411+
[`cppgc::HeapStatistics struct`]: https://v8docs.nodesource.com/node-22.4/df/d2f/structcppgc_1_1_heap_statistics.html
1412+
[`cppgc::HeapStatistics`]: https://v8docs.nodesource.com/node-22.4/d7/d51/heap-statistics_8h_source.html
13261413
[`deserializer._readHostObject()`]: #deserializer_readhostobject
13271414
[`deserializer.transferArrayBuffer()`]: #deserializertransferarraybufferid-arraybuffer
13281415
[`init` callback]: #initpromise-parent

lib/v8.js

Lines changed: 21 additions & 1 deletion
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)