Skip to content

Commit 0a5eb02

Browse files
committed
Revert "Merge pull request davidmarkclements#165 from BridgeAR/filter-init"
This reverts commit be8e703, reversing changes made to 2bbc814.
1 parent e88214c commit 0a5eb02

File tree

8 files changed

+125
-92
lines changed

8 files changed

+125
-92
lines changed

.gitignore

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,4 @@ node_modules
55
win
66
package-lock.json
77
todo
8-
.vscode
9-
*.0x
8+
.vscode

lib/ticks-to-tree.js

+48-13
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ function ticksToTree (ticks, mapFrames, inlined) {
2323
stack = removeInstrumentationFrames(stack)
2424
if (typeof mapFrames === 'function') stack = mapFrames(stack)
2525
if (!stack) return
26-
2726
stack = stack.map(({name, kind, type}, ix) => {
2827
name = name.replace(/ (:[0-9]+:[0-9]+)/, (_, loc) => ` [eval]${loc}`)
2928
// 0 no info
@@ -65,15 +64,14 @@ function ticksToTree (ticks, mapFrames, inlined) {
6564
}
6665
}
6766
if (kind === 'Unopt') S += 1
68-
else if (kind === 'Opt') S += 2
67+
if (kind === 'Opt') S += 2
6968
}
7069

7170
if (type && type !== 'JS') name += ' [' + type + (kind ? ':' + kind : '') + ']'
72-
7371
return {S, name, value: 0, top: 0}
7472
})
7573

76-
labelInitFrames(stack)
74+
stack = labelInitFrames(stack)
7775

7876
addToMergedTree(stack.map(({S, name, value, top}) => ({S, name, value, top})))
7977
// mutate original (save another loop over stack + extra objects)
@@ -118,9 +116,9 @@ function ticksToTree (ticks, mapFrames, inlined) {
118116
if (child === undefined) {
119117
frame.fn = frame.name
120118
if (frame.S === 1) frame.name = '~' + frame.name
121-
else if (frame.S === 2) frame.name = '*' + frame.name
122-
else if (frame.S === 3) frame.name = '~' + frame.name + ' [INLINABLE]'
123-
else if (frame.S === 4) frame.name = '*' + frame.name + ' [INLINABLE]'
119+
if (frame.S === 2) frame.name = '*' + frame.name
120+
if (frame.S === 3) frame.name = '~' + frame.name + ' [INLINABLE]'
121+
if (frame.S === 4) frame.name = '*' + frame.name + ' [INLINABLE]'
124122
children.push(frame)
125123
} else frame = child
126124

@@ -135,14 +133,51 @@ function ticksToTree (ticks, mapFrames, inlined) {
135133
return { merged, unmerged }
136134
}
137135

136+
138137
function labelInitFrames (frames) {
139-
frames.findIndex((frame) => {
140-
if (/^.?\(anonymous\) \/.+\.m?js:[0-9]+:[0-9]+/.test(frame.name)) {
141-
return true
142-
}
143-
frame.name += ' [INIT]'
144-
frame.isInit = true
138+
const startupBootstrapNodeIndex = frames.findIndex(({name}, ix) => {
139+
if (frames[ix + 1] && /Module.runMain module\.js/.test(frames[ix + 1].name)) return false
140+
return /startup bootstrap_node\.js/.test(name)
141+
})
142+
143+
if (startupBootstrapNodeIndex !== -1) {
144+
frames.slice(startupBootstrapNodeIndex + 1).forEach((frame) => {
145+
if (frame.isInit) return
146+
frame.name += ' [INIT]'
147+
frame.isInit = true
148+
})
149+
}
150+
151+
const moduleRunMainIndex = frames.findIndex(({name}, ix) => {
152+
return /Module.runMain module\.js/.test(name)
145153
})
154+
155+
if (moduleRunMainIndex !== -1) {
156+
frames.slice(moduleRunMainIndex + 1).forEach((frame) => {
157+
if (frame.isInit) return
158+
if (/.+ (internal\/)?module\.js/.test(frame.name)) frame.name += ' [INIT]'
159+
frame.isInit = true
160+
})
161+
}
162+
163+
// if there's so many modules to load, the module requiring may
164+
// actually go into another tick, so far that's been observed where Module.load
165+
// is the first function, but there could be variation...
166+
167+
const partOfModuleLoadingCycle = frames.findIndex(({name}, ix) => {
168+
return /(Module\.load|Module\._load|tryModuleLoad|Module\._extensions.+|Module\._compile|Module.require|require internal.+) module\.js/.test(name)
169+
})
170+
171+
if (partOfModuleLoadingCycle === 0) {
172+
frames.forEach((frame) => {
173+
if (frame.isInit) return
174+
if (/.+ (internal\/)?module\.js/.test(frame.name)) frame.name += ' [INIT]'
175+
frame.isInit = true
176+
})
177+
}
178+
179+
180+
return frames
146181
}
147182

148183
function removeInstrumentationFrames (frames) {

platform/linux.js

-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ function linux (args, sudo, binary, cb) {
4545
'--',
4646
node,
4747
'--perf-basic-prof',
48-
'-r', path.join(__dirname, '..', 'lib', 'preload', 'no-cluster'),
4948
'-r', path.join(__dirname, '..', 'lib', 'preload', 'soft-exit'),
5049
...(onPort ? ['-r', path.join(__dirname, '..', 'lib', 'preload', 'detect-port.js')] : [])
5150
].filter(Boolean).concat(args.argv), {

platform/sun.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ function sun (args, sudo, binary, cb) {
3333

3434
args = Object.assign([
3535
'--perf-basic-prof',
36-
'-r', path.join(__dirname, '..', 'lib', 'preload', 'no-cluster'),
3736
'-r', path.join(__dirname, '..', 'lib', 'preload', 'soft-exit'),
3837
...(onPort ? ['-r', path.join(__dirname, '..', 'lib', 'preload', 'detect-port.js')] : [])
3938
].concat(args.argv), args)
@@ -52,6 +51,7 @@ function sun (args, sudo, binary, cb) {
5251
})
5352
var folder
5453
var prof
54+
var profExited = false
5555

5656
function start () {
5757
prof = spawn('sudo', [profile, '-p', proc.pid])
@@ -80,7 +80,7 @@ function sun (args, sudo, binary, cb) {
8080
else status('Profiling')
8181

8282
start()
83-
83+
8484
if (onPort) when(proc.stdio[5], 'data').then((port) => {
8585
const whenPort = spawnOnPort(onPort, port)
8686
whenPort.then(() => proc.kill('SIGINT'))
@@ -122,11 +122,11 @@ function sun (args, sudo, binary, cb) {
122122
try { process.kill(prof.pid, 'SIGKILL') } catch (e) {}
123123
}
124124

125-
try {
126-
translate = sym({silent: true, pid: proc.pid})
125+
try {
126+
translate = sym({silent: true, pid: proc.pid})
127127
capture(attempts, translate)
128128
} catch (e) {
129-
setTimeout(capture, 300, attempts - 1)
129+
setTimeout(capture, 300, attempts - 1)
130130
}
131131
} else {
132132
status('Unable to find map file!\n')
@@ -137,7 +137,7 @@ function sun (args, sudo, binary, cb) {
137137
}
138138
return
139139
}
140-
140+
141141
translate = translate || sym({silent: true, pid: proc.pid})
142142

143143
if (!translate) {

platform/v8.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,12 @@ function collectInliningInfo (sp) {
150150
const [ match, inlinedFn ] = /INLINE \((.*)\)/.exec(s) || [ false ]
151151
// shouldn't not match though..
152152
if (match === false) return cb()
153-
154-
if (lastOptimizedFrame === null) return cb()
153+
154+
if (lastOptimizedFrame === null) return cb()
155155
const { fn, file } = lastOptimizedFrame
156156
// could be a big problem if the fn doesn't match
157157
if (fn !== inlinedFn) return cb()
158-
158+
159159
const key = `${fn} ${file}`
160160
inlined[key] = inlined[key] || []
161161
inlined[key].push(lastOptimizedFrame)
@@ -177,7 +177,7 @@ function collectInliningInfo (sp) {
177177
if (ix === '-1') root = {file, fn, id, ix, pos, key: `${fn} ${file}`}
178178
else {
179179
lastOptimizedFrame = {file, fn, id, ix, pos, caller: root}
180-
}
180+
}
181181
} else process.stdout.write(s)
182182
}
183183

readme.md

+39-38
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ on any platform which Node runs on (macOs, Linux, Windows, Android...).
1616
* Node v8.5.0 and above
1717
* Default usage supports any Operating System that Node runs on!
1818
* Chrome
19-
* Other browsers may open flamegraphs in a degraded, but functional form
19+
* Other browsers may open flamegraphs in a degraded, but functional form
2020

2121
## Legacy
2222

@@ -82,12 +82,12 @@ generates a profile folder (`<pid>.0x`), containing `flamegraph.html`.
8282

8383
## The UI
8484

85-
The `flamegraph.html` file contains the 0x UI, which is explained in
85+
The `flamegraph.html` file contains the 0x UI, which is explained in
8686
[docs/ui.md](docs/ui.md).
8787

8888
## Production Servers
8989

90-
A lightweight, production server friendly, approach to generating a
90+
A lightweight, production server friendly, approach to generating a
9191
flamegraph is described in [docs/production-servers.md](docs/production-servers.md).
9292

9393
## The Profile Folder
@@ -125,90 +125,90 @@ Print usage info.
125125
Open the flamegraph in the browser using `open` or `xdg-open` (see
126126
https://www.npmjs.com/package/open for details).
127127

128-
### --on-port | -P
128+
### --on-port | -P
129129

130-
Run a given command and then generate the flamegraph.
131-
The command as specified has access to a `$PORT` variable.
132-
The `$PORT` variable is set according to the first port that
133-
profiled process opens.
130+
Run a given command and then generate the flamegraph.
131+
The command as specified has access to a `$PORT` variable.
132+
The `$PORT` variable is set according to the first port that
133+
profiled process opens.
134134

135-
For instance, here's an example of using [autocannon](http://npm.im/autocannon)
135+
For instance, here's an example of using [autocannon](http://npm.im/autocannon)
136136
to load-test the process:
137137

138138
```sh
139139
0x -P 'autocannon localhost:$PORT' app.js
140140
```
141141

142-
When the load-test completes, the profiled processed will be
143-
sent a SIGINT and the flamegraph will be automatically generated.
142+
When the load-test completes, the profiled processed will be
143+
sent a SIGINT and the flamegraph will be automatically generated.
144144

145145
Remember to use single quotes to avoid bash interpolation,
146146
or else escape variable (e.g. `0x -P "autocannon localhost:$PORT" app.js`
147147
won't work wheras `0x -P "autocannon localhost:\$PORT" app.js` will).
148148

149149
Note: On Windows interpolation usually occurs with `%PORT%`, however
150-
in this case the dollar-prefix `$PORT` is the correct syntax
151-
(because the interpolation is not shell based).
150+
in this case the dollar-prefix `$PORT` is the correct syntax
151+
(because the interpolation is not shell based).
152152

153153
Default: ''
154154

155155
### --name
156156

157157
The name of the HTML file, without the .html extension
158158
Can be set to - to write HTML to STDOUT (note
159-
due to the nature of CLI argument parsing, this must be set using `=`,
159+
due to the nature of CLI argument parsing, this must be set using `=`,
160160
e.g. `--name=-`).
161161

162-
If either this flag or `--output-html-file` is set to `-`
162+
If either this flag or `--output-html-file` is set to `-`
163163
then the HTML will go to STDOUT.
164164

165165
Default: flamegraph
166166

167-
### ---title
167+
### ---title
168168

169169
Set the title to display in the flamegraph UI.
170170

171-
Default: the command that 0x ran to start the process
171+
Default: the command that 0x ran to start the process
172172

173173
### --output-dir | -D
174174

175175
Specify artifact output directory. This can be specified in template
176-
form with possible variables being `{pid}`, `{timestamp}`, `{name}`
176+
form with possible variables being `{pid}`, `{timestamp}`, `{name}`
177177
(based on the `--name` flag) and `{outputDir}`(variables
178178
must be specified without whitespace, e.g. `{ pid }` is not supported).
179179

180180
Default: `{pid}.0x`
181181

182182
### --output-html | -F
183183

184-
Specify destination of the generated flamegraph HTML file.
185-
This can be specified in template form with possible variables
186-
being `{pid}`, `{timestamp}`, `{name}` (based on the `--name` flag) and
187-
`{outputDir}` (variables must be specified without whitespace,
188-
e.g. `{ pid }` is not supported). It can also be set to `-` to
184+
Specify destination of the generated flamegraph HTML file.
185+
This can be specified in template form with possible variables
186+
being `{pid}`, `{timestamp}`, `{name}` (based on the `--name` flag) and
187+
`{outputDir}` (variables must be specified without whitespace,
188+
e.g. `{ pid }` is not supported). It can also be set to `-` to
189189
send the HTML output to STDOUT (note
190-
due to the nature of CLI argument parsing, this must be set using `=`,
190+
due to the nature of CLI argument parsing, this must be set using `=`,
191191
e.g. `--output-html=-`).
192192

193-
If either this flag or `--name` is set to `-`
193+
If either this flag or `--name` is set to `-`
194194
then the HTML will go to STDOUT.
195195

196196
Default: `{outputDir}/{name}.html`
197197

198198
### --kernel-tracing
199199

200-
Use an OS kernel tracing tool (perf on Linux or
201-
dtrace on macOS and SmartOS). This will capture
202-
native stack frames (C++ modules and Libuv I/O),
200+
Use an OS kernel tracing tool (perf on Linux or
201+
dtrace on macOS and SmartOS). This will capture
202+
native stack frames (C++ modules and Libuv I/O),
203203
but may result in missing stacks on Node 8.
204204

205205
See [docs/kernel-tracing.md](docs/kernel-tracing.md) for more information.
206206

207-
Default: false
207+
Default: false
208208

209-
### --quiet | -q
209+
### --quiet | -q
210210

211-
Limit output, the only output will be fatal errors or
211+
Limit output, the only output will be fatal errors or
212212
the path to the `flamegraph.html` upon successful generation.
213213

214214
Default: false
@@ -226,9 +226,9 @@ with relevant outputs.
226226

227227
Default: false
228228

229-
### --visualize-only
229+
### --visualize-only
230230

231-
Supply a path to a profile folder to build or rebuild visualization
231+
Supply a path to a profile folder to build or rebuild visualization
232232
from original stacks.
233233

234234
Default: undefined
@@ -246,7 +246,7 @@ file.
246246

247247
Default: false
248248

249-
## Programmatic API
249+
## Programmatic API
250250

251251
0x can also be required as a Node module and scripted:
252252

@@ -268,6 +268,7 @@ async function capture () {
268268
}
269269

270270
capture()
271+
271272
```
272273

273274
The Programmatic API is detailed in [docs/api.md](docs/api.md).
@@ -276,9 +277,9 @@ The Programmatic API is detailed in [docs/api.md](docs/api.md).
276277

277278
### Memory Issues
278279

279-
Very complex applications with lots of stacks may hit memory issues.
280+
Very complex applications with lots of stacks may hit memory issues.
280281

281-
The `--stack-size` flag can be used to set the memory to the maximum 8GB
282+
The `--stack-size` flag can be used to set the memory to the maximum 8GB
282283
in order to work around this when profiling:
283284

284285
```
@@ -287,7 +288,7 @@ node --stack-size=8024 $(which 0x) my-app.js
287288

288289
There may still be a problem opening the flamegraph in Chrome. The same work
289290
around can be used by opening Chrome from the command line (platform dependent)
290-
and nesting the `--stack-size` flag within the `--js-flags` flag:
291+
and nesting the `--stack-size` flag within the `--js-flags` flag:
291292
`--js-flags="--stack-size 8024"`.
292293

293294
## Debugging
@@ -305,7 +306,7 @@ and nesting the `--stack-size` flag within the `--js-flags` flag:
305306
Sponsored by [nearForm](http://nearform.com)
306307

307308
This tool is inspired from various info and code sources
308-
and would have taken much longer without the following people and
309+
and would have taken much longer without the following people and
309310
their Open Source/Info Sharing efforts:
310311

311312
* Thorsten Lorenz (<http://thlorenz.com/>)

0 commit comments

Comments
 (0)