@@ -1603,9 +1603,85 @@ added:
16031603 - v24.12.0
16041604-->
16051605
1606- * Returns: {string}
1606+ * Returns: {string|undefined }
16071607
1608- Stopping collecting the profile and return the profile data.
1608+ Stop collecting the profile and return the profile data as a JSON-encoded
1609+ string. Calling ` stop ()` after the handle has already been stopped returns
1610+ ` undefined ` .
1611+
1612+ ### ` syncCpuProfileHandle .stopAndCapture ()`
1613+
1614+ <!-- YAML
1615+ added: REPLACEME
1616+ -->
1617+
1618+ * Returns: {Object|undefined}
1619+
1620+ Stop collecting the profile and return a structured profile object instead
1621+ of a JSON string. Calling ` stopAndCapture ()` after the handle has already
1622+ been stopped returns ` undefined ` .
1623+
1624+ The returned object has shape:
1625+
1626+ * ` startTime` {number} Microseconds since V8's clock origin.
1627+ * ` endTime` {number} Microseconds since V8's clock origin.
1628+ * ` droppedContexts` {number} Number of samples for which a context could not
1629+ be recorded because the per-session context buffer was full. Always ` 0 `
1630+ when the profile was started without ` withContext` .
1631+ * ` topDownRoot` {Object} Root of the recursive call tree:
1632+ * ` functionName` {string}
1633+ * ` scriptName` {string}
1634+ * ` lineNumber` {number}
1635+ * ` columnNumber` {number}
1636+ * ` hitCount` {number} Number of samples that landed at this node.
1637+ * ` contexts` {Array} Optional. Present only when at least one sample at
1638+ this node carried a context. Each element is ` { context, timestamp }` .
1639+ * ` children` {Array} Child nodes (same shape).
1640+
1641+ ### ` syncCpuProfileHandle .snapshot ()`
1642+
1643+ <!-- YAML
1644+ added: REPLACEME
1645+ -->
1646+
1647+ * Returns: {Object}
1648+
1649+ Capture a profile of samples taken since the last ` start` or ` snapshot`
1650+ call, and continue sampling with a fresh internal session. Returns the
1651+ same shape as [` stopAndCapture ()` ][]. Useful for continuous profiling: emit
1652+ a snapshot every minute without losing samples between sessions. Throws
1653+ ` ERR_INVALID_STATE ` if the handle has already been stopped.
1654+
1655+ ### ` syncCpuProfileHandle .runWithContext (value, fn[, ... args])`
1656+
1657+ <!-- YAML
1658+ added: REPLACEME
1659+ -->
1660+
1661+ * ` value` {any} Arbitrary JavaScript value to associate with samples
1662+ captured during the execution of ` fn` .
1663+ * ` fn` {Function} Function to invoke.
1664+ * ` ... args` {any} Arguments forwarded to ` fn` .
1665+ * Returns: {any} The return value of ` fn (... args)` .
1666+
1667+ Run ` fn (... args)` with ` value` recorded as the context for any samples
1668+ captured during its synchronous execution and across awaited continuations
1669+ that propagate the context (via {AsyncLocalStorage}). Throws if the profile
1670+ was started without ` withContext: true ` .
1671+
1672+ ### ` syncCpuProfileHandle .enterWithContext (value)`
1673+
1674+ <!-- YAML
1675+ added: REPLACEME
1676+ -->
1677+
1678+ * ` value` {any} Arbitrary JavaScript value to associate with subsequent
1679+ samples in the current asynchronous scope.
1680+
1681+ Set ` value` as the current sample context for the rest of the active
1682+ {AsyncLocalStorage} scope. Mirrors the naming of
1683+ [` asyncLocalStorage .enterWith ()` ][]. Throws if the profile was started
1684+ without ` withContext: true ` .
16091685
16101686### ` syncCpuProfileHandle[Symbol .dispose ]()`
16111687
@@ -1615,7 +1691,8 @@ added:
16151691 - v24.12.0
16161692-->
16171693
1618- Stopping collecting the profile and the profile will be discarded.
1694+ Stops collecting the profile (equivalent to ` stop ()` ); the profile is
1695+ discarded.
16191696
16201697## Class: ` SyncHeapProfileHandle`
16211698
@@ -1783,6 +1860,19 @@ added:
17831860 * ` sampleInterval` {number} Requested sampling interval in milliseconds. **Default:** ` 0 ` .
17841861 * ` maxBufferSize` {integer} Maximum number of samples to keep before older
17851862 entries are discarded. **Default:** ` 4294967295 ` .
1863+ * ` withContext` {boolean} If ` true ` , the returned handle exposes
1864+ [` runWithContext ()` ][] and [` enterWithContext ()` ][] for associating
1865+ arbitrary JavaScript values with samples captured during their execution
1866+ scope. The values are surfaced on each sample of the structured profile
1867+ returned by [` stopAndCapture ()` ][] or [` snapshot ()` ][]. When ` false `
1868+ (default), no per-sample context tracking is performed and there is no
1869+ extractor overhead. **Default:** ` false ` .
1870+ * ` contextBufferSize` {integer} Maximum number of samples that can carry a
1871+ context value during a single profile session. Once exceeded, further
1872+ samples are recorded with no associated context and the
1873+ ` droppedContexts` counter on the result is incremented. Only meaningful
1874+ when ` withContext` is ` true ` . **Default:** ` 60000 ` (sufficient for 60
1875+ seconds of sampling at the default 10 ms interval).
17861876* Returns: {SyncCPUProfileHandle}
17871877
17881878Starting a CPU profile then return a ` SyncCPUProfileHandle` object.
@@ -1794,6 +1884,21 @@ const profile = handle.stop();
17941884console .log (profile);
17951885` ` `
17961886
1887+ The returned handle can also produce a structured object tree instead of the
1888+ JSON string, and can carry a per-sample JavaScript context that propagates
1889+ across asynchronous boundaries via {AsyncLocalStorage}:
1890+
1891+ ` ` ` cjs
1892+ const handle = v8 .startCpuProfile ({ withContext: true });
1893+ handle .runWithContext ({ requestId: 42 }, () => {
1894+ // Synchronous and propagated-async work here is sampled with
1895+ // { requestId: 42 } associated with each sample.
1896+ });
1897+ const profile = handle .stopAndCapture ();
1898+ // profile.topDownRoot is a recursive tree; each node may carry
1899+ // `contexts: [{ context, timestamp }, ...]`.
1900+ ` ` `
1901+
17971902## ` v8 .startHeapProfile ([options])`
17981903
17991904<!-- YAML
@@ -1879,13 +1984,16 @@ console.log(profile);
18791984[` Serializer` ]: #class-v8serializer
18801985[` after` callback]: #afterpromise
18811986[` async_hooks` ]: async_hooks.md
1987+ [` asyncLocalStorage .enterWith ()` ]: async_context.md#asynclocalstorageenterwithstore
18821988[` before` callback]: #beforepromise
18831989[` buffer .constants .MAX_LENGTH ` ]: buffer.md#bufferconstantsmax_length
18841990[` cppgc:: HeapStatistics struct` ]: https://v8docs.nodesource.com/node-22.4/df/d2f/structcppgc_1_1_heap_statistics.html
18851991[` cppgc:: HeapStatistics` ]: https://v8docs.nodesource.com/node-22.4/d7/d51/heap-statistics_8h_source.html
18861992[` deserializer ._readHostObject ()` ]: #deserializer_readhostobject
18871993[` deserializer .transferArrayBuffer ()` ]: #deserializertransferarraybufferid-arraybuffer
1994+ [` enterWithContext ()` ]: #synccpuprofilehandleenterwithcontextvalue
18881995[` init` callback]: #initpromise-parent
1996+ [` runWithContext ()` ]: #synccpuprofilehandlerunwithcontextvalue-fn-args
18891997[` queryObjects ()` console API]: https://developer.chrome.com/docs/devtools/console/utilities#queryObjects-function
18901998[` serialize ()` ]: #v8serializevalue
18911999[` serializer ._getSharedArrayBufferId ()` ]: #serializer_getsharedarraybufferidsharedarraybuffer
@@ -1894,6 +2002,8 @@ console.log(profile);
18942002[` serializer .transferArrayBuffer ()` ]: #serializertransferarraybufferid-arraybuffer
18952003[` serializer .writeRawBytes ()` ]: #serializerwriterawbytesbuffer
18962004[` settled` callback]: #settledpromise
2005+ [` snapshot ()` ]: #synccpuprofilehandlesnapshot
2006+ [` stopAndCapture ()` ]: #synccpuprofilehandlestopandcapture
18972007[` v8 .stopCoverage ()` ]: #v8stopcoverage
18982008[` v8 .takeCoverage ()` ]: #v8takecoverage
18992009[` vm .Script ` ]: vm.md#new-vmscriptcode-options
0 commit comments