Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81a6f29ad1 | ||
|
|
263f7d513e | ||
|
|
1bce806933 | ||
|
|
6493c5f66f | ||
|
|
639dae322b | ||
|
|
33a8f3f313 | ||
|
|
7ae545a6c3 | ||
|
|
48d692c2a3 | ||
|
|
ca8fcb48cc | ||
|
|
63f3bc0395 | ||
|
|
1ac88cc09a | ||
|
|
9a2c2a270b | ||
|
|
229d48eca5 | ||
|
|
103db681d2 | ||
|
|
21167e69d8 | ||
|
|
e37f6fa7c3 | ||
|
|
6d02bf510f | ||
|
|
b71cef5db4 | ||
|
|
e6351a3c22 | ||
|
|
36aebfbda6 | ||
|
|
246fc3dd5d | ||
|
|
d6f5efa06c | ||
|
|
03a5104317 | ||
|
|
7dcfab1bbc | ||
|
|
24b60dfd4a | ||
|
|
6a979bb568 | ||
|
|
36911599cb | ||
|
|
b32ff08ca3 | ||
|
|
361bdc9cd2 | ||
|
|
a1384b03be | ||
|
|
5f32640060 | ||
|
|
a10c834f99 | ||
|
|
de3ab89eb5 | ||
|
|
aee2dfdf89 | ||
|
|
d9b3950274 | ||
|
|
177696e359 | ||
|
|
16e32dc08e | ||
|
|
8a4f38a8cb | ||
|
|
9361a6baf2 | ||
|
|
ede9c74d50 | ||
|
|
f758130455 | ||
|
|
f3a1c09c9b | ||
|
|
069c0194a6 | ||
|
|
64fe369c42 | ||
|
|
f55c53f699 | ||
|
|
a0b3fe8420 | ||
|
|
9452aeae82 | ||
|
|
b26cdb5be4 | ||
|
|
1c5bdba36e | ||
|
|
c3b35d7b0f | ||
|
|
dfaefe54fd | ||
|
|
7514f4c0c9 | ||
|
|
ff447c2719 | ||
|
|
668bb032ba | ||
|
|
9ed1eb192c | ||
|
|
8620432cbc | ||
|
|
dead3f9ad9 | ||
|
|
80b747a55e | ||
|
|
351994972d | ||
|
|
ca1abfdd32 | ||
|
|
dee9e5ade4 | ||
|
|
2077a905a9 | ||
|
|
e969178e65 | ||
|
|
56f6459af9 | ||
|
|
3f79e0fe96 | ||
|
|
d30bb2ef7e | ||
|
|
fd4195da10 | ||
|
|
707462e9cf | ||
|
|
375040e892 | ||
|
|
5ae9abcf1d | ||
|
|
bdd9301c59 | ||
|
|
cc9750923a | ||
|
|
c3074b7343 | ||
|
|
b15a08b3ff | ||
|
|
68683aa054 | ||
|
|
eb0e1ce731 | ||
|
|
bd546ca893 | ||
|
|
0c1e477f35 | ||
|
|
30ca6291ca | ||
|
|
66a9e5d1cf | ||
|
|
a2022a07a2 | ||
|
|
b7806a1c5f | ||
|
|
7f19a13012 | ||
|
|
abd74be9fa | ||
|
|
c706bdfe04 | ||
|
|
cfc8fe8f6e |
+11
-4
@@ -1,13 +1,20 @@
|
||||
module.exports = {
|
||||
parser: 'typescript-eslint-parser',
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
},
|
||||
plugins: ['prettier'],
|
||||
plugins: ['prettier', '@typescript-eslint', 'react-hooks'],
|
||||
rules: {
|
||||
'prettier/prettier': 'error',
|
||||
'@typescript-eslint/explicit-function-return-type': 'off',
|
||||
'react-hooks/rules-of-hooks': 'error',
|
||||
'react-hooks/exhaustive-deps': [
|
||||
'error',
|
||||
{
|
||||
additionalHooks: '(useSelector|useAppSelector|useActionCreator)',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
name: Node.js CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [10.x, 12.x, 14.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: npm install
|
||||
- run: npm test
|
||||
env:
|
||||
CI: true
|
||||
|
||||
- name: Coveralls Parallel
|
||||
uses: coverallsapp/github-action@master
|
||||
with:
|
||||
github-token: ${{ secrets.github_token }}
|
||||
flag-name: run-${{ matrix.node-version }}
|
||||
parallel: true
|
||||
|
||||
finish:
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Coveralls Finished
|
||||
uses: coverallsapp/github-action@master
|
||||
with:
|
||||
github-token: ${{ secrets.github_token }}
|
||||
parallel-finished: true
|
||||
+2
-1
@@ -2,4 +2,5 @@ node_modules
|
||||
.cache
|
||||
dist
|
||||
.idea
|
||||
coverage
|
||||
coverage
|
||||
.vscode
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- '9'
|
||||
Vendored
-3
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"editor.formatOnSave": true,
|
||||
}
|
||||
+175
-34
@@ -1,133 +1,274 @@
|
||||
## Unreleased
|
||||
## [1.15.0] - 2022-10-22
|
||||
|
||||
### Fixed
|
||||
|
||||
- Replace fuzzy matching with exact substring matching for finding matching frames [[#407](https://github.com/jlfwong/speedscope/pull/407)]
|
||||
|
||||
## [1.14.0] - 2022-05-19
|
||||
|
||||
### Added
|
||||
|
||||
- File and line information is now displayed in hover tips [[#365](https://github.com/jlfwong/speedscope/pull/365)] (by [@sokra](https://github.com/sokra))
|
||||
- Support for stackprof object mode [[#391](https://github.com/jlfwong/speedscope/pull/391)] (by [@alexcoco](https://github.com/alexcoco))
|
||||
- Support for hash params to control view-mode [[#362](https://github.com/jlfwong/speedscope/pull/362)] (by [@djudd](https://github.com/djudd))
|
||||
- Support for profiles over 512MB now works [[#385](https://github.com/jlfwong/speedscope/pull/385)] (by [@jlfwong](https://github.com/jlfwong))
|
||||
- Support for relative URLs in profileURL hashParam [[#357](https://github.com/jlfwong/speedscope/pull/357)] (by [@danvk](https://github.com/danvk))
|
||||
|
||||
### Fixed
|
||||
|
||||
- Allow collapsed stacks with invalid lines for the Brenden Gregg stack format [[#336](https://github.com/jlfwong/speedscope/pull/336)] (by [@P403n1x87](https://github.com/P403n1x87))
|
||||
- Allow pasting into the search box [[#338](https://github.com/jlfwong/speedscope/pull/338)] (by [@P403n1x87](https://github.com/P403n1x87))
|
||||
- Prevent hover tips from getting unnecessarily clipped outside container bounds [[#395](https://github.com/jlfwong/speedscope/pull/395)] (by [@jlfwong](https://github.com/jlfwong))
|
||||
|
||||
## [1.13.0] - 2021-02-14
|
||||
|
||||
### Added
|
||||
|
||||
- Support for importing callgrind profiles [[#331](https://github.com/jlfwong/speedscope/pull/331)]
|
||||
|
||||
## [1.12.1] - 2020-11-12
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed for retina displays [[#327](https://github.com/jlfwong/speedscope/issues/327)]
|
||||
|
||||
## [1.12.0] - 2020-11-12
|
||||
|
||||
### Added
|
||||
|
||||
- Dark mode! [[#323](https://github.com/jlfwong/speedscope/pull/323)]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed incorrect highlighting when search result overlaps "…" [[#326](https://github.com/jlfwong/speedscope/pull/326)]
|
||||
|
||||
## [1.11.1] - 2020-10-25
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix trace-event import for many cases where there are 'ts' collisions [[#322](https://github.com/jlfwong/speedscope/pull/322)]
|
||||
- Fix import of trace event files where B/E events' args don't match [[#321](https://github.com/jlfwong/speedscope/pull/321)]
|
||||
|
||||
## [1.11.0] - 2020-10-13
|
||||
|
||||
### Added
|
||||
|
||||
- Support remapping profiles using source maps [[#317](https://github.com/jlfwong/speedscope/pull/317)]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix line & column numbers in imports from Chrome & Firefox [[#318](https://github.com/jlfwong/speedscope/pull/318)]
|
||||
|
||||
## [1.10.0] - 2020-09-29
|
||||
|
||||
### Added
|
||||
|
||||
- Support for importing profiles from Safari [[#300](https://github.com/jlfwong/speedscope/pull/300)] (by [@radex](https://github.com/radex))
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed browser not opening on Windows when using the CLI [[#307](https://github.com/jlfwong/speedscope/pull/307)] (by [@spillerrec](https://github.com/spillerrec))
|
||||
- Fixed import of UTF-16 encoded files w/ BOM [[#314](https://github.com/jlfwong/speedscope/pull/314)]
|
||||
- Removed accidental dependency on React [[#315](https://github.com/jlfwong/speedscope/pull/315)]
|
||||
|
||||
## [1.9.0] - 2020-08-05
|
||||
|
||||
### Added
|
||||
|
||||
- Provide prev/next buttons to cycle through search results, make search results more visually prominen [[#304](https://github.com/jlfwong/speedscope/pull/304)]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix accumulated errors in Chrome profile imports caused by zeroed negative timeDeltas [[#305](https://github.com/jlfwong/speedscope/pull/305)] (by [@taneliang](https://github.com/taneliang))
|
||||
|
||||
## [1.8.0] - 2020-07-19
|
||||
|
||||
### Added
|
||||
|
||||
- Added search highlighting in time order & left heavy views [[#297](https://github.com/jlfwong/speedscope/pull/297)]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix performance issues for the caller/callee flamegraphs in the sandwich view [[#296](https://github.com/jlfwong/speedscope/pull/296)]
|
||||
|
||||
## [1.7.0] - 2020-07-13
|
||||
|
||||
### Added
|
||||
|
||||
- Introduced filtering via Ctrl+F/Cmd+F into the sandwich view [[#293](https://github.com/jlfwong/speedscope/pull/293)]
|
||||
|
||||
## [1.6.0] - 2020-05-30
|
||||
|
||||
### Added
|
||||
|
||||
- Improved profile/thread selection UI [[#282](https://github.com/jlfwong/speedscope/pull/282)]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Crash instead of incorrectly interpreting profiles with incorrectly ordered events [[#273](https://github.com/jlfwong/speedscope/pull/273)]
|
||||
- A large refactor to upgrade to Preact X was performed [[#267](https://github.com/jlfwong/speedscope/pull/267)]
|
||||
|
||||
## [1.5.3] - 2020-01-16
|
||||
|
||||
### Fixed
|
||||
|
||||
- Bump dependency versions to unbreak build [[#253](https://github.com/jlfwong/speedscope/pull/253)] (by [@jlfwong](https://github.com/jlfwong), with changes from [@Archerlly](https://github.com/Archerlly)'s [#215](https://github.com/jlfwong/speedscope/pull/215))
|
||||
- Trace event: Prevent event re-ordering from generating incorrect flamegraphs ([#252](https://github.com/jlfwong/speedscope/pull/252), with changes from [@hwajaywang](https://github.com/hwajaywang)'s [#249](https://github.com/jlfwong/speedscope/pull/249))
|
||||
- Make tooltip width wider [[#239](https://github.com/jlfwong/speedscope/pull/239)] (by [@miso11](https://github.com/miso11))
|
||||
|
||||
## [1.5.2] - 2019-10-10
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix emscripten remapping when symbols are hex-escaped, like `a\20b` [[#233](https://github.com/jlfwong/speedscope/pull/233)] (by [@jyc](https://github.com/jyc))
|
||||
|
||||
## [1.5.1] - 2019-06-06
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed import of trace event files which contain unmatched "E" events ([#222](https://github.com/jlfwong/speedscope/pull/222)) (by [@jlfwong](https://github.com/jlfwong))
|
||||
|
||||
## [1.5.0] - 2019-02-17
|
||||
|
||||
### Added
|
||||
|
||||
- Support importing unterminated JSON in simple cases ([#208](https://github.com/jlfwong/speedscope/pull/208)) (by [@jlfwong](https://github.com/jlfwong))
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix crash when importing from stackprof without raw_timestamp_deltas ([#207](https://github.com/jlfwong/speedscope/pull/207)) (by [@jlfwong](https://github.com/jlfwong))
|
||||
- Alert instead of crash when importing a file containing no profiles ([#205](https://github.com/jlfwong/speedscope/pull/205)) (by [@jlfwong](https://github.com/jlfwong))
|
||||
- Fixed import of multithreaded profiles from Chrome 66 ([#206](https://github.com/jlfwong/speedscope/pull/206)) (by [@jlfwong](https://github.com/jlfwong))
|
||||
- Fixed import of instruments trace files with missing run number ([#203](https://github.com/jlfwong/speedscope/pull/203)) (by [@Archerlly](https://github.com/Archerlly))
|
||||
|
||||
## [1.4.1] - 2019-01-22
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fix importing of Trace Event Format files with no ts field on M events [#198] (by @jlfwong)
|
||||
- Fix importing of Trace Event Format files with no ts field on M events [[#198](https://github.com/jlfwong/speedscope/pull/198)] (by [@jlfwong](https://github.com/jlfwong))
|
||||
|
||||
## [1.4.0] - 2019-01-22
|
||||
|
||||
### Added
|
||||
|
||||
* Import v8 cpu profile (old format) [#177] (by @vmarchaud)
|
||||
* Import basic "Trace Event Format" profiles [#197] (by @jlfwong)
|
||||
- Import v8 cpu profile (old format) [[#177](https://github.com/jlfwong/speedscope/pull/177)] (by [@vmarchaud](https://github.com/vmarchaud))
|
||||
- Import basic "Trace Event Format" profiles [[#197](https://github.com/jlfwong/speedscope/pull/197)] (by [@jlfwong](https://github.com/jlfwong))
|
||||
|
||||
## [1.3.2] - 2018-12-03
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed import of multithreaded Chrome profiles [#19] (by @jlfwong)
|
||||
- Fixed import of multithreaded Chrome profiles [[#19](https://github.com/jlfwong/speedscope/pull/19)] (by [@jlfwong](https://github.com/jlfwong))
|
||||
|
||||
## [1.3.1] - 2018-11-08
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed a file import performance regression by using TextDecoder [#188] (by @jlfwong)
|
||||
- Fixed a file import performance regression by using TextDecoder [[#188](https://github.com/jlfwong/speedscope/pull/188)] (by [@jlfwong](https://github.com/jlfwong))
|
||||
|
||||
## [1.3.0] - 2018-10-29
|
||||
|
||||
### Added
|
||||
|
||||
* Support import from Haskell GHC JSON format support [#183] (by @trishume)
|
||||
- Support import from Haskell GHC JSON format support [[#183](https://github.com/jlfwong/speedscope/pull/183)] (by [@trishume](https://github.com/trishume))
|
||||
|
||||
### Fixed
|
||||
|
||||
* Make the wasd keymappings work on azerty keyboards [#184] (by @vrischmann)
|
||||
* Fix import of binary formats via profileURL [#179] (by @f-hj)
|
||||
- Make the wasd keymappings work on azerty keyboards [[#184](https://github.com/jlfwong/speedscope/pull/184)] (by [@vrischmann](https://github.com/vrischmann))
|
||||
- Fix import of binary formats via profileURL [[#179](https://github.com/jlfwong/speedscope/pull/179)] (by [@f](https://github.com/f)-hj)
|
||||
|
||||
## [1.2.0] - 2018-10-08
|
||||
|
||||
### Added
|
||||
|
||||
* Add import of v8 heap allocation profile [#170] (by @vmarchaud)
|
||||
- Add import of v8 heap allocation profile [[#170](https://github.com/jlfwong/speedscope/pull/170)] (by [@vmarchaud](https://github.com/vmarchaud))
|
||||
|
||||
## [1.1.0] - 2018-09-26
|
||||
|
||||
### Added
|
||||
|
||||
* Add go tool pprof import support [#165]
|
||||
- Add go tool pprof import support [[#165](https://github.com/jlfwong/speedscope/pull/165)]
|
||||
|
||||
## [1.0.4] - 2018-09-12
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fix import from Chrome < 69 when there are multiple profiles [#161]
|
||||
- Fix import from Chrome < 69 when there are multiple profiles [[#161](https://github.com/jlfwong/speedscope/pull/161)]
|
||||
|
||||
## [1.0.3] - 2018-09-10
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fix import for Chrome 69, support leading idle time before first call [#160]
|
||||
- Fix import for Chrome 69, support leading idle time before first call [[#160](https://github.com/jlfwong/speedscope/pull/160)]
|
||||
|
||||
## [1.0.2] - 2018-09-04
|
||||
|
||||
### Fixed
|
||||
|
||||
* Allow optional CR before LF when probing collapsed stacks files [#154]
|
||||
* Fix import for Firefox 63 [#156]
|
||||
* Change time formatting for minutes from 1.50min to 1:30 [#153] (by @Alex-Diez)
|
||||
- Allow optional CR before LF when probing collapsed stacks files [[#154](https://github.com/jlfwong/speedscope/pull/154)]
|
||||
- Fix import for Firefox 63 [[#156](https://github.com/jlfwong/speedscope/pull/156)]
|
||||
- Change time formatting for minutes from 1.50min to 1:30 [[#153](https://github.com/jlfwong/speedscope/pull/153)] (by [@Alex](https://github.com/Alex)-Diez)
|
||||
|
||||
## [1.0.1] - 2018-08-23
|
||||
|
||||
* Fixed an issue where flamegraph bounds were not always being cleared correctly, leading to visual artifacts [#150]
|
||||
- Fixed an issue where flamegraph bounds were not always being cleared correctly, leading to visual artifacts [[#150](https://github.com/jlfwong/speedscope/pull/150)]
|
||||
|
||||
## [1.0.0] - 2018-08-23
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed rendering issues when switching between screens w/ different `devicePixelRatios` [#147]
|
||||
- Fixed rendering issues when switching between screens w/ different `devicePixelRatios` [[#147](https://github.com/jlfwong/speedscope/pull/147)]
|
||||
|
||||
## [0.7.1] - 2018-08-20
|
||||
|
||||
### Fixed
|
||||
|
||||
* Removed dependency on regl in order to allow speedscope to run in strict content-security-policy environments [#140]
|
||||
* Fixed text culling bug [#143]
|
||||
- Removed dependency on regl in order to allow speedscope to run in strict content-security-policy environments [[#140](https://github.com/jlfwong/speedscope/pull/140)]
|
||||
- Fixed text culling bug [[#143](https://github.com/jlfwong/speedscope/pull/143)]
|
||||
|
||||
## [0.7.0] - 2018-08-16
|
||||
|
||||
### Added
|
||||
|
||||
* Added support to import from linux `perf script` [#135]
|
||||
- Added support to import from linux `perf script` [[#135](https://github.com/jlfwong/speedscope/pull/135)]
|
||||
|
||||
## [0.6.0] - 2018-08-14
|
||||
|
||||
### Added
|
||||
|
||||
* Added support for multiple threads/processes [#130]
|
||||
* Import all runs & threads from Instruments .trace files instead of just main thread from selected run [#130]
|
||||
- Added support for multiple threads/processes [[#130](https://github.com/jlfwong/speedscope/pull/130)]
|
||||
- Import all runs & threads from Instruments .trace files instead of just main thread from selected run [[#130](https://github.com/jlfwong/speedscope/pull/130)]
|
||||
|
||||
### Fixed
|
||||
|
||||
* Ensure the JSON schema has actual contents [#133]
|
||||
- Ensure the JSON schema has actual contents [[#133](https://github.com/jlfwong/speedscope/pull/133)]
|
||||
|
||||
## [0.5.1] - 2018-08-09
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed broken CLI
|
||||
- Fixed broken CLI
|
||||
|
||||
## [0.5.0] - 2018-08-09
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fix emscripten remapping when symbols contain dashes, like `527:i32s-div` [#129]
|
||||
* Improved firefox import speed and fixed bugs in it [#128]
|
||||
* Prevent non-contiguous blocks in the time ordered flamechart from appearing as a single node for selection [#123]
|
||||
* Prevent dragging from changing selection [#122]
|
||||
* Clamp zoom to prevent floating point issues [#121]
|
||||
* Preserve view state when switching tabs [#100]
|
||||
- Fix emscripten remapping when symbols contain dashes, like `527:i32s-div` [[#129](https://github.com/jlfwong/speedscope/pull/129)]
|
||||
- Improved firefox import speed and fixed bugs in it [[#128](https://github.com/jlfwong/speedscope/pull/128)]
|
||||
- Prevent non-contiguous blocks in the time ordered flamechart from appearing as a single node for selection [[#123](https://github.com/jlfwong/speedscope/pull/123)]
|
||||
- Prevent dragging from changing selection [[#122](https://github.com/jlfwong/speedscope/pull/122)]
|
||||
- Clamp zoom to prevent floating point issues [[#121](https://github.com/jlfwong/speedscope/pull/121)]
|
||||
- Preserve view state when switching tabs [[#100](https://github.com/jlfwong/speedscope/pull/100)]
|
||||
|
||||
## [0.4.0] - 2018-07-21
|
||||
|
||||
### Added
|
||||
|
||||
* Support for importing v8 logs from node [#98]
|
||||
* Optionally read from stdin via cli [#99]
|
||||
- Support for importing v8 logs from node [[#98](https://github.com/jlfwong/speedscope/pull/98)]
|
||||
- Optionally read from stdin via cli [[#99](https://github.com/jlfwong/speedscope/pull/99)]
|
||||
|
||||
## [0.3.0] - 2018-07-18
|
||||
|
||||
### Added
|
||||
|
||||
* Support for remapping profiles using a wasm symbol file [#93]
|
||||
- Support for remapping profiles using a wasm symbol file [[#93](https://github.com/jlfwong/speedscope/pull/93)]
|
||||
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
简体中文 | [English](./README.md)
|
||||
# 🔬speedscope
|
||||
|
||||
一个快速,交互式,基于网络的性能分析工具。 [FlameGraphs][1](火焰图)的另一个替代品。它可以轻松显示数兆的配置文件并且不会使浏览器崩溃。
|
||||
|
||||
给定原始分析数据,你就可以交互式的探索数据,了解应用程序中什么部分速度较慢,或者分配所有内存,或者对任何数据进行分析。
|
||||
|
||||

|
||||
|
||||
[0]: https://en.wikipedia.org/wiki/Profiling_(computer_programming)#Statistical_profilers
|
||||
[1]: https://github.com/brendangregg/FlameGraph
|
||||
|
||||
# 使用
|
||||
|
||||
访问https://www.speedscope.app,上传文件或者拖拽到页面上。配置文件不会上传到任何地方——应用程序完全在浏览器中。
|
||||
|
||||
## 命令行中使用
|
||||
|
||||
为了方便在不联网的情况下或者在终端中使用, 你可以使用npm下载speedscope:
|
||||
|
||||
npm install -g speedscope
|
||||
|
||||
调用`speedscope /path/to/profile` 就可以在默认浏览器中加载speedscope。
|
||||
|
||||
## 独立使用
|
||||
|
||||
如果你不想使用npm或者node下载,你也可以在这里下载独立的版本https://github.com/jlfwong/speedscope/releases.
|
||||
下载完一个版本的压缩文件之后,解压并在谷歌或者火狐浏览器中打开`index.html`文件即可。
|
||||
|
||||
## 支持的文件格式
|
||||
|
||||
Speedscope可以不同编程语言和环境的各种不同探查器中摄取概要文件。单击下面的链接获取从特定源导入的文档。
|
||||
|
||||
- JavaScript
|
||||
- [从 Chrome 导入](https://github.com/jlfwong/speedscope/wiki/Importing-from-Chrome)
|
||||
- [从 Firefox 导入](https://github.com/jlfwong/speedscope/wiki/Importing-from-Firefox)
|
||||
- [从 Safari 导入](https://github.com/jlfwong/speedscope/wiki/Importing-from-Safari)
|
||||
- [从 Node.js 导入](https://github.com/jlfwong/speedscope/wiki/Importing-from-Node.js)
|
||||
- Ruby
|
||||
- [从 stackprof 导入](https://github.com/jlfwong/speedscope/wiki/Importing-from-stackprof-(ruby))
|
||||
- [从 rbspy 导入](https://github.com/jlfwong/speedscope/wiki/Importing-from-rbspy-(ruby))
|
||||
- [从 ruby-prof 导入](https://github.com/jlfwong/speedscope/wiki/Importing-from-ruby-prof)
|
||||
- Python
|
||||
- [从 py-spy 导入](https://github.com/jlfwong/speedscope/wiki/Importing-from-py-spy-(python))
|
||||
- [pyspeedscope](https://github.com/windelbouwman/pyspeedscope)
|
||||
- [从 Austin 导入](https://github.com/P403n1x87/austin-python#format-conversion)
|
||||
- [从 pyinstrument 导入](https://github.com/jlfwong/speedscope/wiki/Importing-from-pyinstrument-(python))
|
||||
- PHP
|
||||
- [从 phpspy 或者 sj-i/php-profiler 导入](https://github.com/sj-i/php-profiler/pull/101)
|
||||
- Go
|
||||
- [从 pprof 导入](https://github.com/jlfwong/speedscope/wiki/Importing-from-pprof-(go))
|
||||
- Rust
|
||||
- [flamescope](https://github.com/coolreader18/flamescope)
|
||||
- Native code
|
||||
- [从 Instruments.app 导入](https://github.com/jlfwong/speedscope/wiki/Importing-from-Instruments.app) (macOS)
|
||||
- [从 `perf` 导入](https://github.com/jlfwong/speedscope/wiki/Importing-from-perf-(linux)) (linux)
|
||||
- [从 .NET Core 导入](https://github.com/jlfwong/speedscope/wiki/Importing-from-.NET-Core)
|
||||
- [从 GHC (Haskell) 导入](https://github.com/jlfwong/speedscope/wiki/Importing-from-Haskell)
|
||||
- [从 custom sources 导入](https://github.com/jlfwong/speedscope/wiki/Importing-from-custom-sources)
|
||||
|
||||
极力欢迎贡献添加对其他格式的支持!查看 issues ["import source" tag](https://github.com/jlfwong/speedscope/issues?q=is%3Aissue+is%3Aopen+label%3A%22import+source%22).
|
||||
|
||||
## 通过URL导入
|
||||
|
||||
要通过URL加载特定的配置文件,你可以添加一个这样的hash片段 `#profileURL=[URL-encoded profile URL]&title=[URL-encoded custom title]`. 注意:托管配置文件的服务器必须配置CORS以允许来自speedscope的AJAX请求。
|
||||
|
||||
## 页面
|
||||
|
||||
### 🕰Time Order
|
||||

|
||||
|
||||
在 "Time Order" 页面 (默认),调用堆栈按照它们在输入文件中出现的顺序从左到右排列,这通常是安排它们被记录的时间顺序。这个视图对于理解应用程序随时间变化的行为非常有帮助,比如 "首次从数据库获取到数据,然后为序列化准备数据,数据被序列化为JSON"。
|
||||
|
||||
水平轴表示每个堆栈的“权重”(最常见的是CPU时间),垂直轴显示在运行期间处于活动状态的堆栈。如果你点击其中一个框,你将能够看到关于它的统计摘要。
|
||||
|
||||
|
||||
### ⬅️Left Heavy
|
||||

|
||||
|
||||
在 "Left Heavy" 页面,将相同的堆栈分组在一,不管它们是否按顺序记录。然后,对堆栈进行排序,使每个父堆栈中最重的堆栈位于左侧——因此称为“左权重”。 这个视图对于理解在其他调用栈之间有成百上千个函数交错调用的情况下,时间都花费在了哪里很有用。
|
||||
|
||||
### 🥪 Sandwich
|
||||

|
||||
|
||||
Sandwich 是一个表格视图,你可以在其中找到所有函数及其相关时间的列表。您可以按自己的时间或总时间排序。
|
||||
之所以称为"Sandwich"视图,是因为如果你选择表中的某一行,就可以看到所选对象的所有调用者和被调用者的火焰图
|
||||
。
|
||||
|
||||
|
||||
## 导航
|
||||
|
||||
一旦配置文件被加载,主视图就会被分成两部分:顶部区域是“迷你地图”,底部区域是“堆栈视图”。
|
||||
|
||||
### 迷你地图导航
|
||||
|
||||
* 在任意一个轴上滚动以进行平移
|
||||
* 单击并拖动可将视图缩小到特定范围
|
||||
|
||||
### 堆栈视图
|
||||
|
||||
* 在任意一个轴上滚动以进行平移
|
||||
* 缩放
|
||||
* 按住 Cmd+Scroll 进行缩放
|
||||
* 双击一帧以使视口适应
|
||||
* 点击一个框以查看关于它的摘要统计
|
||||
|
||||
### 键盘导航
|
||||
|
||||
* `+`: 放大
|
||||
* `-`: 缩小
|
||||
* `0`: 缩小以看到整体情况
|
||||
* `w`/`a`/`s`/`d` 或者箭头键: pan around the profile
|
||||
* `1`: 切换到 "Time Order" 视图
|
||||
* `2`: 切换到 "Left Heavy" 视图
|
||||
* `3`: 切换到 "Sandwich" 视图
|
||||
* `r`: 在火焰图中折叠递归
|
||||
* `Cmd+S`/`Ctrl+S` 保存现有文件
|
||||
* `Cmd+O`/`Ctrl+O` 打开一个新文件
|
||||
* `n`: 跳转到下一个文件/如果下一个文件存在
|
||||
* `p`: 跳转到上一个文件/如果上一个文件存在
|
||||
* `t`: 打开一个新文件/如果新文件存在
|
||||
* `Cmd+F`/`Ctrl+F`: 打开搜索。打开时,按下 `Enter` and `Shift+Enter` 查看结果
|
||||
|
||||
## 参与贡献
|
||||
|
||||
你想成为 speedscope 的贡献者吗? 查看 [CONTRIBUTING.md](./CONTRIBUTING.md) 关于设置开发环境的说明。
|
||||
@@ -1,4 +1,5 @@
|
||||
# 🔬speedscope
|
||||
English | [简体中文](./README-zh_CN.md)
|
||||
# 🔬speedscope
|
||||
|
||||
A fast, interactive web-based viewer for performance profiles. An alternative viewer for [FlameGraphs][1]. Will happily display multi-megabyte profiles without crashing your browser.
|
||||
|
||||
@@ -36,15 +37,27 @@ speedscope is designed to ingest profiles from a variety of different profilers
|
||||
- JavaScript
|
||||
- [Importing from Chrome](https://github.com/jlfwong/speedscope/wiki/Importing-from-Chrome)
|
||||
- [Importing from Firefox](https://github.com/jlfwong/speedscope/wiki/Importing-from-Firefox)
|
||||
- [Importing from Safari](https://github.com/jlfwong/speedscope/wiki/Importing-from-Safari)
|
||||
- [Importing from Node.js](https://github.com/jlfwong/speedscope/wiki/Importing-from-Node.js)
|
||||
- Ruby
|
||||
- [Importing from stackprof](https://github.com/jlfwong/speedscope/wiki/Importing-from-stackprof-(ruby))
|
||||
- [Importing from rbspy](https://github.com/jlfwong/speedscope/wiki/Importing-from-rbspy-(ruby))
|
||||
- [Importing from ruby-prof](https://github.com/jlfwong/speedscope/wiki/Importing-from-ruby-prof)
|
||||
- Python
|
||||
- [Importing from py-spy](https://github.com/jlfwong/speedscope/wiki/Importing-from-py-spy-(python))
|
||||
- [pyspeedscope](https://github.com/windelbouwman/pyspeedscope)
|
||||
- [Importing from Austin](https://github.com/P403n1x87/austin-python#format-conversion)
|
||||
- [Importing from pyinstrument](https://github.com/jlfwong/speedscope/wiki/Importing-from-pyinstrument-(python))
|
||||
- PHP
|
||||
- [Importing from phpspy or sj-i/php-profiler](https://github.com/sj-i/php-profiler/pull/101)
|
||||
- Go
|
||||
- [Importing from pprof](https://github.com/jlfwong/speedscope/wiki/Importing-from-pprof-(go))
|
||||
- Rust
|
||||
- [flamescope](https://github.com/coolreader18/flamescope)
|
||||
- Native code
|
||||
- [Importing from Instruments.app](https://github.com/jlfwong/speedscope/wiki/Importing-from-Instruments.app) (macOS)
|
||||
- [Importing from `perf`](https://github.com/jlfwong/speedscope/wiki/Importing-from-perf-(linux)) (linux)
|
||||
- [Importing from .NET Core](https://github.com/jlfwong/speedscope/wiki/Importing-from-.NET-Core)
|
||||
- [Importing from GHC (Haskell)](https://github.com/jlfwong/speedscope/wiki/Importing-from-Haskell)
|
||||
- [Importing from custom sources](https://github.com/jlfwong/speedscope/wiki/Importing-from-custom-sources)
|
||||
|
||||
@@ -72,7 +85,7 @@ In the "Left Heavy" view, identical stacks are grouped together, regardless of w
|
||||
### 🥪 Sandwich
|
||||

|
||||
|
||||
The Sandwich view is a table view in which you can find a list of all functions an their associated times. You can sort by self time or total time.
|
||||
The Sandwich view is a table view in which you can find a list of all functions and their associated times. You can sort by self time or total time.
|
||||
It's called "Sandwich" view because if you select one of the rows in the table, you can see flamegraphs for all the callers and callees of the selected
|
||||
row.
|
||||
|
||||
@@ -108,6 +121,8 @@ Once a profile has loaded, the main view is split into two: the top area is the
|
||||
* `Cmd+O`/`Ctrl+O` to open a new profile
|
||||
* `n`: Go to next profile/thread if one is available
|
||||
* `p`: Go to previous profile/thread if one is available
|
||||
* `t`: Open the profile/thread selector if available
|
||||
* `Cmd+F`/`Ctrl+F`: to open search. While open, `Enter` and `Shift+Enter` cycle through results
|
||||
|
||||
## Contributing
|
||||
|
||||
|
||||
+20
-6
@@ -4,7 +4,7 @@ const fs = require('fs')
|
||||
const os = require('os')
|
||||
const stream = require('stream')
|
||||
|
||||
const opn = require('opn')
|
||||
const open = require('open')
|
||||
|
||||
const helpString = `Usage: speedscope [filepath]
|
||||
|
||||
@@ -66,10 +66,20 @@ async function main() {
|
||||
const relPath = process.argv[2]
|
||||
const sourceBuffer = await getProfileBuffer(relPath)
|
||||
const filename = path.basename(relPath)
|
||||
const sourceBase64 = sourceBuffer.toString('base64')
|
||||
const jsSource = `speedscope.loadFileFromBase64(${JSON.stringify(filename)}, ${JSON.stringify(
|
||||
sourceBase64,
|
||||
)})`
|
||||
|
||||
let jsSource
|
||||
try {
|
||||
const sourceBase64 = sourceBuffer.toString('base64')
|
||||
jsSource = `speedscope.loadFileFromBase64(${JSON.stringify(filename)}, ${JSON.stringify(
|
||||
sourceBase64,
|
||||
)})`
|
||||
} catch(e) {
|
||||
if (e && e.message && /Cannot create a string longer than/.exec(e.message)) {
|
||||
jsSource = `alert("Sorry, ${filename} is too large to be loaded via command-line argument! Try dragging it into speedscope instead.")`
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
const filePrefix = `speedscope-${+new Date()}-${process.pid}`
|
||||
const jsPath = path.join(os.tmpdir(), `${filePrefix}.js`)
|
||||
@@ -89,7 +99,11 @@ async function main() {
|
||||
|
||||
console.log('Opening', urlToOpen, 'in your default browser')
|
||||
|
||||
await opn(urlToOpen, {wait: false})
|
||||
// We'd like to avoid blocking the terminal on the browsing closing,
|
||||
// but for some reason this doesn't work at all on Windows if we
|
||||
// don't use wait: true.
|
||||
const wait = process.platform === "win32";
|
||||
await open(urlToOpen, {wait})
|
||||
}
|
||||
|
||||
main()
|
||||
|
||||
Generated
+22430
-8893
File diff suppressed because it is too large
Load Diff
+44
-22
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "speedscope",
|
||||
"version": "1.4.1",
|
||||
"version": "1.15.0",
|
||||
"description": "",
|
||||
"repository": "jlfwong/speedscope",
|
||||
"main": "index.js",
|
||||
@@ -13,48 +13,70 @@
|
||||
"prettier": "prettier --write 'src/**/*.ts' 'src/**/*.tsx'",
|
||||
"lint": "eslint 'src/**/*.ts' 'src/**/*.tsx'",
|
||||
"jest": "./scripts/test-setup.sh && jest --runInBand",
|
||||
"coverage": "npm run jest -- --coverage && coveralls < coverage/lcov.info",
|
||||
"test": "tsc --noEmit && npm run lint && npm run coverage",
|
||||
"coverage": "npm run jest -- --coverage",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"test": "./scripts/ci.sh",
|
||||
"serve": "parcel assets/index.html --open --no-autoinstall"
|
||||
},
|
||||
"files": ["bin/cli.js", "dist/release/**", "!*.map"],
|
||||
"browserslist": ["last 2 Chrome versions", "last 2 Firefox versions"],
|
||||
"files": [
|
||||
"bin/cli.js",
|
||||
"dist/release/**",
|
||||
"!*.map"
|
||||
],
|
||||
"browserslist": [
|
||||
"last 2 Chrome versions",
|
||||
"last 2 Firefox versions"
|
||||
],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/jest": "22.2.3",
|
||||
"@types/jszip": "3.1.4",
|
||||
"@types/node": "10.1.4",
|
||||
"@types/node": "14.0.1",
|
||||
"@types/pako": "1.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "4.19.0",
|
||||
"@typescript-eslint/parser": "4.19.0",
|
||||
"acorn": "7.2.0",
|
||||
"aphrodite": "2.1.0",
|
||||
"coveralls": "3.0.1",
|
||||
"eslint": "4.19.1",
|
||||
"eslint": "6.0.0",
|
||||
"eslint-plugin-prettier": "2.6.0",
|
||||
"jest": "23.0.1",
|
||||
"eslint-plugin-react-hooks": "4.0.2",
|
||||
"jest": "24.3.0",
|
||||
"jsverify": "0.8.3",
|
||||
"jszip": "3.1.5",
|
||||
"pako": "1.0.6",
|
||||
"parcel-bundler": "1.9.2",
|
||||
"preact": "8.2.7",
|
||||
"preact-redux": "jlfwong/preact-redux#a56dcc4",
|
||||
"prettier": "1.12.0",
|
||||
"parcel-bundler": "1.12.4",
|
||||
"preact": "10.4.1",
|
||||
"prettier": "2.0.4",
|
||||
"protobufjs": "6.8.8",
|
||||
"quicktype": "15.0.45",
|
||||
"redux": "^4.0.0",
|
||||
"ts-jest": "22.4.6",
|
||||
"typescript": "2.8.1",
|
||||
"typescript-eslint-parser": "17.0.1",
|
||||
"uglify-es": "3.2.2"
|
||||
"source-map": "0.6.1",
|
||||
"ts-jest": "24.3.0",
|
||||
"typescript": "4.2.3",
|
||||
"typescript-json-schema": "0.42.0",
|
||||
"uglify-es": "3.2.2",
|
||||
"uint8array-json-parser": "0.0.2"
|
||||
},
|
||||
"jest": {
|
||||
"transform": {
|
||||
"^.+\\.tsx?$": "ts-jest"
|
||||
},
|
||||
"setupFilesAfterEnv": [
|
||||
"./src/jest-setup.js"
|
||||
],
|
||||
"testRegex": "\\.test\\.tsx?$",
|
||||
"collectCoverageFrom": ["**/*.{ts,tsx}", "!**/*.d.{ts,tsx}"],
|
||||
"moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json"]
|
||||
"collectCoverageFrom": [
|
||||
"**/*.{ts,tsx}",
|
||||
"!**/*.d.{ts,tsx}"
|
||||
],
|
||||
"moduleFileExtensions": [
|
||||
"ts",
|
||||
"tsx",
|
||||
"js",
|
||||
"jsx",
|
||||
"json"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"opn": "5.3.0"
|
||||
"open": "7.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -4,4 +4,5 @@ module.exports = {
|
||||
semi: false,
|
||||
singleQuote: true,
|
||||
trailingComma: 'all',
|
||||
};
|
||||
arrowParens: 'avoid'
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -0,0 +1,46 @@
|
||||
Weight Self Weight Symbol Name
|
||||
96.08 Gc 100.0% - example_app (40414)
|
||||
96.08 Gc 100.0% - start
|
||||
96.08 Gc 100.0% - main
|
||||
96.08 Gc 100.0% - std::rt::lang_start::hdba6f1ebfd1bdcf8
|
||||
96.08 Gc 100.0% - std::rt::lang_start_internal::hc453db0ee48af82e
|
||||
96.08 Gc 100.0% - std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::hd856f2663871206c
|
||||
96.08 Gc 100.0% - std::sys_common::backtrace::__rust_begin_short_backtrace::h4869fd82068bc1dc
|
||||
96.08 Gc 100.0% - core::ops::function::FnOnce::call_once::h06e0c27ee740c6a8
|
||||
96.08 Gc 100.0% - example_app::main::hddab13ae8d8b6a6e
|
||||
47.82 Gc 49.7% - example_app::example_a::h622d6879b734496d
|
||||
46.92 Gc 48.8% 404.75 Mc std::time::Instant::elapsed::h2e3793148fc23529
|
||||
45.92 Gc 47.7% 45.92 Gc mach_absolute_time
|
||||
600.78 Mc 0.6% 600.78 Mc std::time::Instant::elapsed::h2e3793148fc23529
|
||||
1.00 Mc 0.0% 1.00 Mc DYLD-STUB$$mach_absolute_time
|
||||
634.35 Mc 0.6% 634.35 Mc core::time::Duration::as_millis::hae6ad1b9cf7bb5ec
|
||||
181.50 Mc 0.1% 181.50 Mc example_app::example_a::h622d6879b734496d
|
||||
84.45 Mc 0.0% - example_app::example_b::h71b31fcd89b9ffd2
|
||||
81.45 Mc 0.0% - std::time::Instant::elapsed::h2e3793148fc23529
|
||||
80.45 Mc 0.0% 80.45 Mc mach_absolute_time
|
||||
1.00 Mc 0.0% 1.00 Mc std::time::Instant::elapsed::h2e3793148fc23529
|
||||
1.00 Mc 0.0% - example_app::example_c::h631759c10d7dee93
|
||||
1.00 Mc 0.0% - alloc::vec::Vec$LT$T$C$A$GT$::push::ha3426502ffc42c8b
|
||||
1.00 Mc 0.0% - alloc::raw_vec::RawVec$LT$T$C$A$GT$::reserve_for_push::he4a29b8274e35dbb
|
||||
1.00 Mc 0.0% - alloc::raw_vec::RawVec$LT$T$C$A$GT$::grow_amortized::h78db9ba423623c58
|
||||
1.00 Mc 0.0% - alloc::raw_vec::finish_grow::h876f5af1c66d74c8
|
||||
1.00 Mc 0.0% - _$LT$alloc..alloc..Global$u20$as$u20$core..alloc..Allocator$GT$::allocate::hcc733a40a34fbc94
|
||||
1.00 Mc 0.0% - alloc::alloc::Global::alloc_impl::hc55feba7d6266dfa
|
||||
1.00 Mc 0.0% - alloc::alloc::alloc::hfac63f3d6850b759
|
||||
1.00 Mc 0.0% - _malloc_zone_malloc
|
||||
1.00 Mc 0.0% - nanov2_malloc
|
||||
1.00 Mc 0.0% - nanov2_allocate
|
||||
1.00 Mc 0.0% - nanov2_allocate
|
||||
1.00 Mc 0.0% 1.00 Mc nanov2_find_block_and_allocate
|
||||
1.00 Mc 0.0% 1.00 Mc example_app::example_b::h71b31fcd89b9ffd2
|
||||
1.00 Mc 0.0% 1.00 Mc core::time::Duration::as_millis::hae6ad1b9cf7bb5ec
|
||||
47.45 Gc 49.3% 415.12 Mc std::time::Instant::elapsed::h2e3793148fc23529
|
||||
46.39 Gc 48.2% 46.39 Gc mach_absolute_time
|
||||
649.70 Mc 0.6% 649.70 Mc std::time::Instant::elapsed::h2e3793148fc23529
|
||||
614.22 Mc 0.6% 614.22 Mc core::time::Duration::as_millis::hae6ad1b9cf7bb5ec
|
||||
190.55 Mc 0.1% 190.55 Mc example_app::main::hddab13ae8d8b6a6e
|
||||
1.34 Kc 0.0% - std::io::stdio::_print::hdecfefdeb43586ed
|
||||
1.34 Kc 0.0% - _$LT$$RF$std..io..stdio..Stdout$u20$as$u20$std..io..Write$GT$::write_fmt::h2cb06dcd2b172844
|
||||
1.34 Kc 0.0% - core::fmt::write::hed96bcfc6342aee5
|
||||
532 cycles 0.0% - _$LT$std..io..Write..write_fmt..Adapter$LT$T$GT$$u20$as$u20$core..fmt..Write$GT$::write_str::hbe33ec23de24ce2f
|
||||
532 cycles 0.0% 532 cycles _$LT$std..io..stdio..StdoutLock$u20$as$u20$std..io..Write$GT$::write_all::h22667d0a03b2151b
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,24 @@
|
||||
# callgrind format
|
||||
events: Instructions
|
||||
|
||||
fl=file1.c
|
||||
fn=main
|
||||
16 20
|
||||
cfn=func1
|
||||
calls=1 50
|
||||
16 400
|
||||
cfi=file2.c
|
||||
cfn=func2
|
||||
calls=3 20
|
||||
16 400
|
||||
|
||||
fn=func1
|
||||
51 100
|
||||
cfi=file2.c
|
||||
cfn=func2
|
||||
calls=2 20
|
||||
51 300
|
||||
|
||||
fl=file2.c
|
||||
fn=func2
|
||||
20 700
|
||||
@@ -0,0 +1,29 @@
|
||||
version: 1
|
||||
creator: xdebug 3.0.2 (PHP 7.4.14)
|
||||
cmd: /var/www/html/index.php
|
||||
part: 1
|
||||
positions: line
|
||||
|
||||
events: Time_(10ns) Memory_(bytes)
|
||||
|
||||
fl=(1) file1.c
|
||||
fn=(1) main
|
||||
16 20 15000
|
||||
cfn=(2) func1
|
||||
calls=1 50
|
||||
16 400 20000
|
||||
cfi=(2) file2.c
|
||||
cfn=(3) func2
|
||||
calls=3 51
|
||||
16 400 3000
|
||||
|
||||
fn=(2)
|
||||
51 100 4000
|
||||
cfi=(2)
|
||||
cfn=(3)
|
||||
calls=2 20
|
||||
51 300 5000
|
||||
|
||||
fl=(2)
|
||||
fn=(3)
|
||||
20 700 6000
|
||||
@@ -0,0 +1,24 @@
|
||||
# callgrind format
|
||||
events: Instructions
|
||||
|
||||
fl=(1) file1.c
|
||||
fn=(1) main
|
||||
16 20
|
||||
cfn=(2) func1
|
||||
calls=1 50
|
||||
16 400
|
||||
cfi=(2) file2.c
|
||||
cfn=(3) func2
|
||||
calls=3 20
|
||||
16 400
|
||||
|
||||
fn=(2)
|
||||
51 100
|
||||
cfi=(2)
|
||||
cfn=(3)
|
||||
calls=2 20
|
||||
51 300
|
||||
|
||||
fl=(2)
|
||||
fn=(3)
|
||||
20 700
|
||||
@@ -0,0 +1,4 @@
|
||||
This directory contains profiles & source-maps to test if source-map
|
||||
remapping of profiles is working correctly. See the corresponding
|
||||
"sourcemaps" directory in programs/javascript to see how these were
|
||||
generated.
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": ["gamma.ts", "beta.ts", "delta.ts", "alpha.ts", "kludge.ts", "typescript-source-map-test.ts"],
|
||||
"sourcesContent": ["export const gamma = () => {\n let prod = 1\n for (let i = 1; i < 1000; i++) {\n prod *= i\n }\n return prod\n}\n", "import {gamma} from './gamma'\n\nexport function beta() {\n for (let i = 0; i < 10; i++) {\n gamma()\n }\n}\n", "import {gamma} from './gamma'\n\nexport const delta = function () {\n for (let i = 0; i < 10; i++) {\n gamma()\n }\n}\n", "import {beta} from './beta'\nimport {delta} from './delta'\n\nexport function alpha() {\n ;(function () {\n for (let i = 0; i < 1000; i++) {\n beta()\n delta()\n }\n })()\n}\n", "import {alpha} from './alpha'\n\nexport class Kludge {\n constructor() {\n alpha()\n console.log(this.floop)\n }\n\n zap() {\n alpha()\n }\n\n get floop(): number {\n alpha()\n return 1\n }\n}\n", "import {Kludge} from './kludge'\n\nconst k = new Kludge()\nk.zap()\n"],
|
||||
"mappings": "MAAO,KAAM,GAAQ,KACnB,GAAI,GAAO,EACX,OAAS,GAAI,EAAG,EAAI,IAAM,IACxB,GAAQ,EAEV,MAAO,ICHF,aACL,OAAS,GAAI,EAAG,EAAI,GAAI,IACtB,ICFG,KAAM,GAAQ,WACnB,OAAS,GAAI,EAAG,EAAI,GAAI,IACtB,KCDG,aACJ,AAAC,YACA,OAAS,GAAI,EAAG,EAAI,IAAM,IACxB,IACA,QCPN,QAGE,cACE,IACA,QAAQ,IAAI,KAAK,OAGnB,MACE,OAGE,SACF,WACO,GCZX,KAAM,GAAI,GAAI,GACd,EAAE",
|
||||
"names": []
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["gamma.ts","beta.ts","delta.ts","alpha.ts","kludge.ts","typescript-source-map-test.ts"],"names":[],"mappings":";AAAO,aAAA,OAAA,eAAA,QAAA,aAAA,CAAA,OAAA,IAAA,QAAA,WAAA,EAAA,IAAM,EAAQ,WAEd,IADD,IAAA,EAAO,EACF,EAAI,EAAG,EAAI,IAAM,IACxB,GAAQ,EAEH,OAAA,GALF,QAAA,MAAA;;ACMN,aAAA,OAAA,eAAA,QAAA,aAAA,CAAA,OAAA,IAAA,QAAA,KAAA,EAND,IAAA,EAAA,QAAA,WAEM,SAAU,IACT,IAAA,IAAI,EAAI,EAAG,EAAI,GAAI,KACtB,EAAA,EAAA;;ACFG,aAAA,OAAA,eAAA,QAAA,aAAA,CAAA,OAAA,IAAA,QAAA,WAAA,EAFP,IAAA,EAAA,QAAA,WAEa,EAAQ,WACd,IAAA,IAAI,EAAI,EAAG,EAAI,GAAI,KACtB,EAAA,EAAA,UAFG,QAAA,MAAA;;ACQN,aAAA,OAAA,eAAA,QAAA,aAAA,CAAA,OAAA,IAAA,QAAA,MAAA,EAVD,IAAA,EAAA,QAAA,UACA,EAAA,QAAA,WAEM,SAAU,KACZ,WACK,IAAA,IAAI,EAAI,EAAG,EAAI,IAAM,KACxB,EAAA,EAAA,SACA,EAAA,EAAA,SAHF;;ACFJ,aAAA,OAAA,eAAA,QAAA,aAAA,CAAA,OAAA,IAAA,QAAA,YAAA,EAFA,IAAA,EAAA,QAAA,WAEA,EAAA,WACE,SAAA,KACE,EAAA,EAAA,SACA,QAAQ,IAAI,KAAK,OAWrB,OARE,EAAA,UAAA,IAAA,YACE,EAAA,EAAA,UAGF,OAAA,eAAI,EAAA,UAAA,QAAK,CAAT,IAAA,WAES,OADP,EAAA,EAAA,SACO,GAFA,YAAA,EAVX,cAAA,IAcA,EAdA,GAAA,QAAA,OAAA;;ACCA,aAHA,IAAA,EAAA,QAAA,YAEM,EAAI,IAAI,EAAJ,OACV,EAAE","file":"typescript-source-map-test.js","sourceRoot":"..","sourcesContent":["export const gamma = () => {\n let prod = 1\n for (let i = 1; i < 1000; i++) {\n prod *= i\n }\n return prod\n}\n","import {gamma} from './gamma'\n\nexport function beta() {\n for (let i = 0; i < 10; i++) {\n gamma()\n }\n}\n","import {gamma} from './gamma'\n\nexport const delta = function () {\n for (let i = 0; i < 10; i++) {\n gamma()\n }\n}\n","import {beta} from './beta'\nimport {delta} from './delta'\n\nexport function alpha() {\n ;(function () {\n for (let i = 0; i < 1000; i++) {\n beta()\n delta()\n }\n })()\n}\n","import {alpha} from './alpha'\n\nexport class Kludge {\n constructor() {\n alpha()\n console.log(this.floop)\n }\n\n zap() {\n alpha()\n }\n\n get floop(): number {\n alpha()\n return 1\n }\n}\n","import {Kludge} from './kludge'\n\nconst k = new Kludge()\nk.zap()\n"]}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["webpack://speedscope-sourcemap-test-project/./gamma.ts","webpack://speedscope-sourcemap-test-project/./beta.ts","webpack://speedscope-sourcemap-test-project/./delta.ts","webpack://speedscope-sourcemap-test-project/./alpha.ts","webpack://speedscope-sourcemap-test-project/./typescript-source-map-test.ts","webpack://speedscope-sourcemap-test-project/./kludge.ts"],"names":["gamma","prod","i","beta","delta","alpha","console","log","this","floop","zap"],"mappings":"mBAAO,IAAMA,EAAQ,WAEnB,IADA,IAAIC,EAAO,EACFC,EAAI,EAAGA,EAAI,IAAMA,IACxBD,GAAQC,EAEV,OAAOD,GCHF,SAASE,IACd,IAAK,IAAID,EAAI,EAAGA,EAAI,GAAIA,IACtBF,ICFG,IAAMI,EAAQ,WACnB,IAAK,IAAIF,EAAI,EAAGA,EAAI,GAAIA,IACtBF,KCDG,SAASK,KACb,WACC,IAAK,IAAIH,EAAI,EAAGA,EAAI,IAAMA,IACxBC,IACAC,IAHH,ICFO,ICAV,WACE,aACEC,IACAC,QAAQC,IAAIC,KAAKC,OAWrB,OARE,YAAAC,IAAA,WACEL,KAGF,sBAAI,oBAAK,C,IAAT,WAEE,OADAA,IACO,G,gCAEX,EAdA,KDCEK,O","file":"typescript-source-map-test.js","sourcesContent":["export const gamma = () => {\n let prod = 1\n for (let i = 1; i < 1000; i++) {\n prod *= i\n }\n return prod\n}\n","import {gamma} from './gamma'\n\nexport function beta() {\n for (let i = 0; i < 10; i++) {\n gamma()\n }\n}\n","import {gamma} from './gamma'\n\nexport const delta = function () {\n for (let i = 0; i < 10; i++) {\n gamma()\n }\n}\n","import {beta} from './beta'\nimport {delta} from './delta'\n\nexport function alpha() {\n ;(function () {\n for (let i = 0; i < 1000; i++) {\n beta()\n delta()\n }\n })()\n}\n","import {Kludge} from './kludge'\n\nconst k = new Kludge()\nk.zap()\n","import {alpha} from './alpha'\n\nexport class Kludge {\n constructor() {\n alpha()\n console.log(this.floop)\n }\n\n zap() {\n alpha()\n }\n\n get floop(): number {\n alpha()\n return 1\n }\n}\n"],"sourceRoot":""}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"$schema": "https://www.speedscope.app/file-format-schema.json",
|
||||
"shared": {
|
||||
"frames": [{"name": "A"}]
|
||||
},
|
||||
"profiles": [
|
||||
{
|
||||
"type": "evented",
|
||||
"name": "p1",
|
||||
"unit": "none",
|
||||
"startValue": 0,
|
||||
"endValue": 100,
|
||||
"events": [{"type": "O", "frame": 0, "at": 0}]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "https://www.speedscope.app/file-format-schema.json",
|
||||
"shared": {
|
||||
"frames": [{"name": "A"}, {"name": "B"}]
|
||||
},
|
||||
"profiles": [
|
||||
{
|
||||
"type": "evented",
|
||||
"name": "p1",
|
||||
"unit": "none",
|
||||
"startValue": 0,
|
||||
"endValue": 100,
|
||||
"events": [
|
||||
{"type": "O", "frame": 0, "at": 0},
|
||||
{"type": "C", "frame": 0, "at": 1},
|
||||
{"type": "O", "frame": 1, "at": 2},
|
||||
{"type": "O", "frame": 0, "at": 2},
|
||||
{"type": "O", "frame": 0, "at": 3},
|
||||
{"type": "C", "frame": 0, "at": 4},
|
||||
{"type": "C", "frame": 1, "at": 4},
|
||||
{"type": "C", "frame": 0, "at": 5}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
# comment that gives extra info about the samples
|
||||
// some other comment
|
||||
a;b;c 1
|
||||
a;b;c 1
|
||||
a;b;d 4
|
||||
a;b;c 3
|
||||
a;b 5
|
||||
invalid line
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,25 @@
|
||||
[
|
||||
{ "pid": 0, "tid": 0, "ph": "B", "ts": 0, "name": "A" },
|
||||
{ "pid": 0, "tid": 0, "ph": "E", "ts": 2, "name": "A" },
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 0, "dur": 2, "name": "B" },
|
||||
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 10, "dur": 2, "name": "C" },
|
||||
{ "pid": 0, "tid": 0, "ph": "B", "ts": 10, "name": "D" },
|
||||
{ "pid": 0, "tid": 0, "ph": "E", "ts": 12, "name": "D" },
|
||||
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 20, "dur": 1, "name": "E" },
|
||||
{ "pid": 0, "tid": 0, "ph": "B", "ts": 20, "name": "F" },
|
||||
{ "pid": 0, "tid": 0, "ph": "E", "ts": 22, "name": "F" },
|
||||
|
||||
{ "pid": 0, "tid": 0, "ph": "B", "ts": 30, "name": "G" },
|
||||
{ "pid": 0, "tid": 0, "ph": "E", "ts": 32, "name": "G" },
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 30, "dur": 1, "name": "H" },
|
||||
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 41, "dur": 1, "name": "I" },
|
||||
{ "pid": 0, "tid": 0, "ph": "B", "ts": 40, "name": "J" },
|
||||
{ "pid": 0, "tid": 0, "ph": "E", "ts": 42, "name": "J" },
|
||||
|
||||
{ "pid": 0, "tid": 0, "ph": "B", "ts": 50, "name": "K" },
|
||||
{ "pid": 0, "tid": 0, "ph": "E", "ts": 52, "name": "K" },
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 51, "dur": 1, "name": "L" }
|
||||
]
|
||||
@@ -0,0 +1,5 @@
|
||||
[
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "alpha", "ts": 0},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "alpha", "ts": 1},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "beta", "ts": 2}
|
||||
]
|
||||
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "A", "args": {"x": 1}, "ts": 0},
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "B", "args": {"x": 2}, "ts": 1},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "A", "args": {"x": 2}, "ts": 10},
|
||||
{"pid": 0, "tid": 0, "ph": "X", "name": "Z", "args": {"x": 1}, "ts": 10, "dur": 1}
|
||||
]
|
||||
@@ -0,0 +1,7 @@
|
||||
[
|
||||
{"tid": 1, "ph": "X", "pid": 0, "name": "alpha", "args": {"x": 0}, "ts": 0, "dur": 10},
|
||||
{"tid": 1, "ph": "B", "pid": 0, "name": "beta", "args": {"x": 0}, "ts": 1},
|
||||
{"tid": 1, "ph": "B", "pid": 0, "name": "gamma", "args": {"x": 0}, "ts": 1},
|
||||
{"tid": 1, "ph": "E", "pid": 0, "name": "beta", "args": {"x": 1}, "ts": 2},
|
||||
{"tid": 1, "ph": "E", "pid": 0, "name": "gamma", "args": {"x": 1}, "ts": 2}
|
||||
]
|
||||
@@ -0,0 +1,4 @@
|
||||
[
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 0, "dur": 10, "name": "alpha" },
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 5, "dur": 10, "name": "beta" }
|
||||
]
|
||||
@@ -0,0 +1,7 @@
|
||||
[
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 0, "dur": 10, "name": "alpha" },
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 1, "dur": 1, "name": "beta" },
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 1, "dur": 1, "name": "gamma" },
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 5, "dur": 1, "name": "gamma" },
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 5, "dur": 1, "name": "beta" }
|
||||
]
|
||||
@@ -0,0 +1,4 @@
|
||||
[
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "A", "args": {"x": 1}, "ts": 0},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "A", "args": {"x": 2}, "ts": 10}
|
||||
]
|
||||
@@ -0,0 +1,4 @@
|
||||
[
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "alpha", "ts": 0},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "beta", "ts": 10}
|
||||
]
|
||||
@@ -0,0 +1,16 @@
|
||||
[
|
||||
{"tid": 1, "ph": "B", "pid": 0, "name": "A", "ts": 0},
|
||||
{"tid": 1, "ph": "B", "pid": 0, "name": "B", "ts": 0},
|
||||
{"tid": 1, "ph": "B", "pid": 0, "name": "C", "ts": 0},
|
||||
{"tid": 1, "ph": "E", "pid": 0, "name": "C", "ts": 1},
|
||||
{"tid": 1, "ph": "E", "pid": 0, "name": "B", "ts": 2},
|
||||
{"tid": 1, "ph": "E", "pid": 0, "name": "A", "ts": 3},
|
||||
{"tid": 1, "ph": "B", "pid": 0, "name": "A", "ts": 4},
|
||||
{"tid": 1, "ph": "B", "pid": 0, "name": "B", "ts": 5},
|
||||
{"tid": 1, "ph": "B", "pid": 0, "name": "C", "ts": 6},
|
||||
{"tid": 1, "ph": "E", "pid": 0, "name": "C", "ts": 7},
|
||||
{"tid": 1, "ph": "E", "pid": 0, "name": "B", "ts": 7},
|
||||
{"tid": 1, "ph": "E", "pid": 0, "name": "A", "ts": 7},
|
||||
{"tid": 1, "ph": "B", "pid": 0, "name": "X", "ts": 7},
|
||||
{"tid": 1, "ph": "E", "pid": 0, "name": "X", "ts": 10}
|
||||
]
|
||||
@@ -0,0 +1,5 @@
|
||||
[
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "A", "args": {"x": 1}, "ts": 0},
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "A", "args": {"x": 2}, "ts": 1},
|
||||
{"pid": 0, "tid": 0, "ph": "X", "name": "A", "args": {"x": 1}, "ts": 10, "dur": 1}
|
||||
]
|
||||
@@ -0,0 +1,5 @@
|
||||
[
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "A", "args": {"x": 1}, "ts": 0},
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "B", "args": {"x": 2}, "ts": 1},
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "C", "args": {"x": 2}, "ts": 2}
|
||||
]
|
||||
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "alpha", "ts": 9},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "beta", "ts": 10},
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "alpha", "ts": 0},
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "beta", "ts": 1}
|
||||
]
|
||||
@@ -0,0 +1,10 @@
|
||||
[
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "B", "ts": 1},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "B", "ts": 9},
|
||||
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "A", "ts": 0},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "A", "ts": 10},
|
||||
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "C", "ts": 2},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "C", "ts": 8}
|
||||
]
|
||||
@@ -0,0 +1,7 @@
|
||||
[
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "alpha", "ts": 0},
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "beta", "ts": 1},
|
||||
{"pid": 0, "tid": 0, "ph": "X", "name": "gamma", "ts": 2, "dur": 5, "args": {"detail": "foobar"}},
|
||||
{"pid": 0, "tid": 0, "ph": "X", "name": "epsilon", "ts": 7, "tdur": 4},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "beta", "ts": 13},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "alpha", "ts": 14},
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
[
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "alpha", "ts": 0},
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "beta", "ts": 1},
|
||||
{"pid": 0, "tid": 0, "ph": "X", "name": "gamma", "ts": 2, "dur": 5, "args": {"detail": "foobar"}},
|
||||
{"pid": 0, "tid": 0, "ph": "X", "name": "epsilon", "ts": 7, "tdur": 4},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "beta", "ts": 13},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "alpha", "ts": 14},
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
[
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "alpha", "ts": 0},
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "beta", "ts": 1},
|
||||
{"pid": 0, "tid": 0, "ph": "X", "name": "gamma", "ts": 2, "dur": 5, "args": {"detail": "foobar"}},
|
||||
{"pid": 0, "tid": 0, "ph": "X", "name": "epsilon", "ts": 7, "tdur": 4},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "beta", "ts": 13},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "alpha", "ts": 14}
|
||||
@@ -0,0 +1,8 @@
|
||||
[
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "alpha", "ts": 0},
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "beta", "ts": 1},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "beta", "ts": 13},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "alpha", "ts": 14},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "gamma", "ts": 5},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "delta", "ts": 5}
|
||||
]
|
||||
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "A", "args": {"x": 1}, "ts": 0},
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "A", "args": {"x": 2}, "ts": 1},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "A", "args": {"x": 1}, "ts": 9},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "A", "args": {"x": 2}, "ts": 10}
|
||||
]
|
||||
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "alpha", "ts": 0},
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "beta", "ts": 1},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "alpha", "ts": 9},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "beta", "ts": 10}
|
||||
]
|
||||
@@ -0,0 +1,15 @@
|
||||
[
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 0, "dur": 20, "name": "alpha" },
|
||||
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 1, "dur": 2, "name": "beta" },
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 2, "dur": 1, "name": "gamma" },
|
||||
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 5, "dur": 2, "name": "gamma" },
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 6, "dur": 1, "name": "beta" },
|
||||
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 10, "dur": 1, "name": "gamma" },
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 9, "dur": 2, "name": "beta" },
|
||||
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 15, "dur": 1, "name": "beta" },
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 14, "dur": 2, "name": "gamma" }
|
||||
]
|
||||
@@ -0,0 +1,15 @@
|
||||
[
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 0, "dur": 20, "name": "alpha" },
|
||||
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 1, "dur": 2, "name": "beta" },
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 1, "dur": 1, "name": "gamma" },
|
||||
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 5, "dur": 2, "name": "gamma" },
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 5, "dur": 1, "name": "beta" },
|
||||
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 9, "dur": 1, "name": "beta" },
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 9, "dur": 2, "name": "gamma" },
|
||||
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 13, "dur": 1, "name": "gamma" },
|
||||
{ "pid": 0, "tid": 0, "ph": "X", "ts": 13, "dur": 2, "name": "beta" }
|
||||
]
|
||||
@@ -0,0 +1,9 @@
|
||||
[
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "A", "ts": 0},
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "B", "ts": 1},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "B", "ts": 1},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "C", "ts": 2},
|
||||
{"pid": 0, "tid": 0, "ph": "B", "name": "C", "ts": 2},
|
||||
{"pid": 0, "tid": 0, "ph": "X", "name": "D", "ts": 3, "dur": 0},
|
||||
{"pid": 0, "tid": 0, "ph": "E", "name": "A", "ts": 10}
|
||||
]
|
||||
@@ -0,0 +1,22 @@
|
||||
## Source Map Test Project
|
||||
|
||||
This directory contains test files used to test whether the remapping of
|
||||
performance profiles using sourcemaps work correctly.
|
||||
|
||||
Run `npm run build` to build the artifacts, then open the appropriate files in
|
||||
the `html` directory in whatever browser you're testing.
|
||||
|
||||
The idea is to sourcemaps generated by a variety of tools, and also to take
|
||||
profiles from a variety of browsers, and hopefully see that they all get
|
||||
remapped as expected.
|
||||
|
||||
This project is set up to go through three levels of source-map indirection,
|
||||
and also using multiple different build chains.
|
||||
|
||||
1. TypeScript -> JavaScript source generation
|
||||
2. JavaScript source -> JavaScript bundling
|
||||
3. Minification
|
||||
|
||||
Some bundlers will swap the order of steps 2 & 3, or potentially merge them,
|
||||
but it's complex yet realistic enough that this will hoepfully suss out
|
||||
problems.
|
||||
@@ -0,0 +1,11 @@
|
||||
import {beta} from './beta'
|
||||
import {delta} from './delta'
|
||||
|
||||
export function alpha() {
|
||||
;(function () {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
beta()
|
||||
delta()
|
||||
}
|
||||
})()
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import {gamma} from './gamma'
|
||||
|
||||
export function beta() {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
gamma()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import {gamma} from './gamma'
|
||||
|
||||
export const delta = function () {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
gamma()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export const gamma = () => {
|
||||
let prod = 1
|
||||
for (let i = 1; i < 1000; i++) {
|
||||
prod *= i
|
||||
}
|
||||
return prod
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<title>ESbuild</title>
|
||||
<script src="../dist/esbuild/typescript-source-map-test.js"></script>
|
||||
<h1>ESbuild Source Map Test</h1>
|
||||
@@ -0,0 +1,3 @@
|
||||
<title>Parcel</title>
|
||||
<script src="../dist/parcel/typescript-source-map-test.js"></script>
|
||||
<h1>Parcel Source Map Test</h1>
|
||||
@@ -0,0 +1,3 @@
|
||||
<title>Webpack</title>
|
||||
<script src="../dist/webpack/typescript-source-map-test.js"></script>
|
||||
<h1>Webpack Source Map Test</h1>
|
||||
@@ -0,0 +1,17 @@
|
||||
import {alpha} from './alpha'
|
||||
|
||||
export class Kludge {
|
||||
constructor() {
|
||||
alpha()
|
||||
console.log(this.floop)
|
||||
}
|
||||
|
||||
zap() {
|
||||
alpha()
|
||||
}
|
||||
|
||||
get floop(): number {
|
||||
alpha()
|
||||
return 1
|
||||
}
|
||||
}
|
||||
+10497
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "speedscope-sourcemap-test-project",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"private": "true",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "npm run parcel && npm run webpack && npm run esbuild",
|
||||
"parcel": "parcel build -o parcel/typescript-source-map-test typescript-source-map-test.ts",
|
||||
"webpack": "webpack",
|
||||
"esbuild": "esbuild --sourcemap --minify --bundle --outdir=dist/esbuild typescript-source-map-test.ts"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.7.14",
|
||||
"parcel": "^1.12.4",
|
||||
"ts-loader": "^8.0.4",
|
||||
"typescript": "^4.0.3",
|
||||
"webpack": "^5.0.0",
|
||||
"webpack-cli": "^4.0.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist/",
|
||||
"noImplicitAny": true,
|
||||
"sourceMap": true,
|
||||
"module": "es6",
|
||||
"target": "es5",
|
||||
"jsx": "react"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import {Kludge} from './kludge'
|
||||
|
||||
const k = new Kludge()
|
||||
k.zap()
|
||||
@@ -0,0 +1,22 @@
|
||||
const path = require('path')
|
||||
|
||||
module.exports = {
|
||||
entry: './typescript-source-map-test.ts',
|
||||
devtool: 'source-map',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.tsx', '.ts', '.js'],
|
||||
},
|
||||
output: {
|
||||
filename: 'typescript-source-map-test.js',
|
||||
path: path.resolve(__dirname, 'dist', 'webpack'),
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
require 'json'
|
||||
require 'stackprof'
|
||||
|
||||
def a
|
||||
for i in 0..2 do
|
||||
b
|
||||
c
|
||||
end
|
||||
end
|
||||
|
||||
def b
|
||||
Object.new
|
||||
end
|
||||
|
||||
def c
|
||||
for i in 0..5
|
||||
(1..10).to_a.sample(3).sort
|
||||
end
|
||||
end
|
||||
|
||||
profile = StackProf.run(mode: :object, raw: true) do
|
||||
a
|
||||
end
|
||||
|
||||
puts JSON.generate(profile)
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
npm run typecheck
|
||||
npm run lint
|
||||
npm run coverage
|
||||
node scripts/generate-file-format-schema-json.js > /dev/null
|
||||
+1
-1
@@ -58,5 +58,5 @@ echo "Build complete. Starting server on http://localhost:4444/"
|
||||
echo "Hit Ctrl+C to complete or cancel the release"
|
||||
echo
|
||||
echo
|
||||
python -m SimpleHTTPServer 4444 .
|
||||
python3 -m http.server 4444
|
||||
set +x
|
||||
|
||||
@@ -3,7 +3,7 @@ const child_process = require('child_process')
|
||||
|
||||
// Convert the file-format-spec.ts file into a json schema file
|
||||
let jsonSchema = child_process.execSync(
|
||||
'node_modules/.bin/quicktype --lang schema ./src/lib/file-format-spec.ts',
|
||||
'node_modules/.bin/typescript-json-schema ./src/lib/file-format-spec.ts --titles --required --topRef "*"',
|
||||
{
|
||||
encoding: 'utf8',
|
||||
},
|
||||
|
||||
+6
-6
@@ -4,10 +4,10 @@ This directory contains the bulk of speedscope's source code.
|
||||
|
||||
## Subdirectories
|
||||
|
||||
* `gl/`: WebGL code. This includes e.g. the code to render flamecharts.
|
||||
* `import/`: Code to import profiles from varous profilers into speedscope. This include e.g. the code to import Chrome performance profiles.
|
||||
* `lib/`: Mostly dependency-less utilities. This includes e.g. an LRU cache implementation, basic linear algebra classes,
|
||||
- `gl/`: WebGL code. This includes e.g. the code to render flamecharts.
|
||||
- `import/`: Code to import profiles from varous profilers into speedscope. This include e.g. the code to import Chrome performance profiles.
|
||||
- `lib/`: Mostly dependency-less utilities. This includes e.g. an LRU cache implementation, basic linear algebra classes,
|
||||
and the definition of speedscope's file format.
|
||||
* `store/`: Speedscope's application state management. Implemented using [`redux`](https://redux.js.org/).
|
||||
* `typings/`: [TypeScript definition files](https://basarat.gitbooks.io/typescript/docs/types/ambient/d.ts.html)
|
||||
* `views/`: View code to generate the HTML & CSS used to construct the UI. Implemented using [`preact`](https://preactjs.com/) and [`aphrodite`](https://github.com/Khan/aphrodite). Also contains code mapping from the `redux` store to views using [`preact-redux`](https://github.com/developit/preact-redux)
|
||||
- `app-state/`: Speedscope's application state management
|
||||
- `typings/`: [TypeScript definition files](https://basarat.gitbooks.io/typescript/docs/types/ambient/d.ts.html)
|
||||
- `views/`: View code to generate the HTML & CSS used to construct the UI. Implemented using [`preact`](https://preactjs.com/) and [`aphrodite`](https://github.com/Khan/aphrodite).
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import {Profile} from '../lib/profile'
|
||||
import {getProfileToView} from './getters'
|
||||
import {flattenRecursionAtom, profileGroupAtom} from '.'
|
||||
import {FlamechartViewState, SandwichViewState} from './profile-group'
|
||||
import {useAtom} from '../lib/atom'
|
||||
|
||||
export interface ApplicationState {}
|
||||
|
||||
export interface ActiveProfileState {
|
||||
profile: Profile
|
||||
index: number
|
||||
chronoViewState: FlamechartViewState
|
||||
leftHeavyViewState: FlamechartViewState
|
||||
sandwichViewState: SandwichViewState
|
||||
}
|
||||
|
||||
export function useActiveProfileState(): ActiveProfileState | null {
|
||||
const flattenRecursion = useAtom(flattenRecursionAtom)
|
||||
const profileGroupState = useAtom(profileGroupAtom)
|
||||
|
||||
if (!profileGroupState) return null
|
||||
if (profileGroupState.indexToView >= profileGroupState.profiles.length) return null
|
||||
|
||||
const index = profileGroupState.indexToView
|
||||
const profileState = profileGroupState.profiles[index]
|
||||
return {
|
||||
...profileGroupState.profiles[profileGroupState.indexToView],
|
||||
profile: getProfileToView({
|
||||
profile: profileState.profile,
|
||||
flattenRecursion,
|
||||
}),
|
||||
index: profileGroupState.indexToView,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
import {Atom} from '../lib/atom'
|
||||
|
||||
export const enum ColorScheme {
|
||||
// Default: respect prefers-color-schema
|
||||
SYSTEM,
|
||||
|
||||
// Use dark theme
|
||||
DARK,
|
||||
|
||||
// use light theme
|
||||
LIGHT,
|
||||
}
|
||||
|
||||
const localStorageKey = 'speedscope-color-scheme'
|
||||
|
||||
function getStoredPreference(): ColorScheme {
|
||||
const storedPreference = window.localStorage && window.localStorage[localStorageKey]
|
||||
if (storedPreference === 'DARK') {
|
||||
return ColorScheme.DARK
|
||||
} else if (storedPreference === 'LIGHT') {
|
||||
return ColorScheme.LIGHT
|
||||
} else {
|
||||
return ColorScheme.SYSTEM
|
||||
}
|
||||
}
|
||||
|
||||
function matchMediaDarkColorScheme(): MediaQueryList {
|
||||
return matchMedia('(prefers-color-scheme: dark)')
|
||||
}
|
||||
|
||||
function nextColorScheme(scheme: ColorScheme): ColorScheme {
|
||||
const systemPrefersDarkMode = matchMediaDarkColorScheme().matches
|
||||
|
||||
// We'll use a different cycling order for changing the color scheme depending
|
||||
// on what the *current* system preference is. This should guarantee that when
|
||||
// a user interacts with the color scheme toggle for the first time, it always
|
||||
// changes the color scheme.
|
||||
if (systemPrefersDarkMode) {
|
||||
switch (scheme) {
|
||||
case ColorScheme.SYSTEM: {
|
||||
return ColorScheme.LIGHT
|
||||
}
|
||||
case ColorScheme.LIGHT: {
|
||||
return ColorScheme.DARK
|
||||
}
|
||||
case ColorScheme.DARK: {
|
||||
return ColorScheme.SYSTEM
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (scheme) {
|
||||
case ColorScheme.SYSTEM: {
|
||||
return ColorScheme.DARK
|
||||
}
|
||||
case ColorScheme.DARK: {
|
||||
return ColorScheme.LIGHT
|
||||
}
|
||||
case ColorScheme.LIGHT: {
|
||||
return ColorScheme.SYSTEM
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ColorSchemeAtom extends Atom<ColorScheme> {
|
||||
cycleToNextColorScheme = () => {
|
||||
this.set(nextColorScheme(this.get()))
|
||||
}
|
||||
}
|
||||
|
||||
export const colorSchemeAtom = new ColorSchemeAtom(getStoredPreference(), 'colorScheme')
|
||||
|
||||
colorSchemeAtom.subscribe(() => {
|
||||
const value = colorSchemeAtom.get()
|
||||
|
||||
switch (value) {
|
||||
case ColorScheme.DARK: {
|
||||
window.localStorage[localStorageKey] = 'DARK'
|
||||
break
|
||||
}
|
||||
case ColorScheme.LIGHT: {
|
||||
window.localStorage[localStorageKey] = 'LIGHT'
|
||||
break
|
||||
}
|
||||
case ColorScheme.SYSTEM: {
|
||||
delete window.localStorage[localStorageKey]
|
||||
break
|
||||
}
|
||||
default: {
|
||||
const _exhaustiveCheck: never = value
|
||||
return _exhaustiveCheck
|
||||
}
|
||||
}
|
||||
return value
|
||||
})
|
||||
@@ -0,0 +1,69 @@
|
||||
import {Frame, Profile} from '../lib/profile'
|
||||
import {memoizeByReference, memoizeByShallowEquality} from '../lib/utils'
|
||||
import {RowAtlas} from '../gl/row-atlas'
|
||||
import {CanvasContext} from '../gl/canvas-context'
|
||||
import {FlamechartRowAtlasKey} from '../gl/flamechart-renderer'
|
||||
import {Theme} from '../views/themes/theme'
|
||||
|
||||
export const createGetColorBucketForFrame = memoizeByReference(
|
||||
(frameToColorBucket: Map<number | string, number>) => {
|
||||
return (frame: Frame): number => {
|
||||
return frameToColorBucket.get(frame.key) || 0
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
export const createGetCSSColorForFrame = memoizeByShallowEquality(
|
||||
({
|
||||
theme,
|
||||
frameToColorBucket,
|
||||
}: {
|
||||
theme: Theme
|
||||
frameToColorBucket: Map<number | string, number>
|
||||
}) => {
|
||||
const getColorBucketForFrame = createGetColorBucketForFrame(frameToColorBucket)
|
||||
return (frame: Frame): string => {
|
||||
const t = getColorBucketForFrame(frame) / 255
|
||||
return theme.colorForBucket(t).toCSS()
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
export const getCanvasContext = memoizeByShallowEquality(
|
||||
({theme, canvas}: {theme: Theme; canvas: HTMLCanvasElement}) => {
|
||||
return new CanvasContext(canvas, theme)
|
||||
},
|
||||
)
|
||||
|
||||
export const getRowAtlas = memoizeByReference((canvasContext: CanvasContext) => {
|
||||
return new RowAtlas<FlamechartRowAtlasKey>(
|
||||
canvasContext.gl,
|
||||
canvasContext.rectangleBatchRenderer,
|
||||
canvasContext.textureRenderer,
|
||||
)
|
||||
})
|
||||
|
||||
export const getProfileToView = memoizeByShallowEquality(
|
||||
({profile, flattenRecursion}: {profile: Profile; flattenRecursion: boolean}): Profile => {
|
||||
return flattenRecursion ? profile.getProfileWithRecursionFlattened() : profile
|
||||
},
|
||||
)
|
||||
export const getFrameToColorBucket = memoizeByReference(
|
||||
(profile: Profile): Map<string | number, number> => {
|
||||
const frames: Frame[] = []
|
||||
profile.forEachFrame(f => frames.push(f))
|
||||
function key(f: Frame) {
|
||||
return (f.file || '') + f.name
|
||||
}
|
||||
function compare(a: Frame, b: Frame) {
|
||||
return key(a) > key(b) ? 1 : -1
|
||||
}
|
||||
frames.sort(compare)
|
||||
const frameToColorBucket = new Map<string | number, number>()
|
||||
for (let i = 0; i < frames.length; i++) {
|
||||
frameToColorBucket.set(frames[i].key, Math.floor((255 * i) / frames.length))
|
||||
}
|
||||
|
||||
return frameToColorBucket
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,78 @@
|
||||
import {Atom} from '../lib/atom'
|
||||
import {ViewMode} from '../lib/view-mode'
|
||||
import {getHashParams, HashParams} from '../lib/hash-params'
|
||||
import {ProfileGroupAtom} from './profile-group'
|
||||
|
||||
// True if recursion should be flattened when viewing flamegraphs
|
||||
export const flattenRecursionAtom = new Atom<boolean>(false, 'flattenRecursion')
|
||||
|
||||
// The query used in top-level views
|
||||
//
|
||||
// An empty string indicates that the search is open by no filter is applied.
|
||||
// searchIsActive is stored separately, because we may choose to persist the
|
||||
// query even when the search input is closed.
|
||||
export const searchIsActiveAtom = new Atom<boolean>(false, 'searchIsActive')
|
||||
export const searchQueryAtom = new Atom<string>('', 'searchQueryAtom')
|
||||
|
||||
// Which top-level view should be displayed
|
||||
export const viewModeAtom = new Atom<ViewMode>(ViewMode.CHRONO_FLAME_CHART, 'viewMode')
|
||||
|
||||
// The top-level profile group from which most other data will be derived
|
||||
export const profileGroupAtom = new ProfileGroupAtom(null, 'profileGroup')
|
||||
|
||||
viewModeAtom.subscribe(() => {
|
||||
// If we switch views, the hover information is no longer relevant
|
||||
profileGroupAtom.clearHoverNode()
|
||||
})
|
||||
|
||||
// Parameters defined by the URL encoded k=v pairs after the # in the URL
|
||||
const hashParams = getHashParams()
|
||||
export const hashParamsAtom = new Atom<HashParams>(hashParams, 'hashParams')
|
||||
|
||||
// The <canvas> element used for WebGL
|
||||
export const glCanvasAtom = new Atom<HTMLCanvasElement | null>(null, 'glCanvas')
|
||||
|
||||
// True when a file drag is currently active. Used to indicate that the
|
||||
// application is a valid drop target.
|
||||
export const dragActiveAtom = new Atom<boolean>(false, 'dragActive')
|
||||
|
||||
// True when the application is currently in a loading state. Used to
|
||||
// display a loading progress bar.
|
||||
|
||||
// Speedscope is usable both from a local HTML file being served
|
||||
// from a file:// URL, and via websites. In the case of file:// URLs,
|
||||
// however, XHR will be unavailable to fetching files in adjacent directories.
|
||||
const protocol = window.location.protocol
|
||||
export const canUseXHR = protocol === 'http:' || protocol === 'https:'
|
||||
const isImmediatelyLoading = canUseXHR && hashParams.profileURL != null
|
||||
export const loadingAtom = new Atom<boolean>(isImmediatelyLoading, 'loading')
|
||||
|
||||
// True when the application is an error state, e.g. because the profile
|
||||
// imported was invalid.
|
||||
export const errorAtom = new Atom<boolean>(false, 'error')
|
||||
|
||||
export enum SortField {
|
||||
SYMBOL_NAME,
|
||||
SELF,
|
||||
TOTAL,
|
||||
}
|
||||
|
||||
export enum SortDirection {
|
||||
ASCENDING,
|
||||
DESCENDING,
|
||||
}
|
||||
|
||||
export interface SortMethod {
|
||||
field: SortField
|
||||
direction: SortDirection
|
||||
}
|
||||
|
||||
// The table sorting method using for the sandwich view, specifying the column
|
||||
// to sort by, and the direction to sort that clumn.
|
||||
export const tableSortMethodAtom = new Atom<SortMethod>(
|
||||
{
|
||||
field: SortField.SELF,
|
||||
direction: SortDirection.DESCENDING,
|
||||
},
|
||||
'tableSortMethod',
|
||||
)
|
||||
@@ -0,0 +1,227 @@
|
||||
import {Atom} from '../lib/atom'
|
||||
import {clamp, Rect, Vec2} from '../lib/math'
|
||||
import {CallTreeNode, Frame, Profile, ProfileGroup} from '../lib/profile'
|
||||
import {objectsHaveShallowEquality} from '../lib/utils'
|
||||
|
||||
export interface FlamechartViewState {
|
||||
hover: {
|
||||
node: CallTreeNode
|
||||
event: MouseEvent
|
||||
} | null
|
||||
selectedNode: CallTreeNode | null
|
||||
logicalSpaceViewportSize: Vec2
|
||||
configSpaceViewportRect: Rect
|
||||
}
|
||||
|
||||
export interface CallerCalleeState {
|
||||
selectedFrame: Frame
|
||||
invertedCallerFlamegraph: FlamechartViewState
|
||||
calleeFlamegraph: FlamechartViewState
|
||||
}
|
||||
|
||||
export interface SandwichViewState {
|
||||
callerCallee: CallerCalleeState | null
|
||||
}
|
||||
|
||||
export interface ProfileState {
|
||||
profile: Profile
|
||||
chronoViewState: FlamechartViewState
|
||||
leftHeavyViewState: FlamechartViewState
|
||||
sandwichViewState: SandwichViewState
|
||||
}
|
||||
|
||||
export type ProfileGroupState = {
|
||||
name: string
|
||||
|
||||
// The index within the list of profiles currently being viewed
|
||||
indexToView: number
|
||||
|
||||
profiles: ProfileState[]
|
||||
} | null
|
||||
|
||||
export enum FlamechartID {
|
||||
LEFT_HEAVY = 'LEFT_HEAVY',
|
||||
CHRONO = 'CHRONO',
|
||||
SANDWICH_INVERTED_CALLERS = 'SANDWICH_INVERTED_CALLERS',
|
||||
SANDWICH_CALLEES = 'SANDWICH_CALLEES',
|
||||
}
|
||||
|
||||
let initialFlameChartViewState: FlamechartViewState = {
|
||||
hover: null,
|
||||
selectedNode: null,
|
||||
configSpaceViewportRect: Rect.empty,
|
||||
logicalSpaceViewportSize: Vec2.zero,
|
||||
}
|
||||
|
||||
export class ProfileGroupAtom extends Atom<ProfileGroupState> {
|
||||
set(newState: ProfileGroupState) {
|
||||
const oldState = this.state
|
||||
if (oldState != null && newState != null && objectsHaveShallowEquality(oldState, newState)) {
|
||||
return
|
||||
}
|
||||
super.set(newState)
|
||||
}
|
||||
|
||||
getActiveProfile(): ProfileState | null {
|
||||
if (this.state == null) return null
|
||||
return this.state.profiles[this.state?.indexToView] || null
|
||||
}
|
||||
|
||||
setProfileGroup = (group: ProfileGroup) => {
|
||||
this.set({
|
||||
name: group.name,
|
||||
indexToView: group.indexToView,
|
||||
profiles: group.profiles.map(p => ({
|
||||
profile: p,
|
||||
chronoViewState: initialFlameChartViewState,
|
||||
leftHeavyViewState: initialFlameChartViewState,
|
||||
sandwichViewState: {callerCallee: null},
|
||||
})),
|
||||
})
|
||||
}
|
||||
|
||||
setProfileIndexToView = (indexToView: number) => {
|
||||
if (this.state == null) return
|
||||
|
||||
indexToView = clamp(indexToView, 0, this.state.profiles.length - 1)
|
||||
|
||||
this.set({
|
||||
...this.state,
|
||||
indexToView,
|
||||
})
|
||||
}
|
||||
|
||||
private updateActiveProfileState(fn: (profileState: ProfileState) => ProfileState) {
|
||||
if (this.state == null) return
|
||||
const {indexToView, profiles} = this.state
|
||||
this.set({
|
||||
...this.state,
|
||||
profiles: profiles.map((p, i) => {
|
||||
if (i != indexToView) return p
|
||||
return fn(p)
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
private updateActiveSandwichViewState(
|
||||
fn: (sandwichViewState: SandwichViewState) => SandwichViewState,
|
||||
) {
|
||||
this.updateActiveProfileState(p => ({
|
||||
...p,
|
||||
sandwichViewState: fn(p.sandwichViewState),
|
||||
}))
|
||||
}
|
||||
|
||||
setSelectedFrame = (frame: Frame | null) => {
|
||||
if (this.state == null) return
|
||||
|
||||
const profile = this.getActiveProfile()
|
||||
if (profile == null) {
|
||||
return
|
||||
}
|
||||
|
||||
this.updateActiveSandwichViewState(sandwichViewState => {
|
||||
if (frame == null) {
|
||||
return {callerCallee: null}
|
||||
}
|
||||
return {
|
||||
callerCallee: {
|
||||
invertedCallerFlamegraph: initialFlameChartViewState,
|
||||
calleeFlamegraph: initialFlameChartViewState,
|
||||
selectedFrame: frame,
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private updateFlamechartState(
|
||||
id: FlamechartID,
|
||||
fn: (flamechartViewState: FlamechartViewState) => FlamechartViewState,
|
||||
) {
|
||||
switch (id) {
|
||||
case FlamechartID.CHRONO: {
|
||||
this.updateActiveProfileState(p => ({
|
||||
...p,
|
||||
chronoViewState: fn(p.chronoViewState),
|
||||
}))
|
||||
break
|
||||
}
|
||||
|
||||
case FlamechartID.LEFT_HEAVY: {
|
||||
this.updateActiveProfileState(p => ({
|
||||
...p,
|
||||
leftHeavyViewState: fn(p.leftHeavyViewState),
|
||||
}))
|
||||
break
|
||||
}
|
||||
|
||||
case FlamechartID.SANDWICH_CALLEES: {
|
||||
this.updateActiveSandwichViewState(s => ({
|
||||
...s,
|
||||
callerCallee:
|
||||
s.callerCallee == null
|
||||
? null
|
||||
: {
|
||||
...s.callerCallee,
|
||||
calleeFlamegraph: fn(s.callerCallee.calleeFlamegraph),
|
||||
},
|
||||
}))
|
||||
break
|
||||
}
|
||||
|
||||
case FlamechartID.SANDWICH_INVERTED_CALLERS: {
|
||||
this.updateActiveSandwichViewState(s => ({
|
||||
...s,
|
||||
callerCallee:
|
||||
s.callerCallee == null
|
||||
? null
|
||||
: {
|
||||
...s.callerCallee,
|
||||
invertedCallerFlamegraph: fn(s.callerCallee.invertedCallerFlamegraph),
|
||||
},
|
||||
}))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setFlamechartHoveredNode(
|
||||
id: FlamechartID,
|
||||
hover: {node: CallTreeNode; event: MouseEvent} | null,
|
||||
) {
|
||||
this.updateFlamechartState(id, f => ({
|
||||
...f,
|
||||
hover,
|
||||
}))
|
||||
}
|
||||
|
||||
setSelectedNode(id: FlamechartID, selectedNode: CallTreeNode | null) {
|
||||
this.updateFlamechartState(id, f => ({
|
||||
...f,
|
||||
selectedNode,
|
||||
}))
|
||||
}
|
||||
|
||||
setConfigSpaceViewportRect(id: FlamechartID, configSpaceViewportRect: Rect) {
|
||||
this.updateFlamechartState(id, f => ({
|
||||
...f,
|
||||
configSpaceViewportRect,
|
||||
}))
|
||||
}
|
||||
|
||||
setLogicalSpaceViewportSize(id: FlamechartID, logicalSpaceViewportSize: Vec2) {
|
||||
this.updateFlamechartState(id, f => ({
|
||||
...f,
|
||||
logicalSpaceViewportSize,
|
||||
}))
|
||||
}
|
||||
|
||||
clearHoverNode() {
|
||||
// TODO(jlfwong): This causes 4 separate observer events. This is probably
|
||||
// fine, since I hope that Preact/React are smart about batching re-renders?
|
||||
this.setFlamechartHoveredNode(FlamechartID.CHRONO, null)
|
||||
this.setFlamechartHoveredNode(FlamechartID.LEFT_HEAVY, null)
|
||||
this.setFlamechartHoveredNode(FlamechartID.SANDWICH_CALLEES, null)
|
||||
this.setFlamechartHoveredNode(FlamechartID.SANDWICH_INVERTED_CALLERS, null)
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import {TextureRenderer} from './texture-renderer'
|
||||
import {Rect, Vec2} from '../lib/math'
|
||||
import {ViewportRectangleRenderer} from './overlay-rectangle-renderer'
|
||||
import {FlamechartColorPassRenderer} from './flamechart-color-pass-renderer'
|
||||
import {Color} from '../lib/color'
|
||||
import {Theme} from '../views/themes/theme'
|
||||
|
||||
type FrameCallback = () => void
|
||||
|
||||
@@ -13,20 +15,24 @@ export class CanvasContext {
|
||||
public readonly textureRenderer: TextureRenderer
|
||||
public readonly viewportRectangleRenderer: ViewportRectangleRenderer
|
||||
public readonly flamechartColorPassRenderer: FlamechartColorPassRenderer
|
||||
public readonly theme: Theme
|
||||
|
||||
constructor(canvas: HTMLCanvasElement) {
|
||||
constructor(canvas: HTMLCanvasElement, theme: Theme) {
|
||||
this.gl = new WebGL.Context(canvas)
|
||||
this.rectangleBatchRenderer = new RectangleBatchRenderer(this.gl)
|
||||
this.textureRenderer = new TextureRenderer(this.gl)
|
||||
this.viewportRectangleRenderer = new ViewportRectangleRenderer(this.gl)
|
||||
this.flamechartColorPassRenderer = new FlamechartColorPassRenderer(this.gl)
|
||||
this.viewportRectangleRenderer = new ViewportRectangleRenderer(this.gl, theme)
|
||||
this.flamechartColorPassRenderer = new FlamechartColorPassRenderer(this.gl, theme)
|
||||
this.theme = theme
|
||||
|
||||
// Whenever the canvas is resized, draw immediately. This prevents
|
||||
// flickering during resizing.
|
||||
this.gl.addAfterResizeEventHandler(this.onBeforeFrame)
|
||||
|
||||
const webGLInfo = this.gl.getWebGLInfo()
|
||||
if (webGLInfo) {
|
||||
console.log(
|
||||
`WebGL initialized. renderer: ${webGLInfo.renderer}, vendor: ${
|
||||
webGLInfo.vendor
|
||||
}, version: ${webGLInfo.version}`,
|
||||
`WebGL initialized. renderer: ${webGLInfo.renderer}, vendor: ${webGLInfo.vendor}, version: ${webGLInfo.version}`,
|
||||
)
|
||||
}
|
||||
;(window as any)['testContextLoss'] = () => {
|
||||
@@ -50,7 +56,8 @@ export class CanvasContext {
|
||||
private onBeforeFrame = () => {
|
||||
this.animationFrameRequest = null
|
||||
this.gl.setViewport(0, 0, this.gl.renderTargetWidthInPixels, this.gl.renderTargetHeightInPixels)
|
||||
this.gl.clear(new Graphics.Color(1, 1, 1, 1))
|
||||
const color = Color.fromCSSHex(this.theme.bgPrimaryColor)
|
||||
this.gl.clear(new Graphics.Color(color.r, color.g, color.b, color.a))
|
||||
|
||||
for (const handler of this.beforeFrameHandlers) {
|
||||
handler()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {Vec2, Rect, AffineTransform} from '../lib/math'
|
||||
import {Theme} from '../views/themes/theme'
|
||||
import {Graphics} from './graphics'
|
||||
import {setUniformAffineTransform} from './utils'
|
||||
|
||||
@@ -20,7 +21,7 @@ const vert = `
|
||||
}
|
||||
`
|
||||
|
||||
const frag = `
|
||||
const frag = (colorForBucket: string) => `
|
||||
precision mediump float;
|
||||
|
||||
uniform vec2 uvSpacePixelSize;
|
||||
@@ -49,13 +50,7 @@ const frag = `
|
||||
return 2.0 * abs(fract(x) - 0.5) - 1.0;
|
||||
}
|
||||
|
||||
vec3 colorForBucket(float t) {
|
||||
float x = triangle(30.0 * t);
|
||||
float H = 360.0 * (0.9 * t);
|
||||
float C = 0.25 + 0.2 * x;
|
||||
float L = 0.80 - 0.15 * x;
|
||||
return hcl2rgb(H, C, L);
|
||||
}
|
||||
${colorForBucket}
|
||||
|
||||
void main() {
|
||||
vec4 here = texture2D(colorTexture, vUv);
|
||||
@@ -107,7 +102,7 @@ export class FlamechartColorPassRenderer {
|
||||
private material: Graphics.Material
|
||||
private buffer: Graphics.VertexBuffer
|
||||
|
||||
constructor(private gl: Graphics.Context) {
|
||||
constructor(private gl: Graphics.Context, theme: Theme) {
|
||||
const vertices = [
|
||||
{pos: [-1, 1], uv: [0, 1]},
|
||||
{pos: [1, 1], uv: [1, 1]},
|
||||
@@ -124,7 +119,7 @@ export class FlamechartColorPassRenderer {
|
||||
|
||||
this.buffer = gl.createVertexBuffer(vertexFormat.stride * vertices.length)
|
||||
this.buffer.uploadFloats(floats)
|
||||
this.material = gl.createMaterial(vertexFormat, vert, frag)
|
||||
this.material = gl.createMaterial(vertexFormat, vert, frag(theme.colorForBucketGLSL))
|
||||
}
|
||||
|
||||
render(props: FlamechartColorPassRenderProps) {
|
||||
|
||||
@@ -175,8 +175,8 @@ export class FlamechartRenderer {
|
||||
// and the blue channel to indicate the color bucket to render.
|
||||
// We add one to each so we have zero reserved for the background color.
|
||||
const color = new Color(
|
||||
(1 + i % 255) / 256,
|
||||
(1 + stackDepth % 255) / 256,
|
||||
(1 + (i % 255)) / 256,
|
||||
(1 + (stackDepth % 255)) / 256,
|
||||
(1 + this.flamechart.getColorBucketForFrame(frame.node.frame)) / 256,
|
||||
)
|
||||
batch.addRect(configSpaceBounds, color)
|
||||
@@ -288,10 +288,10 @@ export class FlamechartRenderer {
|
||||
const configSpaceContentWidth = this.flamechart.getTotalWeight()
|
||||
const numAtlasEntriesPerLayer = Math.pow(2, zoomLevel)
|
||||
const left = Math.floor(
|
||||
numAtlasEntriesPerLayer * configSpaceSrcRect.left() / configSpaceContentWidth,
|
||||
(numAtlasEntriesPerLayer * configSpaceSrcRect.left()) / configSpaceContentWidth,
|
||||
)
|
||||
const right = Math.ceil(
|
||||
numAtlasEntriesPerLayer * configSpaceSrcRect.right() / configSpaceContentWidth,
|
||||
(numAtlasEntriesPerLayer * configSpaceSrcRect.right()) / configSpaceContentWidth,
|
||||
)
|
||||
|
||||
const nLayers = this.flamechart.getLayers().length
|
||||
|
||||
+29
-4
@@ -83,6 +83,15 @@ export namespace Graphics {
|
||||
public alphaF: number,
|
||||
) {}
|
||||
|
||||
equals(other: Color): boolean {
|
||||
return (
|
||||
this.redF === other.redF &&
|
||||
this.greenF === other.greenF &&
|
||||
this.blueF === other.blueF &&
|
||||
this.alphaF === other.alphaF
|
||||
)
|
||||
}
|
||||
|
||||
static TRANSPARENT = new Color(0, 0, 0, 0)
|
||||
}
|
||||
|
||||
@@ -160,6 +169,14 @@ export namespace Graphics {
|
||||
setUnpremultipliedBlendState() {
|
||||
this.setBlendState(BlendOperation.SOURCE_ALPHA, BlendOperation.INVERSE_SOURCE_ALPHA)
|
||||
}
|
||||
|
||||
protected resizeEventHandlers = new Set<() => void>()
|
||||
addAfterResizeEventHandler(callback: () => void): void {
|
||||
this.resizeEventHandlers.add(callback)
|
||||
}
|
||||
removeAfterResizeEventHandler(callback: () => void): void {
|
||||
this.resizeEventHandlers.delete(callback)
|
||||
}
|
||||
}
|
||||
|
||||
export interface Material {
|
||||
@@ -455,10 +472,11 @@ export namespace WebGL {
|
||||
widthInAppUnits: number,
|
||||
heightInAppUnits: number,
|
||||
) {
|
||||
const bounds = this._gl.canvas.getBoundingClientRect()
|
||||
let canvas = this._gl.canvas as HTMLCanvasElement
|
||||
const bounds = canvas.getBoundingClientRect()
|
||||
|
||||
if (
|
||||
this._width === widthInAppUnits &&
|
||||
this._width === widthInPixels &&
|
||||
this._height === heightInPixels &&
|
||||
bounds.width === widthInAppUnits &&
|
||||
bounds.height === heightInAppUnits
|
||||
@@ -467,7 +485,6 @@ export namespace WebGL {
|
||||
return
|
||||
}
|
||||
|
||||
let canvas = this._gl.canvas
|
||||
let style = canvas.style
|
||||
canvas.width = widthInPixels
|
||||
canvas.height = heightInPixels
|
||||
@@ -476,13 +493,15 @@ export namespace WebGL {
|
||||
this.setViewport(0, 0, widthInPixels, heightInPixels)
|
||||
this._width = widthInPixels
|
||||
this._height = heightInPixels
|
||||
|
||||
this.resizeEventHandlers.forEach(cb => cb())
|
||||
}
|
||||
|
||||
clear(color: Graphics.Color) {
|
||||
this._updateRenderTargetAndViewport()
|
||||
this._updateBlendState()
|
||||
|
||||
if (color != this._currentClearColor) {
|
||||
if (!color.equals(this._currentClearColor)) {
|
||||
this._gl.clearColor(color.redF, color.greenF, color.blueF, color.alphaF)
|
||||
this._currentClearColor = color
|
||||
}
|
||||
@@ -1086,11 +1105,17 @@ export namespace WebGL {
|
||||
|
||||
_compileShader(gl: WebGLRenderingContext, type: GLenum, source: string) {
|
||||
let shader = gl.createShader(type)
|
||||
if (!shader) {
|
||||
throw new Error('Failed to create shader')
|
||||
}
|
||||
gl.shaderSource(shader, source)
|
||||
gl.compileShader(shader)
|
||||
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
|
||||
throw new Error(`${gl.getShaderInfoLog(shader)}`)
|
||||
}
|
||||
if (!this._program) {
|
||||
throw new Error('Tried to attach shader before program was created')
|
||||
}
|
||||
gl.attachShader(this._program, shader)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import {Color} from '../lib/color'
|
||||
import {AffineTransform, Rect} from '../lib/math'
|
||||
import {Theme} from '../views/themes/theme'
|
||||
import {Graphics} from './graphics'
|
||||
import {setUniformAffineTransform, setUniformVec2} from './utils'
|
||||
|
||||
@@ -18,54 +20,63 @@ const vert = `
|
||||
}
|
||||
`
|
||||
|
||||
const frag = `
|
||||
precision mediump float;
|
||||
const frag = (theme: Theme) => {
|
||||
const {r, g, b} = Color.fromCSSHex(theme.fgSecondaryColor)
|
||||
const rgb = `${r.toFixed(1)}, ${g.toFixed(1)}, ${b.toFixed(1)}`
|
||||
return `
|
||||
precision mediump float;
|
||||
|
||||
uniform mat3 configSpaceToPhysicalViewSpace;
|
||||
uniform vec2 physicalSize;
|
||||
uniform vec2 physicalOrigin;
|
||||
uniform vec2 configSpaceViewportOrigin;
|
||||
uniform vec2 configSpaceViewportSize;
|
||||
uniform float framebufferHeight;
|
||||
uniform mat3 configSpaceToPhysicalViewSpace;
|
||||
uniform vec2 physicalSize;
|
||||
uniform vec2 physicalOrigin;
|
||||
uniform vec2 configSpaceViewportOrigin;
|
||||
uniform vec2 configSpaceViewportSize;
|
||||
uniform float framebufferHeight;
|
||||
|
||||
void main() {
|
||||
vec2 origin = (configSpaceToPhysicalViewSpace * vec3(configSpaceViewportOrigin, 1.0)).xy;
|
||||
vec2 size = (configSpaceToPhysicalViewSpace * vec3(configSpaceViewportSize, 0.0)).xy;
|
||||
void main() {
|
||||
vec2 origin = (configSpaceToPhysicalViewSpace * vec3(configSpaceViewportOrigin, 1.0)).xy;
|
||||
vec2 size = (configSpaceToPhysicalViewSpace * vec3(configSpaceViewportSize, 0.0)).xy;
|
||||
|
||||
vec2 halfSize = physicalSize / 2.0;
|
||||
vec2 halfSize = physicalSize / 2.0;
|
||||
|
||||
float borderWidth = 2.0;
|
||||
float borderWidth = 2.0;
|
||||
|
||||
origin = floor(origin * halfSize) / halfSize + borderWidth * vec2(1.0, 1.0);
|
||||
size = floor(size * halfSize) / halfSize - 2.0 * borderWidth * vec2(1.0, 1.0);
|
||||
origin = floor(origin * halfSize) / halfSize + borderWidth * vec2(1.0, 1.0);
|
||||
size = floor(size * halfSize) / halfSize - 2.0 * borderWidth * vec2(1.0, 1.0);
|
||||
|
||||
vec2 coord = gl_FragCoord.xy;
|
||||
coord.x = coord.x - physicalOrigin.x;
|
||||
coord.y = framebufferHeight - coord.y - physicalOrigin.y;
|
||||
vec2 clamped = clamp(coord, origin, origin + size);
|
||||
vec2 gap = clamped - coord;
|
||||
float maxdist = max(abs(gap.x), abs(gap.y));
|
||||
vec2 coord = gl_FragCoord.xy;
|
||||
coord.x = coord.x - physicalOrigin.x;
|
||||
coord.y = framebufferHeight - coord.y - physicalOrigin.y;
|
||||
vec2 clamped = clamp(coord, origin, origin + size);
|
||||
vec2 gap = clamped - coord;
|
||||
float maxdist = max(abs(gap.x), abs(gap.y));
|
||||
|
||||
// TOOD(jlfwong): Could probably optimize this to use mix somehow.
|
||||
if (maxdist == 0.0) {
|
||||
// Inside viewport rectangle
|
||||
gl_FragColor = vec4(0, 0, 0, 0);
|
||||
} else if (maxdist < borderWidth) {
|
||||
// Inside viewport rectangle at border
|
||||
gl_FragColor = vec4(0.7, 0.7, 0.7, 0.8);
|
||||
} else {
|
||||
// Outside viewport rectangle
|
||||
gl_FragColor = vec4(0.7, 0.7, 0.7, 0.5);
|
||||
// TOOD(jlfwong): Could probably optimize this to use mix somehow.
|
||||
if (maxdist == 0.0) {
|
||||
// Inside viewport rectangle
|
||||
gl_FragColor = vec4(0, 0, 0, 0);
|
||||
} else if (maxdist < borderWidth) {
|
||||
// Inside viewport rectangle at border
|
||||
gl_FragColor = vec4(${rgb}, 0.8);
|
||||
} else {
|
||||
// Outside viewport rectangle
|
||||
gl_FragColor = vec4(${rgb}, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
`
|
||||
}
|
||||
|
||||
export class ViewportRectangleRenderer {
|
||||
private material: Graphics.Material
|
||||
private buffer: Graphics.VertexBuffer
|
||||
|
||||
constructor(private gl: Graphics.Context) {
|
||||
const vertices = [[-1, 1], [1, 1], [-1, -1], [1, -1]]
|
||||
constructor(private gl: Graphics.Context, theme: Theme) {
|
||||
const vertices = [
|
||||
[-1, 1],
|
||||
[1, 1],
|
||||
[-1, -1],
|
||||
[1, -1],
|
||||
]
|
||||
const floats: number[] = []
|
||||
for (let v of vertices) {
|
||||
floats.push(v[0])
|
||||
@@ -73,7 +84,7 @@ export class ViewportRectangleRenderer {
|
||||
}
|
||||
this.buffer = gl.createVertexBuffer(vertexFormat.stride * vertices.length)
|
||||
this.buffer.upload(new Uint8Array(new Float32Array(floats).buffer))
|
||||
this.material = gl.createMaterial(vertexFormat, vert, frag)
|
||||
this.material = gl.createMaterial(vertexFormat, vert, frag(theme))
|
||||
}
|
||||
|
||||
render(props: ViewportRectangleRendererProps) {
|
||||
|
||||
@@ -45,7 +45,14 @@ export class RectangleBatch {
|
||||
return this.buffer
|
||||
}
|
||||
|
||||
const corners = [[0, 0], [1, 0], [0, 1], [1, 0], [0, 1], [1, 1]]
|
||||
const corners = [
|
||||
[0, 0],
|
||||
[1, 0],
|
||||
[0, 1],
|
||||
[1, 0],
|
||||
[0, 1],
|
||||
[1, 1],
|
||||
]
|
||||
|
||||
const bytes = new Uint8Array(vertexFormat.stride * corners.length * this.rects.length)
|
||||
const floats = new Float32Array(bytes.buffer)
|
||||
|
||||
@@ -104,6 +104,168 @@ exports[`importFromBGFlameGraph with CRLF: indexToView 1`] = `0`;
|
||||
|
||||
exports[`importFromBGFlameGraph with CRLF: profileGroup.name 1`] = `"simple-crlf.txt"`;
|
||||
|
||||
exports[`importFromBGFlameGraph with UTF-16, Big Endian 1`] = `
|
||||
Object {
|
||||
"frames": Array [
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": undefined,
|
||||
"key": "a",
|
||||
"line": undefined,
|
||||
"name": "a",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 14,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": undefined,
|
||||
"key": "b",
|
||||
"line": undefined,
|
||||
"name": "b",
|
||||
"selfWeight": 5,
|
||||
"totalWeight": 14,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": undefined,
|
||||
"key": "c",
|
||||
"line": undefined,
|
||||
"name": "c",
|
||||
"selfWeight": 5,
|
||||
"totalWeight": 5,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": undefined,
|
||||
"key": "d",
|
||||
"line": undefined,
|
||||
"name": "d",
|
||||
"selfWeight": 4,
|
||||
"totalWeight": 4,
|
||||
},
|
||||
],
|
||||
"name": "simple-utf16-be.txt",
|
||||
"stacks": Array [
|
||||
"a;b;c 2",
|
||||
"a;b;d 4",
|
||||
"a;b;c 3",
|
||||
"a;b 5",
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`importFromBGFlameGraph with UTF-16, Big Endian: indexToView 1`] = `0`;
|
||||
|
||||
exports[`importFromBGFlameGraph with UTF-16, Big Endian: profileGroup.name 1`] = `"simple-utf16-be.txt"`;
|
||||
|
||||
exports[`importFromBGFlameGraph with UTF-16, Little Endian 1`] = `
|
||||
Object {
|
||||
"frames": Array [
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": undefined,
|
||||
"key": "a",
|
||||
"line": undefined,
|
||||
"name": "a",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 14,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": undefined,
|
||||
"key": "b",
|
||||
"line": undefined,
|
||||
"name": "b",
|
||||
"selfWeight": 5,
|
||||
"totalWeight": 14,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": undefined,
|
||||
"key": "c",
|
||||
"line": undefined,
|
||||
"name": "c",
|
||||
"selfWeight": 5,
|
||||
"totalWeight": 5,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": undefined,
|
||||
"key": "d",
|
||||
"line": undefined,
|
||||
"name": "d",
|
||||
"selfWeight": 4,
|
||||
"totalWeight": 4,
|
||||
},
|
||||
],
|
||||
"name": "simple-utf16-le.txt",
|
||||
"stacks": Array [
|
||||
"a;b;c 2",
|
||||
"a;b;d 4",
|
||||
"a;b;c 3",
|
||||
"a;b 5",
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`importFromBGFlameGraph with UTF-16, Little Endian: indexToView 1`] = `0`;
|
||||
|
||||
exports[`importFromBGFlameGraph with UTF-16, Little Endian: profileGroup.name 1`] = `"simple-utf16-le.txt"`;
|
||||
|
||||
exports[`importFromBGFlameGraph with invalid lines 1`] = `
|
||||
Object {
|
||||
"frames": Array [
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": undefined,
|
||||
"key": "a",
|
||||
"line": undefined,
|
||||
"name": "a",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 14,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": undefined,
|
||||
"key": "b",
|
||||
"line": undefined,
|
||||
"name": "b",
|
||||
"selfWeight": 5,
|
||||
"totalWeight": 14,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": undefined,
|
||||
"key": "c",
|
||||
"line": undefined,
|
||||
"name": "c",
|
||||
"selfWeight": 5,
|
||||
"totalWeight": 5,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": undefined,
|
||||
"key": "d",
|
||||
"line": undefined,
|
||||
"name": "d",
|
||||
"selfWeight": 4,
|
||||
"totalWeight": 4,
|
||||
},
|
||||
],
|
||||
"name": "simple-with-invalids.txt",
|
||||
"stacks": Array [
|
||||
"a;b;c 2",
|
||||
"a;b;d 4",
|
||||
"a;b;c 3",
|
||||
"a;b 5",
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`importFromBGFlameGraph with invalid lines: indexToView 1`] = `0`;
|
||||
|
||||
exports[`importFromBGFlameGraph with invalid lines: profileGroup.name 1`] = `"simple-with-invalids.txt"`;
|
||||
|
||||
exports[`importFromBGFlameGraph: indexToView 1`] = `0`;
|
||||
|
||||
exports[`importFromBGFlameGraph: profileGroup.name 1`] = `"simple.txt"`;
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`importFromCallgrind 1`] = `
|
||||
Object {
|
||||
"frames": Array [
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "file1.c",
|
||||
"key": "file1.c:main",
|
||||
"line": undefined,
|
||||
"name": "main",
|
||||
"selfWeight": 20,
|
||||
"totalWeight": 820,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "file1.c",
|
||||
"key": "file1.c:func1",
|
||||
"line": undefined,
|
||||
"name": "func1",
|
||||
"selfWeight": 100,
|
||||
"totalWeight": 400,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "file2.c",
|
||||
"key": "file2.c:func2",
|
||||
"line": undefined,
|
||||
"name": "func2",
|
||||
"selfWeight": 700,
|
||||
"totalWeight": 700,
|
||||
},
|
||||
],
|
||||
"name": "callgrind.example.log -- Instructions",
|
||||
"stacks": Array [
|
||||
"main;func1;func2 300",
|
||||
"main;func1 100",
|
||||
"main;func2 400",
|
||||
"main 20",
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`importFromCallgrind multiple event types 1`] = `
|
||||
Object {
|
||||
"frames": Array [
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "file1.c",
|
||||
"key": "file1.c:main",
|
||||
"line": undefined,
|
||||
"name": "main",
|
||||
"selfWeight": 200,
|
||||
"totalWeight": 8200,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "file1.c",
|
||||
"key": "file1.c:func1",
|
||||
"line": undefined,
|
||||
"name": "func1",
|
||||
"selfWeight": 1000,
|
||||
"totalWeight": 4000,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "file2.c",
|
||||
"key": "file2.c:func2",
|
||||
"line": undefined,
|
||||
"name": "func2",
|
||||
"selfWeight": 7000,
|
||||
"totalWeight": 7000,
|
||||
},
|
||||
],
|
||||
"name": "callgrind.multiple-event-types.log -- Time",
|
||||
"stacks": Array [
|
||||
"main;func1;func2 3.00µs",
|
||||
"main;func1 1.00µs",
|
||||
"main;func2 4.00µs",
|
||||
"main 200.00ns",
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`importFromCallgrind multiple event types 2`] = `
|
||||
Object {
|
||||
"frames": Array [
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "file1.c",
|
||||
"key": "file1.c:main",
|
||||
"line": undefined,
|
||||
"name": "main",
|
||||
"selfWeight": 15000,
|
||||
"totalWeight": 38000,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "file1.c",
|
||||
"key": "file1.c:func1",
|
||||
"line": undefined,
|
||||
"name": "func1",
|
||||
"selfWeight": 8888.888888888889,
|
||||
"totalWeight": 20000,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "file2.c",
|
||||
"key": "file2.c:func2",
|
||||
"line": undefined,
|
||||
"name": "func2",
|
||||
"selfWeight": 14111.111111111111,
|
||||
"totalWeight": 14111.111111111111,
|
||||
},
|
||||
],
|
||||
"name": "callgrind.multiple-event-types.log -- Memory",
|
||||
"stacks": Array [
|
||||
"main;func1;func2 10.85 KB",
|
||||
"main;func1 8.68 KB",
|
||||
"main;func2 2.93 KB",
|
||||
"main 14.65 KB",
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`importFromCallgrind multiple event types: indexToView 1`] = `0`;
|
||||
|
||||
exports[`importFromCallgrind multiple event types: profileGroup.name 1`] = `"callgrind.multiple-event-types.log"`;
|
||||
|
||||
exports[`importFromCallgrind name compression 1`] = `
|
||||
Object {
|
||||
"frames": Array [
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "file1.c",
|
||||
"key": "file1.c:main",
|
||||
"line": undefined,
|
||||
"name": "main",
|
||||
"selfWeight": 20,
|
||||
"totalWeight": 820,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "file1.c",
|
||||
"key": "file1.c:func1",
|
||||
"line": undefined,
|
||||
"name": "func1",
|
||||
"selfWeight": 100,
|
||||
"totalWeight": 400,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "file2.c",
|
||||
"key": "file2.c:func2",
|
||||
"line": undefined,
|
||||
"name": "func2",
|
||||
"selfWeight": 700,
|
||||
"totalWeight": 700,
|
||||
},
|
||||
],
|
||||
"name": "callgrind.name-compression.log -- Instructions",
|
||||
"stacks": Array [
|
||||
"main;func1;func2 300",
|
||||
"main;func1 100",
|
||||
"main;func2 400",
|
||||
"main 20",
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`importFromCallgrind name compression: indexToView 1`] = `0`;
|
||||
|
||||
exports[`importFromCallgrind name compression: profileGroup.name 1`] = `"callgrind.name-compression.log"`;
|
||||
|
||||
exports[`importFromCallgrind: indexToView 1`] = `0`;
|
||||
|
||||
exports[`importFromCallgrind: profileGroup.name 1`] = `"callgrind.example.log"`;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -64,17 +64,17 @@ exports[`importFromFirefox ignore self-hosted 1`] = `
|
||||
Object {
|
||||
"frames": Array [
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "http://localhost:8000/simple.js:1",
|
||||
"col": 15,
|
||||
"file": "http://localhost:8000/simple.js",
|
||||
"key": "alpha (http://localhost:8000/simple.js:1:14)",
|
||||
"line": 14,
|
||||
"line": 1,
|
||||
"name": "alpha",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 26.983816999942064,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "http://localhost:8000/simple.js:14",
|
||||
"col": 15,
|
||||
"file": "http://localhost:8000/simple.js",
|
||||
"key": "delta (http://localhost:8000/simple.js:14:14)",
|
||||
"line": 14,
|
||||
"name": "delta",
|
||||
@@ -82,19 +82,19 @@ Object {
|
||||
"totalWeight": 11.946324001066387,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "http://localhost:8000/simple.js:20",
|
||||
"col": 15,
|
||||
"file": "http://localhost:8000/simple.js",
|
||||
"key": "gamma (http://localhost:8000/simple.js:20:14)",
|
||||
"line": 14,
|
||||
"line": 20,
|
||||
"name": "gamma",
|
||||
"selfWeight": 26.983816999942064,
|
||||
"totalWeight": 26.983816999942064,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "http://localhost:8000/simple.js:8",
|
||||
"col": 14,
|
||||
"file": "http://localhost:8000/simple.js",
|
||||
"key": "beta (http://localhost:8000/simple.js:8:13)",
|
||||
"line": 13,
|
||||
"line": 8,
|
||||
"name": "beta",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 15.037492998875678,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1376,6 +1376,268 @@ Object {
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`importFromLinuxPerf system-wide.linux-perf.txt chunked 1`] = `
|
||||
Object {
|
||||
"frames": Array [
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "[unknown]",
|
||||
"key": "[unknown] ([unknown])",
|
||||
"line": undefined,
|
||||
"name": "??? ([unknown])",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 0.13823499999125488,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "/lib/x86_64-linux-gnu/libc-2.27.so",
|
||||
"key": "__libc_start_main (/lib/x86_64-linux-gnu/libc-2.27.so)",
|
||||
"line": undefined,
|
||||
"name": "__libc_start_main",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 0.13823499999125488,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "/workdir/simple-terminates",
|
||||
"key": "main (/workdir/simple-terminates)",
|
||||
"line": undefined,
|
||||
"name": "main",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 0.13823499999125488,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "/workdir/simple-terminates",
|
||||
"key": "_Z5alphav (/workdir/simple-terminates)",
|
||||
"line": undefined,
|
||||
"name": "_Z5alphav",
|
||||
"selfWeight": 0.04059999997843988,
|
||||
"totalWeight": 0.04059999997843988,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "/workdir/simple-terminates",
|
||||
"key": "_Z5deltav (/workdir/simple-terminates)",
|
||||
"line": undefined,
|
||||
"name": "_Z5deltav",
|
||||
"selfWeight": 0.023244000098202378,
|
||||
"totalWeight": 0.07264250004664063,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "/workdir/simple-terminates",
|
||||
"key": "_Z4betav (/workdir/simple-terminates)",
|
||||
"line": undefined,
|
||||
"name": "_Z4betav",
|
||||
"selfWeight": 0.05354449988226406,
|
||||
"totalWeight": 0.05447799988905899,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "/workdir/simple-terminates",
|
||||
"key": "_Z5gammav (/workdir/simple-terminates)",
|
||||
"line": undefined,
|
||||
"name": "_Z5gammav",
|
||||
"selfWeight": 0.01991300002555363,
|
||||
"totalWeight": 0.01991300002555363,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "[kernel.kallsyms]",
|
||||
"key": "[unknown] ([kernel.kallsyms])",
|
||||
"line": undefined,
|
||||
"name": "??? ([kernel.kallsyms])",
|
||||
"selfWeight": 0.0009335000067949295,
|
||||
"totalWeight": 0.0009335000067949295,
|
||||
},
|
||||
],
|
||||
"name": "simple-terminat tid: 9",
|
||||
"stacks": Array [
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5alphav 501.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.01ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 1.01ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5alphav 996.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 1.03ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 989.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5gammav 1.07ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.04ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav;??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]) 933.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.46ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 1.47ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5alphav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 997.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5alphav 1.01ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5gammav 1.01ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z5alphav 1.04ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 1.06ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5alphav 965.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z5alphav 2.12ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 925.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.02ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z5alphav 1.07ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 987.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5alphav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5gammav 997.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z5alphav 1000.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 997.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5alphav 997.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5alphav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5gammav 999.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z5alphav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5alphav 999.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z5alphav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5alphav 999.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z5alphav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5alphav 921.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z5alphav 1.01ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 1.08ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 989.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5gammav 974.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z5alphav 963.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 1.04ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5alphav 1.04ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 991.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z5alphav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5gammav 922.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z5alphav 1.02ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 1.07ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5alphav 983.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.01ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z5alphav 999.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5alphav 999.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z5alphav 998.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5gammav 998.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z5alphav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 974.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5gammav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.03ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z5alphav 998.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5alphav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z5alphav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 1000.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5alphav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 999.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5gammav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z5alphav 997.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5gammav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 999.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5gammav 999.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5gammav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5alphav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5gammav 999.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 997.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5gammav 932.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 2.09ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5alphav 986.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5gammav 998.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z5alphav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 954.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5alphav 991.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.05ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z5alphav 1.01ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 999.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5gammav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 989.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5gammav 1.01ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.01ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 998.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5gammav 1000.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5gammav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 981.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 1.01ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 921.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 2.09ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 1.01ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z4betav 999.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5gammav 995.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z5alphav 997.50µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav 1.00ms",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5alphav 980.00µs",
|
||||
"??? ([unknown]);__libc_start_main;main;_Z5deltav;_Z4betav 476.00µs",
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`importFromLinuxPerf system-wide.linux-perf.txt chunked 2`] = `
|
||||
Object {
|
||||
"frames": Array [
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "[kernel.kallsyms]",
|
||||
"key": "[unknown] ([kernel.kallsyms])",
|
||||
"line": undefined,
|
||||
"name": "??? ([kernel.kallsyms])",
|
||||
"selfWeight": 0.1372890000056941,
|
||||
"totalWeight": 0.1372890000056941,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "[unknown]",
|
||||
"key": "[unknown] ([unknown])",
|
||||
"line": undefined,
|
||||
"name": "??? ([unknown])",
|
||||
"selfWeight": 0.0009340000106021762,
|
||||
"totalWeight": 0.0014475000207312405,
|
||||
},
|
||||
],
|
||||
"name": "swapper",
|
||||
"stacks": Array [
|
||||
"??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]) 17.00µs",
|
||||
"??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]) 9.55ms",
|
||||
"??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([unknown]) 487.50µs",
|
||||
"??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]) 486.00µs",
|
||||
"??? ([unknown]);??? ([unknown]) 446.50µs",
|
||||
"??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]) 34.50µs",
|
||||
"??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]) 38.00µs",
|
||||
"??? ([kernel.kallsyms]);??? ([unknown]);??? ([unknown]);??? ([unknown]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]) 479.00µs",
|
||||
"??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]) 6.52ms",
|
||||
"??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]) 517.00µs",
|
||||
"??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]) 111.12ms",
|
||||
"??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]) 399.50µs",
|
||||
"??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]);??? ([kernel.kallsyms]) 8.13ms",
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`importFromLinuxPerf system-wide.linux-perf.txt chunked: indexToView 1`] = `0`;
|
||||
|
||||
exports[`importFromLinuxPerf system-wide.linux-perf.txt chunked: profileGroup.name 1`] = `"system-wide.linux-perf.txt"`;
|
||||
|
||||
exports[`importFromLinuxPerf system-wide.linux-perf.txt: indexToView 1`] = `0`;
|
||||
|
||||
exports[`importFromLinuxPerf system-wide.linux-perf.txt: profileGroup.name 1`] = `"system-wide.linux-perf.txt"`;
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`importFromSafari 1`] = `
|
||||
Object {
|
||||
"frames": Array [
|
||||
Frame {
|
||||
"col": 13,
|
||||
"file": "__InjectedScript_InjectedScriptSource.js",
|
||||
"key": "injectModule:__InjectedScript_InjectedScriptSource.js:109:13",
|
||||
"line": 109,
|
||||
"name": "injectModule",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 0.001,
|
||||
},
|
||||
Frame {
|
||||
"col": 10,
|
||||
"file": "__InjectedScript_CommandLineAPIModuleSource.js",
|
||||
"key": ":__InjectedScript_CommandLineAPIModuleSource.js:2:10",
|
||||
"line": 2,
|
||||
"name": "(anonymous __InjectedScript_CommandLineAPIModuleSource.js:2)",
|
||||
"selfWeight": 0.001,
|
||||
"totalWeight": 0.001,
|
||||
},
|
||||
Frame {
|
||||
"col": 1,
|
||||
"file": "file:///speedscope/sample/programs/javascript/simple.js",
|
||||
"key": "(program):file:///speedscope/sample/programs/javascript/simple.js:1:1",
|
||||
"line": 1,
|
||||
"name": "(program)",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 0.03248933597933502,
|
||||
},
|
||||
Frame {
|
||||
"col": 15,
|
||||
"file": "file:///speedscope/sample/programs/javascript/simple.js",
|
||||
"key": "alpha:file:///speedscope/sample/programs/javascript/simple.js:1:15",
|
||||
"line": 1,
|
||||
"name": "alpha",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 0.03248933597933502,
|
||||
},
|
||||
Frame {
|
||||
"col": 15,
|
||||
"file": "file:///speedscope/sample/programs/javascript/simple.js",
|
||||
"key": "delta:file:///speedscope/sample/programs/javascript/simple.js:14:15",
|
||||
"line": 14,
|
||||
"name": "delta",
|
||||
"selfWeight": 0.003094222474222382,
|
||||
"totalWeight": 0.020112446082445484,
|
||||
},
|
||||
Frame {
|
||||
"col": 15,
|
||||
"file": "file:///speedscope/sample/programs/javascript/simple.js",
|
||||
"key": "gamma:file:///speedscope/sample/programs/javascript/simple.js:20:15",
|
||||
"line": 20,
|
||||
"name": "gamma",
|
||||
"selfWeight": 0.029395113505112636,
|
||||
"totalWeight": 0.029395113505112636,
|
||||
},
|
||||
Frame {
|
||||
"col": 14,
|
||||
"file": "file:///speedscope/sample/programs/javascript/simple.js",
|
||||
"key": "beta:file:///speedscope/sample/programs/javascript/simple.js:8:14",
|
||||
"line": 8,
|
||||
"name": "beta",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 0.012376889896889526,
|
||||
},
|
||||
Frame {
|
||||
"col": 102,
|
||||
"file": "",
|
||||
"key": "firstOpenSearchURLString::4:102",
|
||||
"line": 4,
|
||||
"name": "firstOpenSearchURLString",
|
||||
"selfWeight": 0.0005174240213818848,
|
||||
"totalWeight": 0.0005174240213818848,
|
||||
},
|
||||
],
|
||||
"name": "Grabación de Control temporal 1",
|
||||
"stacks": Array [
|
||||
"injectModule;(anonymous __InjectedScript_CommandLineAPIModuleSource.js:2) 1.00ms",
|
||||
" 39.93ms",
|
||||
"(program);alpha;delta;gamma 10.83ms",
|
||||
" 2.46ms",
|
||||
"(program);alpha;delta 3.09ms",
|
||||
"(program);alpha;beta;gamma 4.64ms",
|
||||
"(program);alpha;delta;gamma 1.55ms",
|
||||
"(program);alpha;beta;gamma 1.55ms",
|
||||
"(program);alpha;delta;gamma 3.09ms",
|
||||
"(program);alpha;beta;gamma 4.64ms",
|
||||
"(program);alpha;delta;gamma 1.55ms",
|
||||
"(program);alpha;beta;gamma 1.55ms",
|
||||
" 253.50ms",
|
||||
"firstOpenSearchURLString 517.42µs",
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`importFromSafari: indexToView 1`] = `0`;
|
||||
|
||||
exports[`importFromSafari: profileGroup.name 1`] = `"Grabación de Control temporal 1"`;
|
||||
@@ -851,6 +851,201 @@ Object {
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`importFromStackprof object mode 1`] = `
|
||||
Object {
|
||||
"frames": Array [
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "../../alexcoco/speedscope/sample/programs/ruby/object.rb",
|
||||
"key": 4317728280,
|
||||
"line": undefined,
|
||||
"name": "<main>",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 103,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "/Users/alex/src/github.com/alexcoco/speedscope/sample/programs/ruby/object.rb",
|
||||
"key": 4376547240,
|
||||
"line": undefined,
|
||||
"name": "<main>",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 103,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "<cfunc>",
|
||||
"key": 4379035920,
|
||||
"line": null,
|
||||
"name": "StackProf.run",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 103,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "/Users/alex/src/github.com/alexcoco/speedscope/sample/programs/ruby/object.rb",
|
||||
"key": 4317464320,
|
||||
"line": 21,
|
||||
"name": "block in <main>",
|
||||
"selfWeight": 1,
|
||||
"totalWeight": 103,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "/Users/alex/src/github.com/alexcoco/speedscope/sample/programs/ruby/object.rb",
|
||||
"key": 4379033920,
|
||||
"line": 4,
|
||||
"name": "Object#a",
|
||||
"selfWeight": 2,
|
||||
"totalWeight": 102,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "<cfunc>",
|
||||
"key": 4317869400,
|
||||
"line": null,
|
||||
"name": "Range#each",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 102,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "/Users/alex/src/github.com/alexcoco/speedscope/sample/programs/ruby/object.rb",
|
||||
"key": 4379033880,
|
||||
"line": 11,
|
||||
"name": "Object#b",
|
||||
"selfWeight": 1,
|
||||
"totalWeight": 5,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "<cfunc>",
|
||||
"key": 4318054440,
|
||||
"line": null,
|
||||
"name": "Class#new",
|
||||
"selfWeight": 4,
|
||||
"totalWeight": 4,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "/Users/alex/src/github.com/alexcoco/speedscope/sample/programs/ruby/object.rb",
|
||||
"key": 4379033840,
|
||||
"line": 15,
|
||||
"name": "Object#c",
|
||||
"selfWeight": 2,
|
||||
"totalWeight": 95,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "<cfunc>",
|
||||
"key": 4317868920,
|
||||
"line": null,
|
||||
"name": "Range#to_a",
|
||||
"selfWeight": 1,
|
||||
"totalWeight": 37,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "<cfunc>",
|
||||
"key": 4379016640,
|
||||
"line": null,
|
||||
"name": "Enumerable#to_a",
|
||||
"selfWeight": 36,
|
||||
"totalWeight": 36,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "<internal:array>",
|
||||
"key": 4317563560,
|
||||
"line": 60,
|
||||
"name": "Array#sample",
|
||||
"selfWeight": 20,
|
||||
"totalWeight": 20,
|
||||
},
|
||||
Frame {
|
||||
"col": undefined,
|
||||
"file": "<cfunc>",
|
||||
"key": 4317922760,
|
||||
"line": null,
|
||||
"name": "Array#sort",
|
||||
"selfWeight": 36,
|
||||
"totalWeight": 36,
|
||||
},
|
||||
],
|
||||
"name": "object-stackprof.json",
|
||||
"stacks": Array [
|
||||
"<main>;<main>;StackProf.run;block in <main> 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#b 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#b;Class#new 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Range#to_a 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Range#to_a;Enumerable#to_a 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sample 3",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sort 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Range#to_a;Enumerable#to_a 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sample 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sort 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Range#to_a;Enumerable#to_a 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sample 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sort 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Range#to_a;Enumerable#to_a 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sample 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sort 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Range#to_a;Enumerable#to_a 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sample 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sort 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Range#to_a;Enumerable#to_a 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sample 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sort 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#b;Class#new 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Range#to_a;Enumerable#to_a 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sample 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sort 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Range#to_a;Enumerable#to_a 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sample 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sort 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Range#to_a;Enumerable#to_a 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sample 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sort 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Range#to_a;Enumerable#to_a 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sample 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sort 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Range#to_a;Enumerable#to_a 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sample 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sort 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Range#to_a;Enumerable#to_a 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sample 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sort 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#b;Class#new 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Range#to_a;Enumerable#to_a 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sample 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sort 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Range#to_a;Enumerable#to_a 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sample 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sort 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Range#to_a;Enumerable#to_a 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sample 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sort 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Range#to_a;Enumerable#to_a 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sample 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sort 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Range#to_a;Enumerable#to_a 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sample 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sort 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Range#to_a;Enumerable#to_a 2",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sample 1",
|
||||
"<main>;<main>;StackProf.run;block in <main>;Object#a;Range#each;Object#a;Object#c;Range#each;Object#c;Array#sort 2",
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`importFromStackprof object mode: indexToView 1`] = `0`;
|
||||
|
||||
exports[`importFromStackprof object mode: profileGroup.name 1`] = `"object-stackprof.json"`;
|
||||
|
||||
exports[`importFromStackprof: indexToView 1`] = `0`;
|
||||
|
||||
exports[`importFromStackprof: profileGroup.name 1`] = `"simple-stackprof.json"`;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ Object {
|
||||
"file": "bootstrap_node.js",
|
||||
"key": " bootstrap_node.js:10:10",
|
||||
"line": 10,
|
||||
"name": "(anonymous)",
|
||||
"name": "(anonymous bootstrap_node.js:10)",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 116424,
|
||||
},
|
||||
@@ -53,7 +53,7 @@ Object {
|
||||
"file": "util.js",
|
||||
"key": " util.js:1:11",
|
||||
"line": 1,
|
||||
"name": "(anonymous)",
|
||||
"name": "(anonymous util.js:1)",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 29385,
|
||||
},
|
||||
@@ -62,7 +62,7 @@ Object {
|
||||
"file": "internal/encoding.js",
|
||||
"key": " internal/encoding.js:1:11",
|
||||
"line": 1,
|
||||
"name": "(anonymous)",
|
||||
"name": "(anonymous encoding.js:1)",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 29385,
|
||||
},
|
||||
@@ -107,7 +107,7 @@ Object {
|
||||
"file": "module.js",
|
||||
"key": " module.js:1:11",
|
||||
"line": 1,
|
||||
"name": "(anonymous)",
|
||||
"name": "(anonymous module.js:1)",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 22888,
|
||||
},
|
||||
@@ -116,7 +116,7 @@ Object {
|
||||
"file": "fs.js",
|
||||
"key": " fs.js:1:11",
|
||||
"line": 1,
|
||||
"name": "(anonymous)",
|
||||
"name": "(anonymous fs.js:1)",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 22888,
|
||||
},
|
||||
@@ -197,7 +197,7 @@ Object {
|
||||
"file": "/Users/jlfwong/code/speedscope/sample/programs/javascript/simple.js",
|
||||
"key": " /Users/jlfwong/code/speedscope/sample/programs/javascript/simple.js:1:11",
|
||||
"line": 1,
|
||||
"name": "(anonymous)",
|
||||
"name": "(anonymous simple.js:1)",
|
||||
"selfWeight": 0,
|
||||
"totalWeight": 64151,
|
||||
},
|
||||
@@ -240,22 +240,22 @@ Object {
|
||||
],
|
||||
"name": "simple.v8log.json",
|
||||
"stacks": Array [
|
||||
"(anonymous);startup;setupGlobalVariables;NativeModule.require;NativeModule.compile;(anonymous);NativeModule.require;NativeModule.compile;(anonymous);(c++) v8::internal::Runtime_CreateArrayLiteral;(c++) v8::internal::JSFunction::EnsureHasInitialMap 29.38ms",
|
||||
"(anonymous);startup;setupGlobalConsole;setupInspectorCommandLineAPI;NativeModule.require;NativeModule.compile;(anonymous);NativeModule.require;NativeModule.compile;(anonymous);(c++) v8::internal::Runtime_StoreIC_Miss;(c++) v8::internal::Map::RawCopy 22.89ms",
|
||||
"(anonymous);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous);a;b;d 37.52ms",
|
||||
"(anonymous);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous);a;c;d 1.28ms",
|
||||
"(anonymous);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous);a;b;d 2.55ms",
|
||||
"(anonymous);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous);a;c;d 1.27ms",
|
||||
"(anonymous);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous);a;b;d 1.28ms",
|
||||
"(anonymous);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous);a;c;d 1.27ms",
|
||||
"(anonymous);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous);a;b;d 1.29ms",
|
||||
"(anonymous);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous);a;c;d 1.26ms",
|
||||
"(anonymous);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous);a;b;d 1.31ms",
|
||||
"(anonymous);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous);a;c;d 2.52ms",
|
||||
"(anonymous);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous);a;c 1.27ms",
|
||||
"(anonymous);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous);a;b 3.62ms",
|
||||
"(anonymous);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous);a;c 1.28ms",
|
||||
"(anonymous);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous);a;b 6.42ms",
|
||||
"(anonymous bootstrap_node.js:10);startup;setupGlobalVariables;NativeModule.require;NativeModule.compile;(anonymous util.js:1);NativeModule.require;NativeModule.compile;(anonymous encoding.js:1);(c++) v8::internal::Runtime_CreateArrayLiteral;(c++) v8::internal::JSFunction::EnsureHasInitialMap 29.38ms",
|
||||
"(anonymous bootstrap_node.js:10);startup;setupGlobalConsole;setupInspectorCommandLineAPI;NativeModule.require;NativeModule.compile;(anonymous module.js:1);NativeModule.require;NativeModule.compile;(anonymous fs.js:1);(c++) v8::internal::Runtime_StoreIC_Miss;(c++) v8::internal::Map::RawCopy 22.89ms",
|
||||
"(anonymous bootstrap_node.js:10);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous simple.js:1);a;b;d 37.52ms",
|
||||
"(anonymous bootstrap_node.js:10);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous simple.js:1);a;c;d 1.28ms",
|
||||
"(anonymous bootstrap_node.js:10);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous simple.js:1);a;b;d 2.55ms",
|
||||
"(anonymous bootstrap_node.js:10);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous simple.js:1);a;c;d 1.27ms",
|
||||
"(anonymous bootstrap_node.js:10);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous simple.js:1);a;b;d 1.28ms",
|
||||
"(anonymous bootstrap_node.js:10);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous simple.js:1);a;c;d 1.27ms",
|
||||
"(anonymous bootstrap_node.js:10);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous simple.js:1);a;b;d 1.29ms",
|
||||
"(anonymous bootstrap_node.js:10);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous simple.js:1);a;c;d 1.26ms",
|
||||
"(anonymous bootstrap_node.js:10);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous simple.js:1);a;b;d 1.31ms",
|
||||
"(anonymous bootstrap_node.js:10);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous simple.js:1);a;c;d 2.52ms",
|
||||
"(anonymous bootstrap_node.js:10);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous simple.js:1);a;c 1.27ms",
|
||||
"(anonymous bootstrap_node.js:10);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous simple.js:1);a;b 3.62ms",
|
||||
"(anonymous bootstrap_node.js:10);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous simple.js:1);a;c 1.28ms",
|
||||
"(anonymous bootstrap_node.js:10);startup;Module.runMain;Module._load;tryModuleLoad;Module.load;Module._extensions..js;Module._compile;(anonymous simple.js:1);a;b 6.42ms",
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -7,3 +7,15 @@ test('importFromBGFlameGraph', async () => {
|
||||
test('importFromBGFlameGraph with CRLF', async () => {
|
||||
await checkProfileSnapshot('./sample/profiles/stackcollapse/simple-crlf.txt')
|
||||
})
|
||||
|
||||
test('importFromBGFlameGraph with UTF-16, Little Endian', async () => {
|
||||
await checkProfileSnapshot('./sample/profiles/stackcollapse/simple-utf16-le.txt')
|
||||
})
|
||||
|
||||
test('importFromBGFlameGraph with UTF-16, Big Endian', async () => {
|
||||
await checkProfileSnapshot('./sample/profiles/stackcollapse/simple-utf16-be.txt')
|
||||
})
|
||||
|
||||
test('importFromBGFlameGraph with invalid lines', async () => {
|
||||
await checkProfileSnapshot('./sample/profiles/stackcollapse/simple-with-invalids.txt')
|
||||
})
|
||||
|
||||
@@ -1,25 +1,31 @@
|
||||
// https://github.com/brendangregg/FlameGraph#2-fold-stacks
|
||||
|
||||
import {Profile, FrameInfo, StackListProfileBuilder} from '../lib/profile'
|
||||
import {TextFileContent} from './utils'
|
||||
|
||||
interface BGSample {
|
||||
stack: FrameInfo[]
|
||||
duration: number
|
||||
}
|
||||
|
||||
function parseBGFoldedStacks(contents: string): BGSample[] {
|
||||
function parseBGFoldedStacks(contents: TextFileContent): BGSample[] {
|
||||
const samples: BGSample[] = []
|
||||
contents.replace(/^(.*) (\d+)$/gm, (match: string, stack: string, n: string) => {
|
||||
for (const line of contents.splitLines()) {
|
||||
const match = /^(.*) (\d+)$/gm.exec(line)
|
||||
if (!match) continue
|
||||
const stack = match[1]
|
||||
const n = match[2]
|
||||
|
||||
samples.push({
|
||||
stack: stack.split(';').map(name => ({key: name, name: name})),
|
||||
duration: parseInt(n, 10),
|
||||
})
|
||||
return match
|
||||
})
|
||||
}
|
||||
|
||||
return samples
|
||||
}
|
||||
|
||||
export function importFromBGFlameGraph(contents: string): Profile | null {
|
||||
export function importFromBGFlameGraph(contents: TextFileContent): Profile | null {
|
||||
const parsed = parseBGFoldedStacks(contents)
|
||||
const duration = parsed.reduce((prev: number, cur: BGSample) => prev + cur.duration, 0)
|
||||
const profile = new StackListProfileBuilder(duration)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import {checkProfileSnapshot} from '../lib/test-utils'
|
||||
|
||||
test('importFromCallgrind', async () => {
|
||||
await checkProfileSnapshot('./sample/profiles/callgrind/callgrind.example.log')
|
||||
})
|
||||
|
||||
test('importFromCallgrind name compression', async () => {
|
||||
await checkProfileSnapshot('./sample/profiles/callgrind/callgrind.name-compression.log')
|
||||
})
|
||||
|
||||
test('importFromCallgrind multiple event types', async () => {
|
||||
await checkProfileSnapshot('./sample/profiles/callgrind/callgrind.multiple-event-types.log')
|
||||
})
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user