Compare commits

..
2 Commits
Author SHA1 Message Date
Jamie Wong 519847b489 1.3.2 2018-12-03 19:25:54 -08:00
Jamie Wong 6d4f3499da Fix import of multithreaded Chrome profiles (#194)
In #160, I wrote code which incorrectly assumed that at most one profile would be active at a time. It turns out this assumption is incorrect because of webworkers! This PR introduces a fix which correctly separates samples taken on the main thread from samples taken on worker threads, and allows viewing both in speedscope.

Fixes #171
2018-12-03 19:21:59 -08:00
9 changed files with 3572 additions and 16 deletions
+6
View File
@@ -1,5 +1,11 @@
## Unreleased
## [1.3.2] - 2018-12-03
* Fixed import of multithreaded Chrome profiles [#19] (by @jlfwong)
### Fixed
## [1.3.1] - 2018-11-08
### Fixed
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "speedscope",
"version": "1.3.1",
"version": "1.3.2",
"description": "",
"repository": "jlfwong/speedscope",
"main": "index.js",
File diff suppressed because it is too large Load Diff
+28
View File
@@ -0,0 +1,28 @@
<script>
function banana() {
let prod = 1
for (let i = 1; i < 1000; i++) {
prod *= i
}
return prod
}
function apple() {
for (let i = 0; i < 1000; i++) {
banana()
}
}
let bounces = 0
const worker = new Worker('./worker.js')
worker.onmessage = function() {
apple()
if (bounces++ < 10) {
worker.postMessage('ping')
}
}
worker.postMessage('ping')
</script>
+18
View File
@@ -0,0 +1,18 @@
function gamma() {
let prod = 1
for (let i = 1; i < 1000; i++) {
prod *= i
}
return prod
}
function alpha() {
for (let i = 0; i < 1000; i++) {
gamma()
}
}
onmessage = function(e) {
alpha()
postMessage('pong')
}
@@ -515,6 +515,845 @@ exports[`importFromChromeTimeline Chrome 69: indexToView 1`] = `0`;
exports[`importFromChromeTimeline Chrome 69: profileGroup.name 1`] = `"simple.json"`;
exports[`importFromChromeTimeline Workers Chrome 70 1`] = `
Object {
"frames": Array [
Frame {
"col": 0,
"file": "extensions::SafeBuiltins",
"key": "(anonymous):extensions::SafeBuiltins:0:0",
"line": 0,
"name": "(anonymous)",
"selfWeight": 0,
"totalWeight": 37463,
},
Frame {
"col": 9,
"file": "extensions::SafeBuiltins",
"key": "(anonymous):extensions::SafeBuiltins:0:9",
"line": 0,
"name": "(anonymous)",
"selfWeight": 0,
"totalWeight": 37463,
},
Frame {
"col": 20,
"file": "extensions::SafeBuiltins",
"key": "saveBuiltin:extensions::SafeBuiltins:24:20",
"line": 24,
"name": "saveBuiltin",
"selfWeight": 233,
"totalWeight": 9858,
},
Frame {
"col": 21,
"file": "extensions::SafeBuiltins",
"key": "makeCallable:extensions::SafeBuiltins:6:21",
"line": 6,
"name": "makeCallable",
"selfWeight": 122,
"totalWeight": 7007,
},
Frame {
"col": 32,
"file": "extensions::SafeBuiltins",
"key": "(anonymous):extensions::SafeBuiltins:7:32",
"line": 7,
"name": "(anonymous)",
"selfWeight": 234,
"totalWeight": 234,
},
Frame {
"col": undefined,
"file": undefined,
"key": "(program):undefined:undefined:undefined",
"line": undefined,
"name": "(program)",
"selfWeight": 48725,
"totalWeight": 48827,
},
Frame {
"col": undefined,
"file": undefined,
"key": "(garbage collector):undefined:undefined:undefined",
"line": undefined,
"name": "(garbage collector)",
"selfWeight": 3380,
"totalWeight": 3380,
},
Frame {
"col": 0,
"file": "chrome-extension://aomjjhallfgjeglblehebfpbcfeobpgk/injected.min.js",
"key": "(anonymous):chrome-extension://aomjjhallfgjeglblehebfpbcfeobpgk/injected.min.js:0:0",
"line": 0,
"name": "(anonymous)",
"selfWeight": 1550,
"totalWeight": 15220,
},
Frame {
"col": 466,
"file": "chrome-extension://aomjjhallfgjeglblehebfpbcfeobpgk/injected.min.js",
"key": "La:chrome-extension://aomjjhallfgjeglblehebfpbcfeobpgk/injected.min.js:34:466",
"line": 34,
"name": "La",
"selfWeight": 407,
"totalWeight": 11272,
},
Frame {
"col": undefined,
"file": undefined,
"key": "get webstore:undefined:undefined:undefined",
"line": undefined,
"name": "get webstore",
"selfWeight": 287,
"totalWeight": 15564,
},
Frame {
"col": 9,
"file": "extensions::runtime",
"key": "(anonymous):extensions::runtime:0:9",
"line": 0,
"name": "(anonymous)",
"selfWeight": 2319,
"totalWeight": 15277,
},
Frame {
"col": undefined,
"file": undefined,
"key": "privates:undefined:undefined:undefined",
"line": undefined,
"name": "privates",
"selfWeight": 1751,
"totalWeight": 6636,
},
Frame {
"col": 9,
"file": "extensions::binding",
"key": "(anonymous):extensions::binding:0:9",
"line": 0,
"name": "(anonymous)",
"selfWeight": 791,
"totalWeight": 4994,
},
Frame {
"col": 9,
"file": "extensions::event_bindings",
"key": "(anonymous):extensions::event_bindings:0:9",
"line": 0,
"name": "(anonymous)",
"selfWeight": 822,
"totalWeight": 4068,
},
Frame {
"col": 9,
"file": "extensions::sendRequest",
"key": "(anonymous):extensions::sendRequest:0:9",
"line": 0,
"name": "(anonymous)",
"selfWeight": 761,
"totalWeight": 2844,
},
Frame {
"col": 9,
"file": "extensions::schemaUtils",
"key": "(anonymous):extensions::schemaUtils:0:9",
"line": 0,
"name": "(anonymous)",
"selfWeight": 847,
"totalWeight": 1814,
},
Frame {
"col": 9,
"file": "extensions::json_schema",
"key": "(anonymous):extensions::json_schema:0:9",
"line": 0,
"name": "(anonymous)",
"selfWeight": 834,
"totalWeight": 834,
},
Frame {
"col": 15,
"file": "extensions::utils",
"key": "expose:extensions::utils:97:15",
"line": 97,
"name": "expose",
"selfWeight": 147,
"totalWeight": 293,
},
Frame {
"col": 35,
"file": "extensions::SafeBuiltins",
"key": "target.(anonymous function):extensions::SafeBuiltins:9:35",
"line": 9,
"name": "target.(anonymous function)",
"selfWeight": 727,
"totalWeight": 7136,
},
Frame {
"col": undefined,
"file": undefined,
"key": "Apply:undefined:undefined:undefined",
"line": undefined,
"name": "Apply",
"selfWeight": 2187,
"totalWeight": 6547,
},
Frame {
"col": 9,
"file": "extensions::messaging",
"key": "(anonymous):extensions::messaging:0:9",
"line": 0,
"name": "(anonymous)",
"selfWeight": 151,
"totalWeight": 428,
},
Frame {
"col": 20,
"file": "extensions::binding",
"key": "generate:extensions::binding:198:20",
"line": 198,
"name": "generate",
"selfWeight": 149,
"totalWeight": 7002,
},
Frame {
"col": 36,
"file": "extensions::binding",
"key": "shouldCheckUnprivileged:extensions::binding:208:36",
"line": 208,
"name": "shouldCheckUnprivileged",
"selfWeight": 0,
"totalWeight": 146,
},
Frame {
"col": 43,
"file": "extensions::binding",
"key": "(anonymous):extensions::binding:252:43",
"line": 252,
"name": "(anonymous)",
"selfWeight": 0,
"totalWeight": 3651,
},
Frame {
"col": 49,
"file": "extensions::json_schema",
"key": "JSONSchemaValidator.addTypes:extensions::json_schema:173:49",
"line": 173,
"name": "JSONSchemaValidator.addTypes",
"selfWeight": 149,
"totalWeight": 149,
},
Frame {
"col": 45,
"file": "extensions::binding",
"key": "(anonymous):extensions::binding:270:45",
"line": 270,
"name": "(anonymous)",
"selfWeight": 546,
"totalWeight": 3349,
},
Frame {
"col": 47,
"file": "extensions::binding",
"key": "(anonymous):extensions::binding:322:47",
"line": 322,
"name": "(anonymous)",
"selfWeight": 159,
"totalWeight": 586,
},
Frame {
"col": 44,
"file": "extensions::binding",
"key": "(anonymous):extensions::binding:396:44",
"line": 396,
"name": "(anonymous)",
"selfWeight": 142,
"totalWeight": 802,
},
Frame {
"col": 16,
"file": "extensions::event_bindings",
"key": "Event:extensions::event_bindings:512:16",
"line": 512,
"name": "Event",
"selfWeight": 139,
"totalWeight": 527,
},
Frame {
"col": 51,
"file": "extensions::utils",
"key": "privates.constructPrivate:extensions::utils:101:51",
"line": 101,
"name": "privates.constructPrivate",
"selfWeight": 0,
"totalWeight": 388,
},
Frame {
"col": 20,
"file": "extensions::event_bindings",
"key": "EventImpl:extensions::event_bindings:212:20",
"line": 212,
"name": "EventImpl",
"selfWeight": 251,
"totalWeight": 251,
},
Frame {
"col": 26,
"file": "extensions::binding",
"key": "addProperties:extensions::binding:424:26",
"line": 424,
"name": "addProperties",
"selfWeight": 149,
"totalWeight": 710,
},
Frame {
"col": 16,
"file": "extensions::utils",
"key": "forEach:extensions::utils:26:16",
"line": 26,
"name": "forEach",
"selfWeight": 0,
"totalWeight": 561,
},
Frame {
"col": 21,
"file": "extensions::binding",
"key": "runHooks_:extensions::binding:179:21",
"line": 179,
"name": "runHooks_",
"selfWeight": 0,
"totalWeight": 273,
},
Frame {
"col": 46,
"file": "extensions::binding",
"key": "(anonymous):extensions::binding:180:46",
"line": 180,
"name": "(anonymous)",
"selfWeight": 141,
"totalWeight": 273,
},
Frame {
"col": 35,
"file": "extensions::runtime",
"key": "(anonymous):extensions::runtime:16:35",
"line": 16,
"name": "(anonymous)",
"selfWeight": 132,
"totalWeight": 132,
},
Frame {
"col": 260,
"file": "chrome-extension://aomjjhallfgjeglblehebfpbcfeobpgk/injected.min.js",
"key": "l:chrome-extension://aomjjhallfgjeglblehebfpbcfeobpgk/injected.min.js:37:260",
"line": 37,
"name": "l",
"selfWeight": 127,
"totalWeight": 127,
},
Frame {
"col": 43,
"file": "extensions::utils",
"key": "publicClassPrototype.(anonymous function):extensions::utils:135:43",
"line": 135,
"name": "publicClassPrototype.(anonymous function)",
"selfWeight": 0,
"totalWeight": 276,
},
Frame {
"col": 44,
"file": "extensions::event_bindings",
"key": "EventImpl.addListener:extensions::event_bindings:272:44",
"line": 272,
"name": "EventImpl.addListener",
"selfWeight": 135,
"totalWeight": 135,
},
Frame {
"col": 161,
"file": "chrome-extension://aomjjhallfgjeglblehebfpbcfeobpgk/injected.min.js",
"key": "bb:chrome-extension://aomjjhallfgjeglblehebfpbcfeobpgk/injected.min.js:57:161",
"line": 57,
"name": "bb",
"selfWeight": 146,
"totalWeight": 146,
},
Frame {
"col": 9,
"file": "chrome-extension://aomjjhallfgjeglblehebfpbcfeobpgk/injected.min.js",
"key": "(anonymous):chrome-extension://aomjjhallfgjeglblehebfpbcfeobpgk/injected.min.js:64:9",
"line": 64,
"name": "(anonymous)",
"selfWeight": 141,
"totalWeight": 1071,
},
Frame {
"col": 46,
"file": "extensions::SafeBuiltins",
"key": "(anonymous):extensions::SafeBuiltins:65:46",
"line": 65,
"name": "(anonymous)",
"selfWeight": 116,
"totalWeight": 27605,
},
Frame {
"col": 0,
"file": "chrome-extension://denbgaamihkadbghdceggmchnflmhpmk/contentScript.js",
"key": "(anonymous):chrome-extension://denbgaamihkadbghdceggmchnflmhpmk/contentScript.js:0:0",
"line": 0,
"name": "(anonymous)",
"selfWeight": 542,
"totalWeight": 6218,
},
Frame {
"col": 25,
"file": "chrome-extension://denbgaamihkadbghdceggmchnflmhpmk/contentScript.js",
"key": "insertTextScript:chrome-extension://denbgaamihkadbghdceggmchnflmhpmk/contentScript.js:30:25",
"line": 30,
"name": "insertTextScript",
"selfWeight": 392,
"totalWeight": 977,
},
Frame {
"col": 25,
"file": "chrome-extension://denbgaamihkadbghdceggmchnflmhpmk/contentScript.js",
"key": "insertHeaderNode:chrome-extension://denbgaamihkadbghdceggmchnflmhpmk/contentScript.js:57:25",
"line": 57,
"name": "insertHeaderNode",
"selfWeight": 292,
"totalWeight": 585,
},
Frame {
"col": undefined,
"file": undefined,
"key": "appendChild:undefined:undefined:undefined",
"line": undefined,
"name": "appendChild",
"selfWeight": 145,
"totalWeight": 293,
},
Frame {
"col": 0,
"file": undefined,
"key": "(anonymous):undefined:0:0",
"line": 0,
"name": "(anonymous)",
"selfWeight": 0,
"totalWeight": 148,
},
Frame {
"col": 13,
"file": undefined,
"key": "(anonymous):undefined:6:13",
"line": 6,
"name": "(anonymous)",
"selfWeight": 148,
"totalWeight": 148,
},
Frame {
"col": 25,
"file": "chrome-extension://denbgaamihkadbghdceggmchnflmhpmk/contentScript.js",
"key": "listenForMessage:chrome-extension://denbgaamihkadbghdceggmchnflmhpmk/contentScript.js:24:25",
"line": 24,
"name": "listenForMessage",
"selfWeight": 0,
"totalWeight": 4699,
},
Frame {
"col": 9,
"file": "extensions::uncaught_exception_handler",
"key": "(anonymous):extensions::uncaught_exception_handler:0:9",
"line": 0,
"name": "(anonymous)",
"selfWeight": 121,
"totalWeight": 121,
},
Frame {
"col": undefined,
"file": undefined,
"key": "(anonymous):undefined:undefined:undefined",
"line": undefined,
"name": "(anonymous)",
"selfWeight": 135,
"totalWeight": 135,
},
Frame {
"col": 8,
"file": "http://127.0.0.1:8081/worker.html",
"key": "(anonymous):http://127.0.0.1:8081/worker.html:0:8",
"line": 0,
"name": "(anonymous)",
"selfWeight": 0,
"totalWeight": 939,
},
Frame {
"col": undefined,
"file": undefined,
"key": "Worker:undefined:undefined:undefined",
"line": undefined,
"name": "Worker",
"selfWeight": 416,
"totalWeight": 939,
},
Frame {
"col": 11,
"file": "chrome-extension://aomjjhallfgjeglblehebfpbcfeobpgk/injected.min.js",
"key": "cb:chrome-extension://aomjjhallfgjeglblehebfpbcfeobpgk/injected.min.js:49:11",
"line": 49,
"name": "cb",
"selfWeight": 0,
"totalWeight": 359,
},
Frame {
"col": 314,
"file": "chrome-extension://aomjjhallfgjeglblehebfpbcfeobpgk/injected.min.js",
"key": "$a:chrome-extension://aomjjhallfgjeglblehebfpbcfeobpgk/injected.min.js:46:314",
"line": 46,
"name": "$a",
"selfWeight": 278,
"totalWeight": 359,
},
Frame {
"col": 51,
"file": "chrome-extension://aomjjhallfgjeglblehebfpbcfeobpgk/injected.min.js",
"key": "(anonymous):chrome-extension://aomjjhallfgjeglblehebfpbcfeobpgk/injected.min.js:50:51",
"line": 50,
"name": "(anonymous)",
"selfWeight": 0,
"totalWeight": 683,
},
Frame {
"col": undefined,
"file": undefined,
"key": "setTimeout:undefined:undefined:undefined",
"line": undefined,
"name": "setTimeout",
"selfWeight": 63,
"totalWeight": 704,
},
Frame {
"col": 144,
"file": "chrome-extension://aomjjhallfgjeglblehebfpbcfeobpgk/injected.min.js",
"key": "(anonymous):chrome-extension://aomjjhallfgjeglblehebfpbcfeobpgk/injected.min.js:50:144",
"line": 50,
"name": "(anonymous)",
"selfWeight": 117,
"totalWeight": 678,
},
Frame {
"col": 29,
"file": "http://127.0.0.1:8081/worker.html",
"key": "worker.onmessage:http://127.0.0.1:8081/worker.html:19:29",
"line": 19,
"name": "worker.onmessage",
"selfWeight": 0,
"totalWeight": 21103,
},
Frame {
"col": 16,
"file": "http://127.0.0.1:8081/worker.html",
"key": "apple:http://127.0.0.1:8081/worker.html:9:16",
"line": 9,
"name": "apple",
"selfWeight": 660,
"totalWeight": 20852,
},
Frame {
"col": 17,
"file": "http://127.0.0.1:8081/worker.html",
"key": "banana:http://127.0.0.1:8081/worker.html:1:17",
"line": 1,
"name": "banana",
"selfWeight": 18755,
"totalWeight": 20192,
},
Frame {
"col": undefined,
"file": undefined,
"key": "postMessage:undefined:undefined:undefined",
"line": undefined,
"name": "postMessage",
"selfWeight": 251,
"totalWeight": 251,
},
],
"name": "worker.json - CrRendererMain",
"stacks": Array [
" 15.06ms",
"(anonymous);(anonymous);saveBuiltin;makeCallable;(anonymous) 102.00µs",
"(anonymous);(anonymous);saveBuiltin 92.00µs",
"(anonymous);(anonymous);saveBuiltin;(program) 2.62ms",
" 312.00µs",
"(program) 295.00µs",
" 105.00µs",
"(program) 306.00µs",
" 111.00µs",
"(program) 109.00µs",
" 197.00µs",
"(program) 110.00µs",
"(program);(garbage collector) 102.00µs",
"(program) 1.25ms",
"(anonymous);(anonymous);saveBuiltin 141.00µs",
"(anonymous);(anonymous);saveBuiltin;makeCallable 122.00µs",
"(anonymous);(anonymous);saveBuiltin;makeCallable;(program) 6.65ms",
"(anonymous) 598.00µs",
"(anonymous);(garbage collector) 778.00µs",
"(anonymous) 660.00µs",
"(anonymous);La 407.00µs",
"(anonymous);La;get webstore 139.00µs",
"(anonymous);La;get webstore;(anonymous) 1.15ms",
"(anonymous);La;get webstore;(anonymous);privates 132.00µs",
"(anonymous);La;get webstore;(anonymous);privates;(anonymous) 791.00µs",
"(anonymous);La;get webstore;(anonymous);privates;(anonymous);privates 135.00µs",
"(anonymous);La;get webstore;(anonymous);privates;(anonymous);privates;(anonymous) 669.00µs",
"(anonymous);La;get webstore;(anonymous);privates;(anonymous);privates;(anonymous);privates;(anonymous) 375.00µs",
"(anonymous);La;get webstore;(anonymous);privates;(anonymous);privates;(anonymous);privates;(anonymous);privates 134.00µs",
"(anonymous);La;get webstore;(anonymous);privates;(anonymous);privates;(anonymous);privates;(anonymous) 256.00µs",
"(anonymous);La;get webstore;(anonymous);privates;(anonymous);privates;(anonymous);privates;(anonymous);privates 135.00µs",
"(anonymous);La;get webstore;(anonymous);privates;(anonymous);privates;(anonymous);privates;(anonymous);privates;(anonymous) 847.00µs",
"(anonymous);La;get webstore;(anonymous);privates;(anonymous);privates;(anonymous);privates;(anonymous);privates;(anonymous);privates 133.00µs",
"(anonymous);La;get webstore;(anonymous);privates;(anonymous);privates;(anonymous);privates;(anonymous);privates;(anonymous);privates;(anonymous) 580.00µs",
"(anonymous);La;get webstore;(anonymous);privates;(anonymous);privates;(anonymous) 153.00µs",
"(anonymous);La;get webstore;(anonymous);privates;(anonymous);privates;(anonymous);expose;target.(anonymous function);Apply 146.00µs",
"(anonymous);La;get webstore;(anonymous) 744.00µs",
"(anonymous);La;get webstore;(anonymous);privates;(anonymous) 151.00µs",
"(anonymous);La;get webstore;(anonymous);privates;(anonymous);expose 147.00µs",
"(anonymous);La;get webstore;(anonymous);privates 141.00µs",
"(anonymous);La;get webstore;(anonymous) 146.00µs",
"(anonymous);La;get webstore;(anonymous);privates 139.00µs",
"(anonymous);La;get webstore;(anonymous) 142.00µs",
"(anonymous);La;get webstore;(anonymous);generate;privates 120.00µs",
"(anonymous);La;get webstore;(anonymous);generate;shouldCheckUnprivileged;target.(anonymous function);Apply 146.00µs",
"(anonymous);La;get webstore;(anonymous);generate;target.(anonymous function);Apply 259.00µs",
"(anonymous);La;get webstore;(anonymous);generate;target.(anonymous function);Apply;(anonymous);JSONSchemaValidator.addTypes 149.00µs",
"(anonymous);La;get webstore;(anonymous);generate;target.(anonymous function);Apply;(anonymous);target.(anonymous function);Apply 153.00µs",
"(anonymous);La;get webstore;(anonymous);generate;target.(anonymous function);Apply;(anonymous);target.(anonymous function);Apply;(anonymous);target.(anonymous function);Apply 251.00µs",
"(anonymous);La;get webstore;(anonymous);generate;target.(anonymous function);Apply;(anonymous);target.(anonymous function);Apply;(anonymous);target.(anonymous function) 292.00µs",
"(anonymous);La;get webstore;(anonymous);generate;target.(anonymous function);Apply;(anonymous);target.(anonymous function);Apply;(anonymous) 295.00µs",
"(anonymous);La;get webstore;(anonymous);generate;target.(anonymous function);Apply 152.00µs",
"(anonymous);La;get webstore;(anonymous);generate;target.(anonymous function);Apply;(anonymous) 159.00µs",
"(anonymous);La;get webstore;(anonymous);generate;target.(anonymous function);Apply;(anonymous);privates 135.00µs",
"(anonymous);La;get webstore;(anonymous);generate;target.(anonymous function);Apply;(anonymous);privates 133.00µs",
"(anonymous);La;get webstore;(anonymous);generate;target.(anonymous function);Apply;(anonymous);Event 139.00µs",
"(anonymous);La;get webstore;(anonymous);generate;target.(anonymous function);Apply;(anonymous);Event;privates.constructPrivate;target.(anonymous function);Apply 137.00µs",
"(anonymous);La;get webstore;(anonymous);generate;target.(anonymous function);Apply;(anonymous);Event;privates.constructPrivate;target.(anonymous function);Apply;EventImpl 125.00µs",
"(anonymous);La;get webstore;(anonymous);generate;target.(anonymous function);Apply;(anonymous) 142.00µs",
"(anonymous);La;get webstore;(anonymous);generate;addProperties 149.00µs",
"(anonymous);La;get webstore;(anonymous);generate;addProperties;forEach;target.(anonymous function);Apply 126.00µs",
"(anonymous);La;get webstore;(anonymous);generate 149.00µs",
"(anonymous);La;get webstore;(anonymous);generate;runHooks_;target.(anonymous function);Apply;(anonymous) 141.00µs",
"(anonymous);La;get webstore;(anonymous);generate;runHooks_;target.(anonymous function);Apply;(anonymous);(anonymous) 132.00µs",
"(anonymous) 160.00µs",
"(anonymous);l 127.00µs",
"(anonymous) 132.00µs",
"(anonymous);publicClassPrototype.(anonymous function);target.(anonymous function);Apply 141.00µs",
"(anonymous);publicClassPrototype.(anonymous function);target.(anonymous function);Apply;EventImpl.addListener 135.00µs",
"(anonymous);bb 146.00µs",
"(anonymous);(anonymous) 141.00µs",
"(anonymous);(anonymous);(program) 930.00µs",
"(anonymous);(anonymous);saveBuiltin;makeCallable;(anonymous) 132.00µs",
"(anonymous);(anonymous);(anonymous) 116.00µs",
"(anonymous);(anonymous);(anonymous);(program) 27.49ms",
"(anonymous) 542.00µs",
"(anonymous);insertTextScript 392.00µs",
"(anonymous);insertTextScript;insertHeaderNode 292.00µs",
"(anonymous);insertTextScript;insertHeaderNode;appendChild;(anonymous);(anonymous) 148.00µs",
"(anonymous);insertTextScript;insertHeaderNode;appendChild 145.00µs",
"(anonymous);listenForMessage;get webstore 148.00µs",
"(anonymous);listenForMessage;get webstore;(anonymous);privates;(anonymous);privates;(anonymous);privates;(anonymous) 121.00µs",
"(anonymous);listenForMessage;get webstore;(anonymous);privates;(anonymous);privates;(anonymous);privates;(anonymous) 130.00µs",
"(anonymous);listenForMessage;get webstore;(anonymous);privates;(anonymous);privates;(anonymous);privates;(anonymous);privates;(anonymous);privates;(anonymous) 254.00µs",
"(anonymous);listenForMessage;get webstore;(anonymous);privates;(anonymous);privates;(anonymous);(anonymous) 135.00µs",
"(anonymous);listenForMessage;get webstore;(anonymous);privates 122.00µs",
"(anonymous);listenForMessage;get webstore;(anonymous);privates;(anonymous);target.(anonymous function);Apply 130.00µs",
"(anonymous);listenForMessage;get webstore;(anonymous) 141.00µs",
"(anonymous);listenForMessage;get webstore;(anonymous);generate;target.(anonymous function) 154.00µs",
"(anonymous);listenForMessage;get webstore;(anonymous);generate;target.(anonymous function);Apply;(anonymous);target.(anonymous function);Apply;(anonymous) 123.00µs",
"(anonymous);listenForMessage;get webstore;(anonymous);generate;target.(anonymous function);Apply;(anonymous);target.(anonymous function);Apply;(anonymous);target.(anonymous function) 137.00µs",
"(anonymous);listenForMessage;get webstore;(anonymous);generate;target.(anonymous function);Apply;(anonymous);target.(anonymous function);Apply;(anonymous);target.(anonymous function);Apply 257.00µs",
"(anonymous);listenForMessage;get webstore;(anonymous);generate;target.(anonymous function);Apply;(anonymous);target.(anonymous function);Apply;(anonymous);target.(anonymous function);Apply;(garbage collector) 1.58ms",
"(anonymous);listenForMessage;get webstore;(anonymous);generate;target.(anonymous function);Apply;(anonymous);target.(anonymous function);Apply;(anonymous) 128.00µs",
"(anonymous);listenForMessage;get webstore;(anonymous);generate;target.(anonymous function);Apply;(anonymous);target.(anonymous function);Apply;(anonymous);target.(anonymous function);Apply 289.00µs",
"(anonymous);listenForMessage;get webstore;(anonymous);generate;target.(anonymous function);Apply;(anonymous);privates 292.00µs",
"(anonymous);listenForMessage;get webstore;(anonymous);generate;target.(anonymous function);Apply;(anonymous);Event;privates.constructPrivate;target.(anonymous function);Apply;EventImpl 126.00µs",
"(anonymous);listenForMessage;get webstore;(anonymous);generate;addProperties;forEach;target.(anonymous function) 144.00µs",
"(anonymous);listenForMessage;get webstore;(anonymous);generate;addProperties;forEach;target.(anonymous function);(program) 291.00µs",
"(anonymous);Worker 416.00µs",
"(anonymous);Worker;(program) 523.00µs",
"cb;$a 278.00µs",
"cb;$a;(program) 81.00µs",
"(anonymous);setTimeout 42.00µs",
"(anonymous);setTimeout;(program) 641.00µs",
"(anonymous);setTimeout 21.00µs",
"(anonymous) 117.00µs",
"(anonymous);(program) 540.00µs",
" 511.00µs",
"(program) 125.00µs",
" 136.00µs",
"(program) 1.06ms",
" 133.00µs",
"(program) 1.46ms",
" 261.00µs",
"(program) 147.00µs",
" 4.74ms",
"(program) 145.00µs",
" 525.00µs",
"(program) 221.00µs",
" 325.00µs",
"(program) 399.00µs",
" 146.00µs",
"(program) 391.00µs",
" 4.01ms",
"(program) 131.00µs",
" 1.10ms",
"(program) 146.00µs",
" 2.91ms",
"(program) 280.00µs",
"worker.onmessage;apple;banana 420.00µs",
"worker.onmessage;apple 128.00µs",
"worker.onmessage;apple;banana 1.27ms",
"worker.onmessage;apple 146.00µs",
"worker.onmessage;apple;banana 1.06ms",
"worker.onmessage;apple 130.00µs",
"worker.onmessage;apple;banana 129.00µs",
"worker.onmessage;postMessage 143.00µs",
" 1.80ms",
"worker.onmessage;apple;banana 1.53ms",
"worker.onmessage;postMessage 108.00µs",
" 1.63ms",
"(program) 141.00µs",
"worker.onmessage;apple;banana 1.86ms",
" 1.75ms",
"worker.onmessage;apple;banana 1.67ms",
" 1.84ms",
"worker.onmessage;apple;banana 1.62ms",
"worker.onmessage;apple;banana;(program) 146.00µs",
" 1.67ms",
"worker.onmessage;apple;banana 1.45ms",
"worker.onmessage;apple;banana;(garbage collector) 923.00µs",
"worker.onmessage;apple;banana 136.00µs",
"worker.onmessage;apple;banana;(program) 132.00µs",
" 1.81ms",
"(program) 136.00µs",
"worker.onmessage;apple;banana 1.69ms",
" 1.75ms",
"(program) 131.00µs",
"worker.onmessage;apple;banana 282.00µs",
"worker.onmessage;apple 128.00µs",
"worker.onmessage;apple;banana 1.10ms",
"worker.onmessage;apple;banana;(program) 136.00µs",
" 1.57ms",
"worker.onmessage;apple;banana 665.00µs",
"worker.onmessage;apple 128.00µs",
"worker.onmessage;apple;banana 779.00µs",
" 1.56ms",
"(program) 131.00µs",
"worker.onmessage;apple;banana 1.56ms",
" 1.57ms",
"(program) 149.00µs",
"worker.onmessage;apple;banana 1.54ms",
"worker.onmessage;apple;banana;(program) 100.00µs",
" 52.45ms",
"(program) 125.00µs",
" 88.71ms",
"(program) 1.06ms",
],
}
`;
exports[`importFromChromeTimeline Workers Chrome 70 2`] = `
Object {
"frames": Array [
Frame {
"col": 20,
"file": "http://127.0.0.1:8081/worker.js",
"key": "onmessage:http://127.0.0.1:8081/worker.js:14:20",
"line": 14,
"name": "onmessage",
"selfWeight": 402,
"totalWeight": 187278,
},
Frame {
"col": 14,
"file": "http://127.0.0.1:8081/worker.js",
"key": "alpha:http://127.0.0.1:8081/worker.js:8:14",
"line": 8,
"name": "alpha",
"selfWeight": 7945,
"totalWeight": 177837,
},
Frame {
"col": 14,
"file": "http://127.0.0.1:8081/worker.js",
"key": "gamma:http://127.0.0.1:8081/worker.js:0:14",
"line": 0,
"name": "gamma",
"selfWeight": 13631,
"totalWeight": 21888,
},
Frame {
"col": undefined,
"file": undefined,
"key": "(program):undefined:undefined:undefined",
"line": undefined,
"name": "(program)",
"selfWeight": 164753,
"totalWeight": 164753,
},
Frame {
"col": undefined,
"file": undefined,
"key": "postMessage:undefined:undefined:undefined",
"line": undefined,
"name": "postMessage",
"selfWeight": 547,
"totalWeight": 5452,
},
],
"name": "worker.json - DedicatedWorker thread",
"stacks": Array [
" 4.33ms",
"onmessage;alpha;gamma 604.00µs",
"onmessage;alpha 1.38ms",
"onmessage;alpha;gamma 3.31ms",
"onmessage 270.00µs",
"onmessage;(program) 3.59ms",
"onmessage;alpha;gamma 127.00µs",
"onmessage;alpha 128.00µs",
"onmessage;alpha;gamma 1.48ms",
"onmessage;alpha;gamma;(program) 1.68ms",
"onmessage;alpha;gamma 1.65ms",
"onmessage;alpha;gamma;(program) 2.00ms",
"onmessage;alpha;gamma 1.62ms",
"onmessage;postMessage 146.00µs",
"onmessage;postMessage;(program) 1.65ms",
"onmessage;alpha;gamma 1.70ms",
"onmessage;postMessage 256.00µs",
"onmessage;postMessage;(program) 1.63ms",
"onmessage;alpha;gamma 670.00µs",
"onmessage;alpha 134.00µs",
"onmessage;alpha;gamma 899.00µs",
"onmessage;alpha;gamma;(program) 2.72ms",
"onmessage 132.00µs",
"onmessage;alpha;gamma 1.57ms",
"onmessage;alpha;gamma;(program) 1.85ms",
"onmessage;alpha 1.75ms",
"onmessage;alpha;(program) 1.76ms",
"onmessage;alpha 1.44ms",
"onmessage;postMessage 145.00µs",
"onmessage;postMessage;(program) 1.63ms",
"onmessage;alpha 1.57ms",
"onmessage;alpha;(program) 1.60ms",
"onmessage;alpha 1.55ms",
"onmessage;alpha;(program) 144.64ms",
],
}
`;
exports[`importFromChromeTimeline Workers Chrome 70: indexToView 1`] = `0`;
exports[`importFromChromeTimeline Workers Chrome 70: profileGroup.name 1`] = `"worker.json"`;
exports[`importFromChromeTimeline: indexToView 1`] = `0`;
exports[`importFromChromeTimeline: profileGroup.name 1`] = `"simple-timeline.json"`;
+4
View File
@@ -11,3 +11,7 @@ test('importFromChromeTimeline', async () => {
test('importFromChromeTimeline Chrome 69', async () => {
await checkProfileSnapshot('./sample/profiles/Chrome/69/simple.json')
})
test('importFromChromeTimeline Workers Chrome 70', async () => {
await checkProfileSnapshot('./sample/profiles/Chrome/70/worker.json')
})
+61 -13
View File
@@ -1,5 +1,5 @@
import {Profile, FrameInfo, CallTreeProfileBuilder} from '../lib/profile'
import {getOrInsert, lastOf, sortBy} from '../lib/utils'
import {Profile, FrameInfo, CallTreeProfileBuilder, ProfileGroup} from '../lib/profile'
import {getOrInsert, lastOf, sortBy, itForEach} from '../lib/utils'
import {TimeFormatter} from '../lib/value-formatters'
// See: https://github.com/v8/v8/blob/master/src/inspector/js_protocol.json
@@ -15,6 +15,7 @@ interface TimelineEvent {
tdur: number
tts: number
args: {[key: string]: any}
id?: string
}
interface PositionTickInfo {
@@ -61,33 +62,54 @@ export function isChromeTimeline(rawProfile: any): boolean {
return true
}
export function importFromChromeTimeline(events: TimelineEvent[]): Profile {
export function importFromChromeTimeline(events: TimelineEvent[], fileName: string): ProfileGroup {
// It seems like sometimes Chrome timeline files contain multiple CpuProfiles?
// For now, choose the first one in the list.
let cpuProfile: CPUProfile | null = null
const cpuProfileByID = new Map<string, CPUProfile>()
// Maps profile IDs (like "0x3") to pid/tid pairs formatted as `${pid}:${tid}`
const pidTidById = new Map<string, string>()
// Maps pid/tid pairs to thread names
const threadNameByPidTid = new Map<string, string>()
// The events aren't necessarily recorded in chronological order. Sort them so
// that they are.
sortBy(events, e => e.ts)
const DEFAULT_ID = '(default id)'
for (let event of events) {
if (event.name == 'CpuProfile') {
cpuProfile = event.args.data.cpuProfile as CPUProfile
if (event.name === 'CpuProfile') {
cpuProfileByID.set(event.id || DEFAULT_ID, event.args.data.cpuProfile as CPUProfile)
if (event.id) {
pidTidById.set(event.id, `${event.pid}:${event.tid}`)
}
}
if (event.name == 'Profile') {
cpuProfile = {
if (event.name === 'Profile') {
cpuProfileByID.set(event.id || DEFAULT_ID, {
startTime: 0,
endTime: 0,
nodes: [],
samples: [],
timeDeltas: [],
...event.args.data,
})
if (event.id) {
pidTidById.set(event.id, `${event.pid}:${event.tid}`)
}
}
if (event.name == 'ProfileChunk') {
if (event.name === 'thread_name') {
threadNameByPidTid.set(`${event.pid}:${event.tid}`, event.args.name)
}
if (event.name === 'ProfileChunk') {
const cpuProfile = cpuProfileByID.get(event.id || DEFAULT_ID)
if (cpuProfile) {
const chunk = event.args.data
if (chunk.cpuProfile) {
@@ -108,13 +130,38 @@ export function importFromChromeTimeline(events: TimelineEvent[]): Profile {
cpuProfile.endTime = chunk.endTime
}
} else {
console.log('Ignoring ProfileChunk when no Profile is active')
console.warn(
`Ignoring ProfileChunk for undeclared Profile with id ${event.id || DEFAULT_ID}`,
)
}
}
}
if (cpuProfile) {
return importFromChromeCPUProfile(cpuProfile as CPUProfile)
if (cpuProfileByID.size > 0) {
const profiles: Profile[] = []
let indexToView = 0
itForEach(cpuProfileByID.keys(), profileId => {
let threadName: string | null = null
let pidTid = pidTidById.get(profileId)
if (pidTid) {
threadName = threadNameByPidTid.get(pidTid) || null
if (threadName) {
}
}
const profile = importFromChromeCPUProfile(cpuProfileByID.get(profileId)!)
if (threadName && cpuProfileByID.size > 1) {
profile.setName(`${fileName} - ${threadName}`)
if (threadName === 'CrRendererMain') {
indexToView = profiles.length
}
} else {
profile.setName(`${fileName}`)
}
profiles.push(profile)
})
return {name: fileName, indexToView, profiles}
} else {
throw new Error('Could not find CPU profile in Timeline')
}
@@ -198,7 +245,8 @@ export function importFromChromeCPUProfile(chromeProfile: CPUProfile): Profile {
} else {
let timeDelta = chromeProfile.timeDeltas[i + 1]
if (timeDelta < 0) {
console.warn('Substituting zero for unexpected time delta:', timeDelta, 'at index', i)
// This is super noisy, but can be helpful when debugging strange data
// console.warn('Substituting zero for unexpected time delta:', timeDelta, 'at index', i)
timeDelta = 0
}
+2 -2
View File
@@ -89,7 +89,7 @@ async function _importProfileGroup(dataSource: ProfileDataSource): Promise<Profi
return toGroup(importFromChromeCPUProfile(JSON.parse(contents)))
} else if (fileName.endsWith('.chrome.json') || /Profile-\d{8}T\d{6}/.exec(fileName)) {
console.log('Importing as Chrome Timeline')
return toGroup(importFromChromeTimeline(JSON.parse(contents)))
return importFromChromeTimeline(JSON.parse(contents), fileName)
} else if (fileName.endsWith('.stackprof.json')) {
console.log('Importing as stackprof profile')
return toGroup(importFromStackprof(JSON.parse(contents)))
@@ -124,7 +124,7 @@ async function _importProfileGroup(dataSource: ProfileDataSource): Promise<Profi
return toGroup(importFromFirefox(parsed))
} else if (isChromeTimeline(parsed)) {
console.log('Importing as Chrome CPU Profile')
return toGroup(importFromChromeTimeline(parsed))
return importFromChromeTimeline(parsed, fileName)
} else if ('nodes' in parsed && 'samples' in parsed && 'timeDeltas' in parsed) {
console.log('Importing as Chrome Timeline')
return toGroup(importFromChromeCPUProfile(parsed))