It is possible that some threads fail/forget to unregister themselves, in which case a registered thread id could get recycled by a later thread, which was not allowed before this patch.
Note: The thread name cannot currently be changed. We record a special marker with the new name, so the frontend could process it to split the thread track at that point.
We also record a marker when profiler_unregister_thread is called from an already-unregistered thread, this could help find reg/unreg mismatches or nesting in Firefox threads.
Differential Revision: https://phabricator.services.mozilla.com/D83293
On Linux (including Android), it was assumed that a registered thread could always be suspended through `tgkill`.
However in some cases a thread may not be correctly unregistered, in which case this would trigger `MOZ_ASSERT` or wait forever in the following loop.
This will especially be needed when `profiler_{,un}register_thread()` are made less strict in the following patch.
Windows and Mac already handle suspension failures.
Differential Revision: https://phabricator.services.mozilla.com/D83292
To avoid deadlocks between the buffer main mutex and the externally-provided update callback code, the callback storage is now using a separate mutex, and both mutexes are never held at the same time.
Differential Revision: https://phabricator.services.mozilla.com/D82141
The profiler can be "paused", which stops sampling, and since bug 1578329 stops markers as well.
Some test suites use pausing between tests (to better differentiate the tests, to keep the profiler ready to run, and to lower the amount of recorded data). But this causes problems with some tracing markers, as their matching ends have not been recorded (e.g., an end marker is missing), which show up as very loooong markers.
To solve this, we need to be able to pause sampling only, but keep recording markers.
But we still need to be able to pause the whole profiler, in particular before capturing, to avoid recording anything around that time.
This big patch is mostly mechanical changes: Wherever there are "Pause" and "Unpause/Resume" profiler functions, we add matching "PauseSampling" and "UnpauseSampling/ResumeSampling" functions that only impact the periodic sampling loop; And existing "Pause/Unpause/Resume" imply pausing sampling as well.
Exceptions and extra work:
- nsIProfiler (the JS API) already had `Pause/ResumeSampling()`, which misleadingly paused everything! Now they do the right thing, and we have `Pause/Resume()` as well.
- All tests using `Pause/ResumeSampling()` now use `Pause/Resume()`, except for Talos tests that only pause sampling between tests; Added some extra `Pause()` calls to pause everything before capturing profiles.
- GeckoJavaSampler doesn't handle pausing/resuming everything, this should be done in a follow-up bug.
- Sampling-only pauses are not streamed into JSON. If needed, we should follow-up, with potential work on the front-end to deal with these.
Differential Revision: https://phabricator.services.mozilla.com/D81492
This was previously r=jchen and landed, but was backed out because some
Android tests were running on an unrealistically old Linux kernel. These
tests have been retired, so this can reland.
Differential Revision: https://phabricator.services.mozilla.com/D81278
Bug 1486524 disabled the features from the custom linker that required
AutoObjectMapperFaultyLib. We can now rely on AutoObjectMapperPOSIX
instead.
Differential Revision: https://phabricator.services.mozilla.com/D81264
The Base Profiler is still recent and barely used, so it may contain some bugs.
With bug 1586939, the Base Profiler is now used more often because it is controlled the same way as the Gecko Profiler.
This has surfaced some intermittent issues, which pollute existing tests.
Until the root cause is found (see bug 1648325), setting `MOZ_PROFILER_STARTUP_NO_BASE=1` prevents the Base Profiler from running. This may be used where problems are visible, to diagnostic them and/or reduce them where needed.
Differential Revision: https://phabricator.services.mozilla.com/D81018
This function can be called whether the profiler mutex is locked or not. If locked, the provided pointer to the profiler mutex is used internally, otherwise the mutex will be locked as needed.
Differential Revision: https://phabricator.services.mozilla.com/D79412
PSAutoTryLock attempts to lock the mutex, but gives up immediately if it's already locked.
This can be used in profiler functions that may be called from unknown code, to avoid deadlocks involving the profiler mutex and another mutex that could be indirectly used by the profiler itself.
Differential Revision: https://phabricator.services.mozilla.com/D79410
In the JIT frame sampler, we apply the appropriate category in addition to
the "implementation" field. For JS frames (IS_JS_FRAME), we identify as
either BaselineInterpreter or Interpreter. Note that JS_Other still applies
to various places we enter SpiderMonkey outside of RunScript.
Differential Revision: https://phabricator.services.mozilla.com/D79524
Replace the duplicate lists in mozglue/baseprofiler/public and js/public with
a shared list. Add this list to both moz.build files so it is published twice
which simplifies supporting different standalone configurations.
Differential Revision: https://phabricator.services.mozilla.com/D79520
Introduce an IS_BLINTERP_FRAME flag to ProfilingStackFrame to distinguish C++
and Baseline interpreter frames. In the profile data this sets the
"implementation" to "blinterp".
Differential Revision: https://phabricator.services.mozilla.com/D78725
Round the number of reserved flag bits up to 16. This leaves 16-bits for the
category (so 64k subcategories). Also make the baseprofiler consistent.
Differential Revision: https://phabricator.services.mozilla.com/D78724
Now both profilers are controlled by the same environment variables, e.g.
"MOZ_PROFILER_STARTUP" to run both profilers at startup.
The only remaining Base Profiler-specific commands are:
- MOZ_BASE_PROFILER_HELP, because the Base Profiler doesn't have the same
capabilities as Gecko, so it may display different available features.
- MOZ_BASE_PROFILER_LOGGING, because the Base Profiler doesn't have access to
MOZ_LOG (both the env-var and the C++ macros).
Differential Revision: https://phabricator.services.mozilla.com/D54449
Now both profilers are controlled by the same environment variables, e.g.
"MOZ_PROFILER_STARTUP" to run both profilers at startup.
The only remaining Base Profiler-specific commands are:
- MOZ_BASE_PROFILER_HELP, because the Base Profiler doesn't have the same
capabilities as Gecko, so it may display different available features.
- MOZ_BASE_PROFILER_LOGGING, because the Base Profiler doesn't have access to
MOZ_LOG (both the env-var and the C++ macros).
Differential Revision: https://phabricator.services.mozilla.com/D54449
This code was not being built any more.
GeckoView requires Android OS version 4.3 (API Level 18). I'm not sure what the
corresponding ANDROID_VERSION macro constant for API Level 18 is, but it's
definitely higher than 16.
Differential Revision: https://phabricator.services.mozilla.com/D73940
In addition to the existing "mainthreadio" feature, we now have:
- "fileio" to also capture file I/O from other profiled threads.
- "fileioall" to also capture file I/O from all threads (even unregistered threads).
- "noiostacks" to prevent capturing stack traces for "io" markers.
These are all off by default, except for `MOZ_PROFILER_STARTUP=1`.
Differential Revision: https://phabricator.services.mozilla.com/D75764
This is a simple compile-time check that the feature numbers go from 0 to N-1, to prevent some mistakes when updating feature lists.
Differential Revision: https://phabricator.services.mozilla.com/D75763
Some markers may be more useful when gathered into a single track, and the main thread is ideal because it's almost always present.
Differential Revision: https://phabricator.services.mozilla.com/D75760
Made StaticBaseProfilerStats a proper class, with more explicit types for measurements and printfs.
Also added the maximum duration in a set, which can be useful to see what the worst case of some code may be.
(Reminder: This code is not built by default, uncomment `# define PROFILER_RUNTIME_STATS` above to enable it.)
Differential Revision: https://phabricator.services.mozilla.com/D75758
Instead of accepting a `UniquePtr<ProfilerMarkerPayload>`, `profiler_add_marker_for_thread` now takes it by `const ProfilerMarkerPayload&`.
All callers can now create the payload on the stack, or as a temporary object. This saves a memory alloc+free for each call.
Differential Revision: https://phabricator.services.mozilla.com/D75912
This patch will do :
- add `Media` markers in related codes
- implement `MediaSampleMarkerPayload` to record the media sample
The advantage of doing so :
- using markers can help us know what happens on the media by a glance without expanding the call stack
- adding sample markers allows us compare the speed of decoding sample in `MediaDecoderStataMachine` and rendering sample in `VideoSink`
Differential Revision: https://phabricator.services.mozilla.com/D74174
This patch will do :
- create a sub-category `Cubeb`
- add `Cubeb` profiling labels in related codes
The advantage of doing so :
- allow us to know the percentage of time respectively we spend on cubeb and non-cubeb codes
More details :
The profiling code would include `<atomic>` which is C++ only, so I can't use the label in `cubeb.c` directly. Instead, I add labels on the `AudioStream` and `AudioCallbackDriver` where we would call cubeb related methods.
Differential Revision: https://phabricator.services.mozilla.com/D74172
This patch will do :
- create a profiling category `Media`
- add `Media` profiling labels in related codes
The advantage of doing so :
- allow us to easily see what operations are related to media playback from the profiled report
More details :
According to the description in the `ProfilingCategory.h`, `topmost profiler label frame in the label stack determines the category pair of that stack`. Therefore, most labels I added are the first task would run on the thread, in order to ensure all its following tasks can be marked as the media playback label as well.
Differential Revision: https://phabricator.services.mozilla.com/D74171
If a label contains a dynamic string that's too long (512 characters or more), instead of just replacing it with "(too long)", we now cut it down to the maximum size, with an ellipsis at the end.
Added test for that in gtest. Also added nearby test for empty strings.
Differential Revision: https://phabricator.services.mozilla.com/D74378
Whenever chunks are about to be destroyed, we try to keep one or two alive, to hopefully fulfill the next request, thereby avoiding a deallocation+allocation pair.
Differential Revision: https://phabricator.services.mozilla.com/D72370
The chunk metadata size is tiny (less than 100 bytes) compared to the buffer size (1MB by default), so it's fine to ignore it while dealing with cross-Firefox limits.
Differential Revision: https://phabricator.services.mozilla.com/D72558
Interface class for a chunk manager that can be controlled: It will provide updates about chunks, and release chunks on command.
Differential Revision: https://phabricator.services.mozilla.com/D72362
profiler_is_locked_on_current_thread() is used to help users avoid calling `profiler_...` functions when the profiler may already have a lock in place, which would prevent a 2nd recursive lock (resulting in a crash or a never-ending wait).
So we must return `true` for any of:
- The main profiler mutex, used by most functions, and/or
- The buffer mutex, used directly in some functions without locking the main mutex, e.g., marker-related functions.
Differential Revision: https://phabricator.services.mozilla.com/D73789
Expose `ProfileChunkedBuffer`'s mutex (if present), so that potential callers can avoid recursive calls that would lock or crash.
Differential Revision: https://phabricator.services.mozilla.com/D73788
Make `BaseProfilerMutex::mOwningThreadId` non-optional, and use it in `IsLockedOnCurrentThread()`, which is similar to the one in Gecko Profiler.
Add related `BaseProfilerMaybeMutex::IsActivatedAndLockedOnCurrentThread()`.
Differential Revision: https://phabricator.services.mozilla.com/D73786
At the time this code was written, JavaScript JIT entry trampolines were
emitting EnterJIT label frames that carried a stack address. From this stack
address, register values could be recovered that would allow native stack
unwinding to resume after getting lost in JIT code.
The EnterJIT label frame was removed in bug 1057082.
Differential Revision: https://phabricator.services.mozilla.com/D73939