Skip to content

Assembly view part 1#4478

Merged
mstange merged 2 commits into
firefox-devtools:mainfrom
mstange:assembly-view-part-1
Feb 17, 2023
Merged

Assembly view part 1#4478
mstange merged 2 commits into
firefox-devtools:mainfrom
mstange:assembly-view-part-1

Conversation

@mstange

@mstange mstange commented Feb 17, 2023

Copy link
Copy Markdown
Contributor

Broken out from #4196 for incremental review + landing.

I recommend reviewing this back-to-front: Start with the types NativeSymbolInfo, BottomBoxInfo, SourceViewState and AssemblyViewState. The rest of the patch just does the legwork to put the right values into those states.

The NativeSymbolInfo is a thread-independent representation of a native symbol. Once the UI is implemented, you should be able double-click something in the call tree and then switch threads, and the assembly view should still display the right assembly code along with per-instruction timings which make sense for the selected thread. This would not be possible if we stored just a native symbol index, which would refer to different symbols in different threads.

The assembly view is closed by default. Double-clicking a call node will now always update both the source view and the assembly view.

By itself, this patch doesn't change much. But it does have some observable effects on its own:

  • If the source view is displaying source code, double-clicking a profiler label frame (which doesn't have an associated source file) will now clear the source view.
  • If the bottom box is closed, double-clicking a frame for native code which does NOT have a source file path will now open an empty bottom box. Before this patch, it would not have opened the bottom box. This new behavior will make more sense once we display assembly code in that case.

@mstange mstange requested a review from julienw February 17, 2023 05:48
@mstange mstange self-assigned this Feb 17, 2023
@codecov

codecov Bot commented Feb 17, 2023

Copy link
Copy Markdown

Codecov Report

Base: 88.63% // Head: 88.64% // Increases project coverage by +0.00% 🎉

Coverage data is based on head (68c8d45) compared to base (3758121).
Patch coverage: 86.13% of modified lines in pull request are covered.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4478   +/-   ##
=======================================
  Coverage   88.63%   88.64%           
=======================================
  Files         284      284           
  Lines       25532    25587   +55     
  Branches     6865     6882   +17     
=======================================
+ Hits        22630    22681   +51     
- Misses       2695     2701    +6     
+ Partials      207      205    -2     
Impacted Files Coverage Δ
src/actions/profile-view.js 89.33% <50.00%> (-0.51%) ⬇️
src/app-logic/url-handling.js 86.55% <50.00%> (+0.02%) ⬆️
src/reducers/url-state.js 96.00% <77.77%> (-0.90%) ⬇️
src/components/shared/CallNodeContextMenu.js 89.95% <85.71%> (-0.29%) ⬇️
src/test/fixtures/profiles/processed-profile.js 94.57% <91.66%> (-0.12%) ⬇️
src/profile-logic/profile-data.js 93.59% <94.28%> (+0.02%) ⬆️
src/components/calltree/CallTree.js 92.13% <100.00%> (+0.92%) ⬆️
src/components/flame-graph/FlameGraph.js 83.83% <100.00%> (+5.40%) ⬆️
src/components/stack-chart/index.js 86.66% <100.00%> (-0.22%) ⬇️
src/profile-logic/call-tree.js 94.16% <100.00%> (+0.33%) ⬆️
... and 3 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

@julienw

julienw commented Feb 17, 2023

Copy link
Copy Markdown
Contributor

If the source view is displaying source code, double-clicking a profiler label frame (which doesn't have an associated source file) will now clear the source view.

This makes me think that we should try to have a way to map this back to where the label frame is inserted and show the source code.

@mstange

mstange commented Feb 17, 2023

Copy link
Copy Markdown
Contributor Author

If the source view is displaying source code, double-clicking a profiler label frame (which doesn't have an associated source file) will now clear the source view.

This makes me think that we should try to have a way to map this back to where the label frame is inserted and show the source code.

That would be ideal, but I'm not sure how to make it work. Storing information about file + line number in the profiling stack would require additional space and additional instructions per push/pop, and I worry that it might penalize WebIDL binding performance and code size.

@julienw julienw left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this work, this looks pretty solid!
I have a few comments related to "where this code should go", a few questions, and a few nits (some of them optional).
I'm approving so that you can land this after handling these.

Please ping me if you have questions!

Comment thread src/types/profile.js Outdated
Comment thread src/types/state.js
Comment on lines +266 to +267
// When this is incremented, the assembly view scrolls to the "hotspot" line.
activationGeneration: number,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then, should that be called scrollGeneration, if this controls the scroll operation?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll fix this in a separate patch because the source view does the same.

Comment thread src/test/fixtures/profiles/processed-profile.js Outdated
Comment thread src/test/fixtures/profiles/processed-profile.js Outdated
Comment thread src/types/state.js
Comment on lines +3384 to +3385
* the frame table, and adding one byte (because the instruction at that address
* is at least one byte long).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably a very naive quesiton:
you write "at least one byte long", so this means that this can be longer, right?
In that case, shouldn't we take the largest possible size for an instruction instead?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be longer, but this function computes a lower bound for the function size, so we should take the smallest possible size. Otherwise we might disassemble instructions from the next function by accident. We don't want to overrun.

Comment thread src/profile-logic/profile-data.js Outdated
* cases, a call node can have its native code in multiple different functions,
* for example if it was inlined into multiple different functions.
* Another way to get multiple native symbols here is if a call tree transform
* collapsed frames from different original functions into a merged function.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the inverted call tree another example (like mentioned elsewhere)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'll adjust the sentence about "inlined into multiple different functions" to mention the inverted tree.

Comment thread src/profile-logic/profile-data.js Outdated

const nativeSymbolSet = new Set(
[
...getNativeSymbolsForCallNode(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the result of getNativeSymbolsForCallNode have a lot of items? My understanding is that this is very unlikely, but could that happen for inverted trees for example? In that case would it make sense to iterate the Set with (for example) a for .. of and create the new one with set.add?

On another hand, it doesn't look like that having a Set for nativeSymbolSet is useful since it contains objects. What do you think of using an Array for this data?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the vast majority of cases it will be 1 element, sometimes 2 or 3, and probably never more than 100 (though you could create a synthetic testcase with an arbitrary amount).

Using an array sounds good to me!

Comment thread src/reducers/app.js Outdated
@@ -145,6 +145,7 @@ const panelLayoutGeneration: Reducer<number> = (state = 0, action) => {
case 'POP_COMMITTED_RANGES':
// Bottom box: (fallthrough)
case 'OPEN_SOURCE_VIEW':

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this OPEN_SOURCE_VIEW was forgotten

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

Comment thread src/types/state.js
transforms: TransformStacksPerThread,
timelineType: TimelineType,
sourceView: SourceViewState,
assemblyView: AssemblyViewState,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that his is not (un/)serialized in the url-handling code, do you intend to serialize this data later? If not, it might make sense to move it to another state, maybe AppState?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do intend to serialize this data later. I have the patch (it's in the full series in the other PR) but I wanted to write tests for it first.

This also changes [address:...] to not use a "0x" before the address,
for consistency.
@mstange mstange force-pushed the assembly-view-part-1 branch from 4533a8b to 68c8d45 Compare February 17, 2023 20:12
@mstange mstange merged commit e0b59d0 into firefox-devtools:main Feb 17, 2023
mstange added a commit to mstange/perf.html that referenced this pull request Feb 18, 2023
I missed these when addressing review comments in firefox-devtools#4478.
julienw pushed a commit that referenced this pull request Feb 20, 2023
I missed these when addressing review comments in #4478.
@canova canova mentioned this pull request Feb 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants