Skip to content

Share stackTable, frameTable, funcTable, resourceTable and nativeSymbols between threads - #5482

Merged
mstange merged 9 commits into
firefox-devtools:mainfrom
mstange:share-everything
Mar 2, 2026
Merged

Share stackTable, frameTable, funcTable, resourceTable and nativeSymbols between threads#5482
mstange merged 9 commits into
firefox-devtools:mainfrom
mstange:share-everything

Conversation

@mstange

@mstangemstange commented Jun 4, 2025

Copy link
Copy Markdown
Contributor

Production | Deploy preview

Sharing the string table happened in #5481.
This PR makes us share the rest, and completes issue #3918.

Only samples and markers are still per-thread. I don't expect this to change.
This includes allocation samples.

To do:

  • Fix type check and test failures
  • Upgrade the URL when upgrading the profile, to remap function indexes etc. in the URL
  • When compacting during upload, apply translation tables to redux state (e.g. update focus function indexes in URL)
  • Do something to address perf impact for computing the derived thread (transforms and call node table computation happen per thread and take longer if the tables are bigger because they now contain information for all threads, should be able to reuse more of the computed outputs in the thread derivation pipeline)
  • Memoize the computation of the implementation filtered thread across threads
  • Adjust indexes in transforms when merging two different profiles
  • Add a paragraph to CHANGELOG-formats.md for the new version.
  • Add a test for merging profiles with applied transforms where we actually check the filtered call tree

Potential follow-ups:

  • Add a test checking that IndexIntoSourceTable indexes in the redux state are updated after profile sanitizing
  • Add a test checking that collapse-resource transforms aren't broken if profile sanitizing adds elements to the funcTable

@vlasakm

Copy link
Copy Markdown

This is really great! Sharing this data across threads works especially well for applications where there is a large number of threads, but just a few "thread pools" whose threads are all executing the same code.

Using this allowed me to employ better caching when creating a firefox profile, save on the profile size, etc.

It also made me greedy, and I attempted to visualize a rather large profile (1602 threads, 577108 stacks, 29760 frames). Previously my experience was that Firefox Profiler would choke on say more than 300+ threads, and I hoped this change with sharing could improve the situation. Now it loads, and the UI is still quite responsive, but the load of the profile is taking long 2 minutes 15 seconds (and Firefox prompts to kill the script, etc.).

90 % of the load time is spent is in computeCallNodeTable, which I believe may be called repeatedly for each thread (and the merged thread which includes all of them), even though all these calls would process the same stack table and frame table, now that they are shared.

I know very little about React/Redux, but I see that there's some concept of memoization and thread selectors, that is still used for call nodes, even though after this change to share the stack and frame table. Very naively, would it perhaps be possible to just compute and memoize the call node information once by not using the thread selector mechanism here? But there's a great chance I am missing all the needed context.

FWIW I was and am still using this branch for quite some time. I am not sure if I am able to contribute much (I even failed to rebase it on top of more recent changes), but it would be great to see this, perhaps after all the big work-in-progress changes land (like the Typescript migration).

@mstange

Copy link
Copy Markdown
ContributorAuthor

Yes indeed, sharing the computed call node table across threads while properly handling per thread transforms is the next thing I want to work on when I get back to this task. Thanks for the encouragement and it's great to hear that you're seeing real improvements from it!

@mstange
mstangeforce-pushed the share-everything branch 4 times, most recently from 24a4604 to 8d957f0CompareJanuary 29, 2026 23:25
@codecov

codecovBot commented Jan 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.69092% with 175 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.36%. Comparing base (19aa5e9) to head (850e4ff).
⚠️ Report is 11 commits behind head on main.

Files with missing linesPatch %Lines
src/app-logic/url-handling.ts12.50%63 Missing ⚠️
src/profile-logic/transforms.ts29.41%48 Missing ⚠️
src/profile-logic/profile-compacting.ts87.96%25 Missing and 1 partial ⚠️
src/profile-logic/sanitize.ts88.60%9 Missing ⚠️
src/reducers/code.ts50.00%6 Missing ⚠️
src/profile-logic/merge-compare.ts96.66%5 Missing ⚠️
src/profile-logic/profile-data.ts94.73%5 Missing ⚠️
src/reducers/url-state.ts80.00%5 Missing ⚠️
src/profile-logic/processed-profile-versioning.ts97.87%3 Missing ⚠️
src/profile-logic/index-translation.ts90.47%2 Missing ⚠️
... and 2 more
Additional details and impacted files
@@ Coverage Diff @@## main #5482 +/- ##
==========================================
- Coverage 85.56% 85.36% -0.20% 
==========================================
Files 319 320 +1 Lines 31499 31916 +417 Branches 8697 8780 +83 ==========================================
+ Hits 26953 27246 +293 - Misses 4115 4239 +124 
Partials 431 431 

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mstange
mstangeforce-pushed the share-everything branch 4 times, most recently from a5b1248 to 4b18e81CompareJanuary 30, 2026 18:40
This was referenced Jan 30, 2026
canova added a commit that referenced this pull request Feb 2, 2026
Small things I noticed while working on #5482.
@mstange
mstange marked this pull request as ready for review February 2, 2026 20:00
@mstange

Copy link
Copy Markdown
ContributorAuthor

This is now ready for review.

@mstange
mstangeforce-pushed the share-everything branch 2 times, most recently from ce546d0 to 0d1cc61CompareFebruary 2, 2026 21:18
mstange added a commit that referenced this pull request Feb 3, 2026
More small stuff that makes #5482 a tiny bit easier.
@mstange
mstange requested a review from canovaFebruary 3, 2026 15:35
@mstange
mstangeforce-pushed the share-everything branch 3 times, most recently from d1916d3 to cf780f4CompareFebruary 3, 2026 17:04

@canovacanova left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I promised myself that I would be done with reviewing this PR today, but I underestimated the amount of changes here 😅 I'm done-ish with the first commit, which is the main beast. So pushing the review comments now even though I still need to review the others.

Comment threadsrc/profile-logic/global-data-collector.ts Outdated
Comment threadsrc/actions/app.ts Outdated
Comment threadsrc/actions/receive-profile.ts
Comment threadsrc/app-logic/url-handling.ts Outdated
Comment threadsrc/profile-logic/processed-profile-versioning.ts
Comment threadsrc/profile-logic/processed-profile-versioning.ts Outdated
Comment threadsrc/profile-logic/processed-profile-versioning.ts Outdated
Comment threadsrc/profile-logic/global-data-collector.ts
Comment threadsrc/app-logic/url-handling.ts
Comment threadsrc/profile-logic/merge-compare.ts Outdated

@canovacanova left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm done reviewing the rest of the PR! (I saw the github's unicorn error message quite a few times while doing so 😄) It was a lot easier to review the other commits. I think it looks good to me with the issues I raised yesterday fixed. I would prefer to take a look at the PR once more once these are fixed though. But I assume that review will be a lot more quicker.

Comment threadsrc/reducers/code.ts
Comment threadsrc/profile-logic/profile-compacting.ts
Comment threadsrc/profile-logic/merge-compare.ts
Comment threadsrc/profile-logic/merge-compare.ts Outdated
Comment threadsrc/profile-logic/index-translation.ts Outdated
Comment threadsrc/profile-logic/merge-compare.ts
Comment threadsrc/selectors/per-thread/stack-sample.ts
@canova

Copy link
Copy Markdown
Member

Ah another question, I see that there are 2 items unchecked in the list. Are they done? I think we can also do those as follow-ups as they don't look critical.

@mstange

Copy link
Copy Markdown
ContributorAuthor

Ah another question, I see that there are 2 items unchecked in the list. Are they done? I think we can also do those as follow-ups as they don't look critical.

Ah yes, I took a brief look at this and it didn't look straightforward to add those tests, so I'll leave those two items for potential follow-ups. Edited the PR description.

@mstange
mstangeforce-pushed the share-everything branch 2 times, most recently from 31327b6 to 02779d1CompareMarch 2, 2026 03:21

@canovacanova left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, looks great! Let's land it before it gets more bitrotted 😄

mstangeand others added 9 commits March 2, 2026 11:02
…Symbols across threads.
This makes func indexes etc valid globally instead of scoped per threads.
It also allows for smaller profiles because data doesn't have to be duplicated.
Symbolication is probably faster.
Selecting multiple threads, i.e. displaying a "merged thread", is now easier because
we no longer need to compute merged funcTables etc for the merged thread; the global
tables are already "merged".
This also also means that func index mapping during symbolication now works even if
multiple threads are selected. Fixesfirefox-devtools#5703.
This profile version comes both with a profile upgrader and with a URL upgrader,
because we have to adjust any func and resource indexes for transforms in the URL.
We also need to adjust any indexes in the redux state after compacting,
for example funcTable or resourceTable indexes used by transforms.
This patch also makes us adjust the source index in the URL after compaction.
Strictly speaking this fixes an existing bug, because the source table
was already being compacted.
It also fixes the bug where we weren't keeping track of the oldFuncCount properly
when splitting functions into private-window and non-private-window instances,
and weren't updating collapse-resource transforms correctly. Fixesfirefox-devtools#5793.
We compute the call node table based on the filtered thread, per thread.
But now that every thread contains the full stackTable with entries used
by all threads, this computation has become much more expensive.
But most of the time we are passing the same tables from the shared profile
info, so we can just do the work once and share it across threads.
This only fixes the case where none of the threads have a transform applied.
They'll end up passing the tables from the shared data and hit the memoization
cache.
If a thread has a transform, it'll pass different tables and not hit the cache.
We don't do anything to share work across two threads that happen to have the
same transforms.
This also doesn't fix the case where there's an implementation filter applied.
Here's how loading the profile https://share.firefox.dev/4bxDqu8 compares:
- Before sharing the tables: https://share.firefox.dev/4r0imRO (1.1 seconds)
- After sharing the tables, no global memoization: https://share.firefox.dev/4qNGp6m (1.8 seconds)
- After sharing the tables, with global memoization: https://share.firefox.dev/4rwkwso (1.3 seconds)
…threads.
Here's how loading the profile https://share.firefox.dev/4kbkjrU compares:
- Before sharing the tables: https://share.firefox.dev/4kh5i84 (1.1 seconds)
- After sharing the tables, no global memoization: https://share.firefox.dev/3NLn1IK (1.6 seconds)
- After sharing the tables, with global memoization: https://share.firefox.dev/3LNNuot (1.3 seconds)
Here's how loading the profile https://share.firefox.dev/4a0b88Y compares:
- Before sharing the tables: https://share.firefox.dev/4qeiVGu (1.1 seconds)
- After sharing the tables, no global memoization: https://share.firefox.dev/3NUEi27 (2.0 seconds)
- After sharing the tables, with global memoization: https://share.firefox.dev/4qcDQty (1.3 seconds)
@mstange
mstange enabled auto-merge March 2, 2026 16:02
@mstange

Copy link
Copy Markdown
ContributorAuthor

Thanks for the review!

@mstange
mstange merged commit 78d0ebb into firefox-devtools:mainMar 2, 2026
19 checks passed
@canovacanova mentioned this pull request Mar 3, 2026
canova added a commit that referenced this pull request Mar 3, 2026
Changes:
[fatadel] Fix crash when nativeSymbol index is out of bounds in assembly
view (#5850)
[depfu[bot]] Update all Yarn dependencies (2026-02-25) (#5859)
[Nazım Can Altınova] Fix the color of dark mode back arrow svg (#5863)
[fatadel] Force canvas redraw when system theme changes (#5861)
[Nazım Can Altınova] Fix unhandled promise rejection in
setupInitialUrlState (#5864)
[fatadel] Persist selected marker in URL and show sticky tooltip on load
(#5847)
[Markus Stange] Implement the "collapse resource" transform with the
help of the "collapse direct recursion" transform. (#5824)
[Markus Stange] Bump rollup from 2.79.2 to 2.80.0 (#5868)
[Markus Stange] Remove async attribute from module script tag. (#5870)
[Nazım Can Altınova] Update the docsify package that's used in the user
documentation (#5872)
[Markus Stange] Share stackTable, frameTable, funcTable, resourceTable
and nativeSymbols between threads (#5482)
[Nazım Can Altınova] Escape CSS URLs that are coming from profiles
(#5874)
[fatadel] Update home page message for the other browser case (#5866)
[fatadel] Add support for ternaries in marker labels (#5857)
[Markus Stange] Reduce allocations for getStackLineInfo +
getStackAddressInfo (#5761)
And special thanks to our localizers:
de: Ger
fy-NL: Fjoerfoks
it: Francesco Lodolo [:flod]
nl: Fjoerfoks
ru: berry
ru: Valery Ledovskoy
zh-TW: Pin-guang Chen
@mstangemstange mentioned this pull request May 20, 2026
Sign up for freeto 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.

3 participants

@mstange@vlasakm@canova