`profiler_capture_backtrace_into` now only uses thread-safe functions: ThreadRegistration::WithOnThreadRefOf, Register::SyncPopulate, DoSyncSample.
So we don't need to lock the main profiler mutex anymore.
This means that on-thread sampling (typically used in markers) can happen at the same time the periodic sampler has locked the profiler mutex and is sampling this and other threads.
Differential Revision: https://phabricator.services.mozilla.com/D122089
Since these functions don't need to access profiler functions requiring a lock, they themselves don't need that lock anymore.
Differential Revision: https://phabricator.services.mozilla.com/D122088
MergeStack requires a fairly large buffer to store JS frames, too big to be allocated on the stack without risking a stack overflow.
Until now, there was only one buffer, stored in CorePS, and only accessible while holding the Profiler gPSMutex.
Now each thread that has a JSContext, also has its own JS frame buffer, which is accessible on the thread without needing any lock.
The Profiler's Sampler still uses the CorePS buffer for its periodic sampling, but it won't prevent parallel on-thread sampling anymore.
The appropriate buffer is passed to ExtractJsFrames and then MergeStacks.
MergeStacks accepts a null pointer, which happens on threads where there is no JSContext, and therefore no JS to sample.
Differential Revision: https://phabricator.services.mozilla.com/D122087
All implementations of DoNativeBacktrace are now thread-safe, so it's not necessary to make their use dependent on the Profiler's gPSMutex being locked.
Differential Revision: https://phabricator.services.mozilla.com/D122085
`Registers::SyncPopulate()` now uses a ucontext_t that's stored with the `Registers` object, so it can safely be called from parallel threads.
Differential Revision: https://phabricator.services.mozilla.com/D122083
`profiler_capture_backtrace_into` now only uses thread-safe functions: ThreadRegistration::WithOnThreadRefOf, Register::SyncPopulate, DoSyncSample.
So we don't need to lock the main profiler mutex anymore.
This means that on-thread sampling (typically used in markers) can happen at the same time the periodic sampler has locked the profiler mutex and is sampling this and other threads.
Differential Revision: https://phabricator.services.mozilla.com/D122089
Since these functions don't need to access profiler functions requiring a lock, they themselves don't need that lock anymore.
Differential Revision: https://phabricator.services.mozilla.com/D122088
MergeStack requires a fairly large buffer to store JS frames, too big to be allocated on the stack without risking a stack overflow.
Until now, there was only one buffer, stored in CorePS, and only accessible while holding the Profiler gPSMutex.
Now each thread that has a JSContext, also has its own JS frame buffer, which is accessible on the thread without needing any lock.
The Profiler's Sampler still uses the CorePS buffer for its periodic sampling, but it won't prevent parallel on-thread sampling anymore.
The appropriate buffer is passed to ExtractJsFrames and then MergeStacks.
MergeStacks accepts a null pointer, which happens on threads where there is no JSContext, and therefore no JS to sample.
Differential Revision: https://phabricator.services.mozilla.com/D122087
All implementations of DoNativeBacktrace are now thread-safe, so it's not necessary to make their use dependent on the Profiler's gPSMutex being locked.
Differential Revision: https://phabricator.services.mozilla.com/D122085
`Registers::SyncPopulate()` now uses a ucontext_t that's stored with the `Registers` object, so it can safely be called from parallel threads.
Differential Revision: https://phabricator.services.mozilla.com/D122083
Instead of blindly outputting floating-point numbers of milliseconds, which leads to things like 363.03499999999997, times in ms are now converted to integer number of nanoseconds, stringified, and then manually adjusted to milliseconds again, so we get smaller and friendlier outputs like 363.035.
Eventually, bug 1726675 may change all times to integer number of nanoseconds anyway, but this patch is already helpful in reducing the output, and paves the way by separating the time-output functions from other number outputs.
Differential Revision: https://phabricator.services.mozilla.com/D123329
The purpose of this is to remove as many docstrings from CommandProvider
classes to make the step of moving commands out of classes simpler.
Where possible, the docstring has been moved to or merged with the function.
Differential Revision: https://phabricator.services.mozilla.com/D123288
It's more appropriate because the running times are only relevant to a profiling session.
And PreviousThreadRunningTimes can now be accessed through the ThreadRegistration (thanks to the ProfiledThreadData pointer added in the previous patch).
Since the threads' RunningTimes don't live in `PlatformData`, and because they are now implicitly cleared between profiling sessions (because `ProfiledThreadData`s get destroyed/recreated when stopping/starting the profiler), there is no need for an explicit `ClearRunningTimes()` anymore.
Differential Revision: https://phabricator.services.mozilla.com/D121964
Because ProfiledThreadData is always related to IsBeingProfiled, they are set and cleared together.
In particular, this is used to quickly guess that the thread is being profiled by reading the non-atomic mProfiledThreadData, rather than reading the slightly slower atomic mIsBeingProfiled.
Differential Revision: https://phabricator.services.mozilla.com/D121963
This is mostly a copy of the old PlatformData. That old PlatformData will be removed in a later patch, once it's not used anymore.
Differential Revision: https://phabricator.services.mozilla.com/D121959
This will help with replacing the old {,Racy}RegisteredThread with the new ThreadRegistration classes, while still being able to access the old classes (until they are not needed anymore).
Differential Revision: https://phabricator.services.mozilla.com/D121849
Now {,Racy}RegisteredThread don't contain any data, but provide the same API that goes through ThreadRegistration.
Until they are removed, {,Racy}RegisteredThread are given private access to ThreadRegistration{,Data} for easier access.
This means that we can now change uses of RegisteredThread to use ThreadRegistration directly instead, and the data will be the same through either APIs.
Also, RacyRegisteredThread::ThreadId() was unused so it can be removed.
Differential Revision: https://phabricator.services.mozilla.com/D121847
The ProfilingStack object inside ThreadRegistrationData is guaranteed to live while the thread is registered (and alive), and all accesses are guaranteed to be done either:
- On-thread, so during that time ThreadRegistrationData and its ProfilingStack cannot be destroyed.
- From another thread, but with the Profiler lock and/or per-thread lock, which also guarantees that ThreadRegistrationData and its ProfilingStack cannot be destroyed.
RacyRegisteredThread brought some doubts about end-of-thread accesses, that why there's was an intermediate ref-counted ProfilingStackOwner to keep ProfilingStack alive where needed. Now we can remove it.
Also the separate TLS (Thread Local Storage) for ProfilingStackOwner can be removed, since we can reach the ProfilingStack through the ThreadRegistration TLS for the same cost.
Differential Revision: https://phabricator.services.mozilla.com/D121846
Since ThreadRegistration already handles nested registrations, the legacy profiler_{,un}register_thread() functions don't need to care about that anymore (and the RegisteredThread TLS will be removed in a later patch anyway).
The informational markers have been moved to ProfilerThreadRegistration.cpp.
Differential Revision: https://phabricator.services.mozilla.com/D122315
ProfilerThreadRegistry (un)register functions have been moved to platform.cpp because they need to interact closely with functions and classes in that file.
profiler_{,un}register_thread are now simple calls to ThreadRegistration::{R,Unr}egisterThread, which call ThreadRegistry::{R,Unr}egister, which now integrate that old bodies of profiler_{,un}register_thread.
So from this point, threads may use either profiler_{,un}register_thread or ThreadRegistration equivalents, and this will (un)register with both the new ThreadRegistration classes and the legacy RegisteredThread class into CorePS. (Later patches will remove RegisteredThread completely.)
Bonus: Since the stack top is now adjusted when constructing ThreadRegistrationInfo (before giving it to the legacy ThreadInfo), there is no more need for `GetStackTop()`.
Differential Revision: https://phabricator.services.mozilla.com/D121844
Thread-related APIs that are currently in ProfilerState.h will move here, and will use the new ThreadRegistration classes introduced in bug 1721939.
In this patch the header is empty apart from a few #includes, and users of "ProfilerState.h"'s thread functions now #include "ProfilerThreadState.h" instead. So there are no actual code changes yet.
Differential Revision: https://phabricator.services.mozilla.com/D121843
When a `ThreadRegistration` object is created through `ThreadRegistration::RegisterThread` (instead of directly on the stack), this is recorded in `mIsOnHeap`.
This helps better handle incorrectly-nested registration/unregistration pairs, or excess unregistrations.
Also, markers are now generated to highlight extra (un)registrations, with added backtrace for those surprising cases of excess unregistrations that should probably be reworked.
And `ThreadRegistration::GetTLS()` was simplified, so it auto-initializes when first used, instead of relying on the main thread registration.
Differential Revision: https://phabricator.services.mozilla.com/D123229
Sampling overheads are very rarely useful, but they occupy some space during profiling, but also a lot of space in the final JSON profile.
So now they will only be recorded if the environment variable "MOZ_PROFILER_RECORD_OVERHEADS" is set to any non-empty value.
Differential Revision: https://phabricator.services.mozilla.com/D123303
This ensures our users will use the latest version of the frontend when
capturing 'cancel' network markers.
Depends on D123254
Differential Revision: https://phabricator.services.mozilla.com/D123255
This patch supports channel cancelations with network markers.
Because of all the possible ways to stop a channel and hence all
possible end markers, it also introduces a new boolean to reduce the
complexity. Indeed it happens that 2 "end functions" are called, but we
need to insert only 1 end marker to have a well-formed result in the
Profiler frontend.
Differential Revision: https://phabricator.services.mozilla.com/D122111