Skip to content

Remove frameTable.implementation from the processed format.#5370

Merged
mstange merged 2 commits into
firefox-devtools:mainfrom
mstange:remove-implementation
Feb 24, 2025
Merged

Remove frameTable.implementation from the processed format.#5370
mstange merged 2 commits into
firefox-devtools:mainfrom
mstange:remove-implementation

Conversation

@mstange

@mstange mstange commented Feb 14, 2025

Copy link
Copy Markdown
Contributor

Fixes #3713.

A frame's "implementation" was used to differentiate various JIT tiers. We now have subcategory information which fulfills this job more accurately.

So we can get rid of this extra data and reduce profile sizes.

This also lets us remove a lot of code.

I have a 3.1GB profile which contains 200MB of ,null for the implementation column. With this change that profile becomes 200MB smaller.


This PR leaves the Gecko format unchanged. As a follow-up we should write a Gecko patch and also bump the Gecko version, but there's no rush to do so; making this change only for the processed format achieves a large part of the benefits.

@mstange mstange requested a review from julienw February 14, 2025 03:58
@mstange mstange self-assigned this Feb 14, 2025
@mstange mstange changed the title Remove frameTable.implementation. Remove frameTable.implementation from the processed format. Feb 14, 2025
@mstange mstange force-pushed the remove-implementation branch 2 times, most recently from 1ea2980 to b95d71b Compare February 14, 2025 04:08
@codecov

codecov Bot commented Feb 14, 2025

Copy link
Copy Markdown

Codecov Report

Attention: Patch coverage is 94.11765% with 2 lines in your changes missing coverage. Please review.

Project coverage is 85.97%. Comparing base (e5d011b) to head (f0c083f).
Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
src/profile-logic/processed-profile-versioning.js 93.54% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5370      +/-   ##
==========================================
- Coverage   85.97%   85.97%   -0.01%     
==========================================
  Files         312      312              
  Lines       30355    30252     -103     
  Branches     8297     8256      -41     
==========================================
- Hits        26098    26009      -89     
+ Misses       3660     3646      -14     
  Partials      597      597              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@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.

This looks generally good, but please look at my comment below.
Also I remember we had some discrepencies between the implementation data vs the subcategory data, and I think we wanted to investigate where this comes from before removing them at all.
Here is an example I just captured: https://share.firefox.dev/42VYaHv
I think that the subcategory data is more precise but I also think that because it's diffently captured it might be wrong sometimes? I don't know and it may not be super important... But good to hear about your opinion on that!

Comment on lines +2376 to +2442
// The `implementation` column was removed from the frameTable. Modern
// profiles from Firefox use subcategories to represent the information
// about the JIT type of a JS frame.
for (const thread of profile.threads) {
delete thread.frameTable.implementation;
}

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 was wondering about converting this data into subcategory-based data, for these profiles that don't have subcategories.
But that's probably also very old profiles, so maybe not worth it.
What do you think?

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.

For example:

production
deploy preview

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 think those profiles are old enough that people won't be interested in the JIT tiers anymore. But I'll take a look anyway, if it's really easy to migrate it may be worth doing.

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've added a commit on top which migrates the information. It doesn't attempt to detect interpreter C++ frames or other C++ frames. This would be more work and I don't think it would be worth doing.

@mstange

mstange commented Feb 14, 2025

Copy link
Copy Markdown
Contributor Author

I remember we had some discrepencies between the implementation data vs the subcategory data, and I think we wanted to investigate where this comes from before removing them at all. Here is an example I just captured: https://share.firefox.dev/42VYaHv

Sure, I can go through a few example stacks.

Link Implementation Subcategory
https://share.firefox.dev/3CHJb9E JS JIT (ion) JIT Compile (Baseline) Subcategory is more accurate; a function which is running in Ion is calling another function which is first getting baseline compiled.
https://share.firefox.dev/4b2oaTR JS JIT (baseline) JIT Compile (Ion) Subcategory is more accurate; a function which is running in Baseline is calling another function which is first getting Ion compiled.
https://share.firefox.dev/3CSNIWC JS JIT (blinterp) Parsing Subcategory is more accurate; a function which is running in Baseline-interpreter is calling a DOM method PrecompiledScript.executeInGlobal which needs to instantiate the parsed "stencil" representation of the executed script via js::frontend::InstantiateStencils.

I can look at more examples but the general pattern is the same: Subcategories are "finer". That's because subcategories can be set on profiler labels, whereas the implementation can only be set on JS function frames. And we have labels in more places than we have running JS functions.

And if I'm doing JS parsing during my Baseline JIT execution, I usually don't want to attribute that to "running Baseline JIT code" because the self time is not in the JIT code.

I think that the subcategory data is more precise but I also think that because it's diffently captured it might be wrong sometimes? I don't know and it may not be super important... But good to hear about your opinion on that!

I think it would be valid to say that the subcategory information is incomplete, for example there's no subcategory for time spent in Baseline ICs or in Ion ICs or in trampolines. But I can't think of a case where it's less correct than the "implementation" information.

Sometimes you do want to know "what's the JIT tier of the closest JS function further up the stack?" and the implementation answers that, mostly (unless it says "Native"). With subcategories you can answer this question by switching to the JS-only tree and by looking at the tooltip of the category square of the deepest JS function call node.

@mstange mstange force-pushed the remove-implementation branch 2 times, most recently from ac86bff to c65838b Compare February 23, 2025 02:17
@mstange mstange requested a review from julienw February 23, 2025 02:20

@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, now I'm convinced that the new data is better :-)

const subcategoryForImplStr = new Map();

for (const thread of profile.threads) {
const subcategoryForImplStrIndex = new Map();

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've been wondering if this 1st level of caching was really useful but I also don't mind.
(I guess it's saving a stringArray lookup + probably the map operation with an integer is faster?)

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.

yeah I was wondering the same thing, I think I'll just simplify it away

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.

done

@mstange mstange force-pushed the remove-implementation branch from c65838b to f0c083f Compare February 24, 2025 18:33
@mstange mstange enabled auto-merge February 24, 2025 18:33
@mstange mstange merged commit 7a2b1cb into firefox-devtools:main Feb 24, 2025
@julienw julienw mentioned this pull request Mar 3, 2025
julienw added a commit that referenced this pull request Mar 3, 2025
[Julien Wajsberg] Update node to v22 (#5378)
[Markus Stange] Speed up createCallNodeTable by 2.3x (#5248)
[Markus Stange] Remove frameTable.implementation from the processed format. (#5370)
[Florian Quèze] Show size units in the timeline for profiles where profile.meta.sampleUnits.time is "bytes". (#5364)
[Sean Kim] Report nsIRequest::status (nsresult) in the marker (#5375)
[Markus Stange] Change the marker schema to accept a description and get rid of the notion of static fields (#5385)

Also thanks to our localizers:
en-CA: Paul
tr: Grk
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.

Re-evaluate whether we need the "implementation" concept, or if subcategories are enough

2 participants