@@ -40,7 +40,8 @@ import {
40
40
TimeProfileNode ,
41
41
} from './v8-types' ;
42
42
43
- export const NON_JS_THREADS_FUNCTION_NAME = '(non-JS threads)' ;
43
+ export const NON_JS_THREADS_FUNCTION_NAME = 'Non JS threads activity' ;
44
+ export const GARBAGE_COLLECTION_FUNCTION_NAME = 'Garbage Collection' ;
44
45
45
46
/**
46
47
* A stack of function IDs.
@@ -110,7 +111,6 @@ function serialize<T extends ProfileNode>(
110
111
if ( ignoreSamplesPath && node . scriptName . indexOf ( ignoreSamplesPath ) > - 1 ) {
111
112
continue ;
112
113
}
113
- if ( node . name === '(idle)' || node . name === '(program)' ) continue ;
114
114
const stack = entry . stack ;
115
115
const location = getLocation ( node , sourceMapper ) ;
116
116
stack . unshift ( location . id as number ) ;
@@ -262,6 +262,75 @@ function computeTotalHitCount(root: TimeProfileNode): number {
262
262
) ;
263
263
}
264
264
265
+ /** Perform some modifications on time profile:
266
+ * - Add non-JS thread activity node if available
267
+ * - Remove `(idle)` and `(program)` nodes
268
+ * - Convert `(garbage collector)` node to `Garbage Collection`
269
+ * - Put `non-JS thread activity` node and `Garbage Collection` under a top level `Node.js` node
270
+ * This function does not change the input profile.
271
+ */
272
+ function updateTimeProfile ( prof : TimeProfile ) : TimeProfile {
273
+ const newTopLevelChildren : TimeProfileNode [ ] = [ ] ;
274
+
275
+ let runtimeNode : TimeProfileNode | undefined ;
276
+
277
+ function getRuntimeNode ( ) : TimeProfileNode {
278
+ if ( ! runtimeNode ) {
279
+ runtimeNode = {
280
+ name : 'Node.js' ,
281
+ scriptName : '' ,
282
+ scriptId : 0 ,
283
+ lineNumber : 0 ,
284
+ columnNumber : 0 ,
285
+ children : [ ] ,
286
+ hitCount : 0 ,
287
+ } ;
288
+ newTopLevelChildren . push ( runtimeNode ) ;
289
+ }
290
+ return runtimeNode ;
291
+ }
292
+
293
+ for ( const child of prof . topDownRoot . children as TimeProfileNode [ ] ) {
294
+ if ( child . name === '(idle)' || child . name === '(program)' ) {
295
+ continue ;
296
+ }
297
+ if ( child . name === '(garbage collector)' ) {
298
+ // Create a new node to avoid modifying the input one
299
+ const newChild : TimeProfileNode = {
300
+ ...child ,
301
+ name : GARBAGE_COLLECTION_FUNCTION_NAME ,
302
+ } ;
303
+ getRuntimeNode ( ) . children . push ( newChild ) ;
304
+ } else {
305
+ newTopLevelChildren . push ( child ) ;
306
+ }
307
+ }
308
+
309
+ if ( prof . hasCpuTime && prof . nonJSThreadsCpuTime ) {
310
+ const node : TimeProfileNode = {
311
+ name : NON_JS_THREADS_FUNCTION_NAME ,
312
+ scriptName : '' ,
313
+ scriptId : 0 ,
314
+ lineNumber : 0 ,
315
+ columnNumber : 0 ,
316
+ children : [ ] ,
317
+ hitCount : 0 , // 0 because this should not be accounted for wall time
318
+ contexts : [
319
+ {
320
+ context : { } ,
321
+ timestamp : BigInt ( 0 ) ,
322
+ cpuTime : prof . nonJSThreadsCpuTime ,
323
+ } ,
324
+ ] ,
325
+ } ;
326
+ getRuntimeNode ( ) . children . push ( node ) ;
327
+ }
328
+ return {
329
+ ...prof ,
330
+ topDownRoot : { ...prof . topDownRoot , children : newTopLevelChildren } ,
331
+ } ;
332
+ }
333
+
265
334
/**
266
335
* Converts v8 time profile into into a profile proto.
267
336
* (https://github.com/google/pprof/blob/master/proto/profile.proto)
@@ -360,28 +429,11 @@ export function serializeTimeProfile(
360
429
period : intervalNanos ,
361
430
} ;
362
431
363
- if ( prof . hasCpuTime && prof . nonJSThreadsCpuTime ) {
364
- const node : TimeProfileNode = {
365
- name : NON_JS_THREADS_FUNCTION_NAME ,
366
- scriptName : '' ,
367
- scriptId : 0 ,
368
- lineNumber : 0 ,
369
- columnNumber : 0 ,
370
- children : [ ] ,
371
- hitCount : 0 , // 0 because this should not be accounted for wall time
372
- contexts : [
373
- {
374
- context : { } ,
375
- timestamp : BigInt ( 0 ) ,
376
- cpuTime : prof . nonJSThreadsCpuTime ,
377
- } ,
378
- ] ,
379
- } ;
380
- prof . topDownRoot . children . push ( node ) ;
381
- }
432
+ const updatedProf = updateTimeProfile ( prof ) ;
433
+
382
434
serialize (
383
435
profile ,
384
- prof . topDownRoot ,
436
+ updatedProf . topDownRoot ,
385
437
appendTimeEntryToSamples ,
386
438
stringTable ,
387
439
undefined ,
0 commit comments