This marker option captures a given thread id.
If left unspecified (by default construction) during the add-marker call, the current thread id will be used then.
Differential Revision: https://phabricator.services.mozilla.com/D87244
The main, and only compulsory, marker option is the `MarkerCategory`, which captures the "category pair", as well as the parent category.
Differential Revision: https://phabricator.services.mozilla.com/D88154
The upcoming profiler-specific add-marker function will need to know which `ProfileChunkedBuffer` to serialize to, `profiler_get_core_buffer()` give access to the profiler's buffer, and `CachedCoreBuffer()` keeps it stored in a function-static object.
Differential Revision: https://phabricator.services.mozilla.com/D87256
These string views are similar to `std::string_view`, but they are optimized to be serialized in the profiler buffer, and later deserialized and streamed to JSON.
They accept literal strings, and keep them as unowned raw pointers and sizes.
They also accept any substring reference, assuming that they will only be used as parameters during function calls, and therefore the dependent string will live during that call where these `StringView`'s are used.
Internally, they also allow optional string ownership, which is only used during deserialization and streaming.
This is hidden, so that users are not tempted to use potentially expensive string allocations during profiling; it's only used *after* profiling, so it's less of an impact to allocate strings then. (But it could still be optimized later on, as part of bug 1577656.)
Differential Revision: https://phabricator.services.mozilla.com/D87242
This patch introduces all new files that contain the new markers C++ API and implementation.
They are mostly empty at this time, only including each other as eventually needed, and with `#ifdef MOZ_GECKO_PROFILER` guards.
Rough inclusion diagram: (header <-- includer)
BaseProfilerMarkerPrerequesites.h <-- ProfilerMarkerPrerequesites.h (Useful types: Input string view, marker options)
^ ^
BaseProfilerMarkerDetail.h <-- ProfilerMarkerDetail.h (Implementation details)
^ ^
BaseProfilerMarkers.h <-- ProfilerMarkers.h (Main API)
^ ^--------- ^ ^---------
BaseProfilerMarkerTypes.h | <-- ProfilerMarkerTypes.h | (Common marker types)
^ BaseProfiler.h <-- GeckoProfiler.h (Existing main profiler headers)
Differential Revision: https://phabricator.services.mozilla.com/D87241
This patch ports existing ProfilerMarkerPayload types to draft struct definitions that may be used with the new markers API.
This is just a starting point, they may be changed later on as needed, see meta-bug 1661394.
Differential Revision: https://phabricator.services.mozilla.com/D87259
This is the main public marker API:
- `AddMarkerToBuffer` can be used to store a marker to any buffer. This could be useful to code that wants to store markers outside of the default profiler buffers.
- `baseprofiler::AddMarker`/`profiler_add_marker` store a marker in the appropriate profiler buffer.
- BASE_PROFILER_MARKER and PROFILER_MARKER do the same, but are also defined (and empty) when MOZ_GECKO_PROFILER is not #defined.
All these take a name, marker options, a marker type, and the type's expected arguments if any (as expected by the `StreamJSONMarkerData` function).
Extra helpers for the most common types:
- BASE_PROFILER_MARKER_UNTYPED and PROFILER_MARKER_UNTYPED store a marker with no data payload.
- BASE_PROFILER_MARKER_TEXT and PROFILER_MARKER_TEXT store a text marker. `baseprofiler::markers::Text` is an example of how new marker types can be defined.
Differential Revision: https://phabricator.services.mozilla.com/D87257
Main marker serialization function, which accepts the same arguments (with implicit conversions) as the marker type's `StreamJSONMarkerData(JSONWriter&, ...)` function, and stores them in a ProfileChunkedBuffer after the marker name and options.
Differential Revision: https://phabricator.services.mozilla.com/D87255
`DeserializeAfterKindAndStream()` is the main function that extracts all the marker data (past the already-read entry kind), and streams it to JSON using the user-provided `Stream(JSONWriter&, ...)` function in the appropriate marker type definition.
It currently requires two external functions to stream the name and the optional backtrace, because these are different between the two profilers. This may change in the future.
(Deserialization is implemented before serialization, because the `Deserialize()` function is needed during serialization to get a marker type tag.)
Differential Revision: https://phabricator.services.mozilla.com/D87254
`NoPayload` will be mostly used internally when adding markers without payload data.
It has an empty specialization of the MarkerTypeHelper (mainly to catch misuses), and the add-marker code will need to have different compile-time paths to handle it.
Differential Revision: https://phabricator.services.mozilla.com/D87252
Marker types will be defined with a simple struct that contains (amongst other things) one `StreamJSONMarkerData(JSONWriter&, ...)` function.
This patch introduces a type-traits-like helper to examine that function. This will be used to check the arguments given to the upcoming add-marker function, to serialize and deserialize them.
Differential Revision: https://phabricator.services.mozilla.com/D87251
This is similar to the existing deserializer table in ProfilerMarkerPayload.*:
Each type of marker (except the `NoPayload` one) has its corresponding deserializer in a table, and the index is used as a tag in the serialization buffer.
Differential Revision: https://phabricator.services.mozilla.com/D87250
A `MarkerOptions` must be constructed from a MarkerCategory, e.g.: `mozilla::baseprofiler::category::OTHER`. This will be required for all markers.
`MarkerOptions` also contains defaulted `MarkerThreadId`, `MarkerTiming`, `MarkerStack`, and `MarkerInnerWindowId`. They may be set by calling `WithOptions()` on the MarkerCategory, e.g.:
`PROFILER_MARKER<...>("name", OTHER.WithOptions(MarkerThreadId(otherThread), MarkerStack::Capture()), ...);`
Differential Revision: https://phabricator.services.mozilla.com/D87249
This marker option allows three cases:
- By default, no stacks are captured.
- The caller can request a stack capture, and the add-marker code will take care of it in the most efficient way.
- The caller can still provide an existing backtrace, for cases where a marker reports something that happened elsewhere.
Differential Revision: https://phabricator.services.mozilla.com/D87247
`profiler_capture_backtrace(ProfileChunkedBuffer&)` renamed to `profiler_capture_backtrace_into(ProfileChunkedBuffer&)` (notice "_into"), which is clearer.
New function `profiler_capture_backtrace()` creates a buffer, uses `profiler_capture_backtrace_into()`, and returns a `UniquePtr<ProfileChunkedBuffer>`, which can later be given to `MarkerStack::TakeBacktrace`.
`profiler_get_backtrace()` (returning a `UniqueProfilerBacktrace`) now uses `profiler_capture_backtrace()`.
This patch reduces most duplicate code between these functions.
Differential Revision: https://phabricator.services.mozilla.com/D88280
`IsEmpty()` makes it easier for users to determine if there is anything stored in the `ProfileChunkedBuffer`.
And `ProfileChunkedBuffer` can now be serialized from a raw pointer, which will be useful when adding markers with an optional stack.
Deserialization should be done to a `UniquePtr<ProfileChunkedBuffer>`, which is already implemented.
Differential Revision: https://phabricator.services.mozilla.com/D87246
This moves the existing MarkerTiming class introduced in bug 1640969 to the BaseProfilerMarkersPrerequesites.h header, and can be used as a marker option.
Some minor clarifying changes:
- `Instant()` is split into two functions: `InstantNow()` and `InstantAt(TimeStamp)`.
- `Interval(TimeStamp, TimeStamp)` must be given both start and end, otherwise `IntervalUntilNowFrom(TimeStamp)` takes the start only and ends "now".
Also the default construction is now reserved for internal marker usage, the private member function `IsUnspecified()` will be used by the add-marker code will replace it with `InstantNow()`.
The serialization contains the phase, and only one or two timestamps as needed, to save space for non-interval timings.
Differential Revision: https://phabricator.services.mozilla.com/D87245
This marker option captures a given thread id.
If left unspecified (by default construction) during the add-marker call, the current thread id will be used then.
Differential Revision: https://phabricator.services.mozilla.com/D87244
The main, and only compulsory, marker option is the `MarkerCategory`, which captures the "category pair", as well as the parent category.
Differential Revision: https://phabricator.services.mozilla.com/D88154
The upcoming profiler-specific add-marker function will need to know which `ProfileChunkedBuffer` to serialize to, `profiler_get_core_buffer()` give access to the profiler's buffer, and `CachedCoreBuffer()` keeps it stored in a function-static object.
Differential Revision: https://phabricator.services.mozilla.com/D87256
These string views are similar to `std::string_view`, but they are optimized to be serialized in the profiler buffer, and later deserialized and streamed to JSON.
They accept literal strings, and keep them as unowned raw pointers and sizes.
They also accept any substring reference, assuming that they will only be used as parameters during function calls, and therefore the dependent string will live during that call where these `StringView`'s are used.
Internally, they also allow optional string ownership, which is only used during deserialization and streaming.
This is hidden, so that users are not tempted to use potentially expensive string allocations during profiling; it's only used *after* profiling, so it's less of an impact to allocate strings then. (But it could still be optimized later on, as part of bug 1577656.)
Differential Revision: https://phabricator.services.mozilla.com/D87242
This patch introduces all new files that contain the new markers C++ API and implementation.
They are mostly empty at this time, only including each other as eventually needed, and with `#ifdef MOZ_GECKO_PROFILER` guards.
Rough inclusion diagram: (header <-- includer)
BaseProfilerMarkerPrerequesites.h <-- ProfilerMarkerPrerequesites.h (Useful types: Input string view, marker options)
^ ^
BaseProfilerMarkerDetail.h <-- ProfilerMarkerDetail.h (Implementation details)
^ ^
BaseProfilerMarkers.h <-- ProfilerMarkers.h (Main API)
^ ^--------- ^ ^---------
BaseProfilerMarkerTypes.h | <-- ProfilerMarkerTypes.h | (Common marker types)
^ BaseProfiler.h <-- GeckoProfiler.h (Existing main profiler headers)
Differential Revision: https://phabricator.services.mozilla.com/D87241
This patch ports existing ProfilerMarkerPayload types to draft struct definitions that may be used with the new markers API.
This is just a starting point, they may be changed later on as needed, see meta-bug 1661394.
Differential Revision: https://phabricator.services.mozilla.com/D87259
This is the main public marker API:
- `AddMarkerToBuffer` can be used to store a marker to any buffer. This could be useful to code that wants to store markers outside of the default profiler buffers.
- `baseprofiler::AddMarker`/`profiler_add_marker` store a marker in the appropriate profiler buffer.
- BASE_PROFILER_MARKER and PROFILER_MARKER do the same, but are also defined (and empty) when MOZ_GECKO_PROFILER is not #defined.
All these take a name, marker options, a marker type, and the type's expected arguments if any (as expected by the `StreamJSONMarkerData` function).
Extra helpers for the most common types:
- BASE_PROFILER_MARKER_UNTYPED and PROFILER_MARKER_UNTYPED store a marker with no data payload.
- BASE_PROFILER_MARKER_TEXT and PROFILER_MARKER_TEXT store a text marker. `baseprofiler::markers::Text` is an example of how new marker types can be defined.
Differential Revision: https://phabricator.services.mozilla.com/D87257
Main marker serialization function, which accepts the same arguments (with implicit conversions) as the marker type's `StreamJSONMarkerData(JSONWriter&, ...)` function, and stores them in a ProfileChunkedBuffer after the marker name and options.
Differential Revision: https://phabricator.services.mozilla.com/D87255
`DeserializeAfterKindAndStream()` is the main function that extracts all the marker data (past the already-read entry kind), and streams it to JSON using the user-provided `Stream(JSONWriter&, ...)` function in the appropriate marker type definition.
It currently requires two external functions to stream the name and the optional backtrace, because these are different between the two profilers. This may change in the future.
(Deserialization is implemented before serialization, because the `Deserialize()` function is needed during serialization to get a marker type tag.)
Differential Revision: https://phabricator.services.mozilla.com/D87254
`NoPayload` will be mostly used internally when adding markers without payload data.
It has an empty specialization of the MarkerTypeHelper (mainly to catch misuses), and the add-marker code will need to have different compile-time paths to handle it.
Differential Revision: https://phabricator.services.mozilla.com/D87252
Marker types will be defined with a simple struct that contains (amongst other things) one `StreamJSONMarkerData(JSONWriter&, ...)` function.
This patch introduces a type-traits-like helper to examine that function. This will be used to check the arguments given to the upcoming add-marker function, to serialize and deserialize them.
Differential Revision: https://phabricator.services.mozilla.com/D87251
This is similar to the existing deserializer table in ProfilerMarkerPayload.*:
Each type of marker (except the `NoPayload` one) has its corresponding deserializer in a table, and the index is used as a tag in the serialization buffer.
Differential Revision: https://phabricator.services.mozilla.com/D87250
A `MarkerOptions` must be constructed from a MarkerCategory, e.g.: `mozilla::baseprofiler::category::OTHER`. This will be required for all markers.
`MarkerOptions` also contains defaulted `MarkerThreadId`, `MarkerTiming`, `MarkerStack`, and `MarkerInnerWindowId`. They may be set by calling `WithOptions()` on the MarkerCategory, e.g.:
`PROFILER_MARKER<...>("name", OTHER.WithOptions(MarkerThreadId(otherThread), MarkerStack::Capture()), ...);`
Differential Revision: https://phabricator.services.mozilla.com/D87249
This marker option allows three cases:
- By default, no stacks are captured.
- The caller can request a stack capture, and the add-marker code will take care of it in the most efficient way.
- The caller can still provide an existing backtrace, for cases where a marker reports something that happened elsewhere.
Differential Revision: https://phabricator.services.mozilla.com/D87247
`profiler_capture_backtrace(ProfileChunkedBuffer&)` renamed to `profiler_capture_backtrace_into(ProfileChunkedBuffer&)` (notice "_into"), which is clearer.
New function `profiler_capture_backtrace()` creates a buffer, uses `profiler_capture_backtrace_into()`, and returns a `UniquePtr<ProfileChunkedBuffer>`, which can later be given to `MarkerStack::TakeBacktrace`.
`profiler_get_backtrace()` (returning a `UniqueProfilerBacktrace`) now uses `profiler_capture_backtrace()`.
This patch reduces most duplicate code between these functions.
Differential Revision: https://phabricator.services.mozilla.com/D88280
`IsEmpty()` makes it easier for users to determine if there is anything stored in the `ProfileChunkedBuffer`.
And `ProfileChunkedBuffer` can now be serialized from a raw pointer, which will be useful when adding markers with an optional stack.
Deserialization should be done to a `UniquePtr<ProfileChunkedBuffer>`, which is already implemented.
Differential Revision: https://phabricator.services.mozilla.com/D87246
This moves the existing MarkerTiming class introduced in bug 1640969 to the BaseProfilerMarkersPrerequesites.h header, and can be used as a marker option.
Some minor clarifying changes:
- `Instant()` is split into two functions: `InstantNow()` and `InstantAt(TimeStamp)`.
- `Interval(TimeStamp, TimeStamp)` must be given both start and end, otherwise `IntervalUntilNowFrom(TimeStamp)` takes the start only and ends "now".
Also the default construction is now reserved for internal marker usage, the private member function `IsUnspecified()` will be used by the add-marker code will replace it with `InstantNow()`.
The serialization contains the phase, and only one or two timestamps as needed, to save space for non-interval timings.
Differential Revision: https://phabricator.services.mozilla.com/D87245
This marker option captures a given thread id.
If left unspecified (by default construction) during the add-marker call, the current thread id will be used then.
Differential Revision: https://phabricator.services.mozilla.com/D87244
The main, and only compulsory, marker option is the `MarkerCategory`, which captures the "category pair", as well as the parent category.
Differential Revision: https://phabricator.services.mozilla.com/D88154
The upcoming profiler-specific add-marker function will need to know which `ProfileChunkedBuffer` to serialize to, `profiler_get_core_buffer()` give access to the profiler's buffer, and `CachedCoreBuffer()` keeps it stored in a function-static object.
Differential Revision: https://phabricator.services.mozilla.com/D87256
These string views are similar to `std::string_view`, but they are optimized to be serialized in the profiler buffer, and later deserialized and streamed to JSON.
They accept literal strings, and keep them as unowned raw pointers and sizes.
They also accept any substring reference, assuming that they will only be used as parameters during function calls, and therefore the dependent string will live during that call where these `StringView`'s are used.
Internally, they also allow optional string ownership, which is only used during deserialization and streaming.
This is hidden, so that users are not tempted to use potentially expensive string allocations during profiling; it's only used *after* profiling, so it's less of an impact to allocate strings then. (But it could still be optimized later on, as part of bug 1577656.)
Differential Revision: https://phabricator.services.mozilla.com/D87242
This patch introduces all new files that contain the new markers C++ API and implementation.
They are mostly empty at this time, only including each other as eventually needed, and with `#ifdef MOZ_GECKO_PROFILER` guards.
Rough inclusion diagram: (header <-- includer)
BaseProfilerMarkerPrerequesites.h <-- ProfilerMarkerPrerequesites.h (Useful types: Input string view, marker options)
^ ^
BaseProfilerMarkerDetail.h <-- ProfilerMarkerDetail.h (Implementation details)
^ ^
BaseProfilerMarkers.h <-- ProfilerMarkers.h (Main API)
^ ^--------- ^ ^---------
BaseProfilerMarkerTypes.h | <-- ProfilerMarkerTypes.h | (Common marker types)
^ BaseProfiler.h <-- GeckoProfiler.h (Existing main profiler headers)
Differential Revision: https://phabricator.services.mozilla.com/D87241
This patch ports existing ProfilerMarkerPayload types to draft struct definitions that may be used with the new markers API.
This is just a starting point, they may be changed later on as needed, see meta-bug 1661394.
Differential Revision: https://phabricator.services.mozilla.com/D87259
This is the main public marker API:
- `AddMarkerToBuffer` can be used to store a marker to any buffer. This could be useful to code that wants to store markers outside of the default profiler buffers.
- `baseprofiler::AddMarker`/`profiler_add_marker` store a marker in the appropriate profiler buffer.
- BASE_PROFILER_MARKER and PROFILER_MARKER do the same, but are also defined (and empty) when MOZ_GECKO_PROFILER is not #defined.
All these take a name, marker options, a marker type, and the type's expected arguments if any (as expected by the `StreamJSONMarkerData` function).
Extra helpers for the most common types:
- BASE_PROFILER_MARKER_UNTYPED and PROFILER_MARKER_UNTYPED store a marker with no data payload.
- BASE_PROFILER_MARKER_TEXT and PROFILER_MARKER_TEXT store a text marker. `baseprofiler::markers::Text` is an example of how new marker types can be defined.
Differential Revision: https://phabricator.services.mozilla.com/D87257
Main marker serialization function, which accepts the same arguments (with implicit conversions) as the marker type's `StreamJSONMarkerData(JSONWriter&, ...)` function, and stores them in a ProfileChunkedBuffer after the marker name and options.
Differential Revision: https://phabricator.services.mozilla.com/D87255
`DeserializeAfterKindAndStream()` is the main function that extracts all the marker data (past the already-read entry kind), and streams it to JSON using the user-provided `Stream(JSONWriter&, ...)` function in the appropriate marker type definition.
It currently requires two external functions to stream the name and the optional backtrace, because these are different between the two profilers. This may change in the future.
(Deserialization is implemented before serialization, because the `Deserialize()` function is needed during serialization to get a marker type tag.)
Differential Revision: https://phabricator.services.mozilla.com/D87254
`NoPayload` will be mostly used internally when adding markers without payload data.
It has an empty specialization of the MarkerTypeHelper (mainly to catch misuses), and the add-marker code will need to have different compile-time paths to handle it.
Differential Revision: https://phabricator.services.mozilla.com/D87252
Marker types will be defined with a simple struct that contains (amongst other things) one `StreamJSONMarkerData(JSONWriter&, ...)` function.
This patch introduces a type-traits-like helper to examine that function. This will be used to check the arguments given to the upcoming add-marker function, to serialize and deserialize them.
Differential Revision: https://phabricator.services.mozilla.com/D87251
This is similar to the existing deserializer table in ProfilerMarkerPayload.*:
Each type of marker (except the `NoPayload` one) has its corresponding deserializer in a table, and the index is used as a tag in the serialization buffer.
Differential Revision: https://phabricator.services.mozilla.com/D87250
A `MarkerOptions` must be constructed from a MarkerCategory, e.g.: `mozilla::baseprofiler::category::OTHER`. This will be required for all markers.
`MarkerOptions` also contains defaulted `MarkerThreadId`, `MarkerTiming`, `MarkerStack`, and `MarkerInnerWindowId`. They may be set by calling `WithOptions()` on the MarkerCategory, e.g.:
`PROFILER_MARKER<...>("name", OTHER.WithOptions(MarkerThreadId(otherThread), MarkerStack::Capture()), ...);`
Differential Revision: https://phabricator.services.mozilla.com/D87249
This marker option allows three cases:
- By default, no stacks are captured.
- The caller can request a stack capture, and the add-marker code will take care of it in the most efficient way.
- The caller can still provide an existing backtrace, for cases where a marker reports something that happened elsewhere.
Differential Revision: https://phabricator.services.mozilla.com/D87247
`profiler_capture_backtrace(ProfileChunkedBuffer&)` renamed to `profiler_capture_backtrace_into(ProfileChunkedBuffer&)` (notice "_into"), which is clearer.
New function `profiler_capture_backtrace()` creates a buffer, uses `profiler_capture_backtrace_into()`, and returns a `UniquePtr<ProfileChunkedBuffer>`, which can later be given to `MarkerStack::TakeBacktrace`.
`profiler_get_backtrace()` (returning a `UniqueProfilerBacktrace`) now uses `profiler_capture_backtrace()`.
This patch reduces most duplicate code between these functions.
Differential Revision: https://phabricator.services.mozilla.com/D88280
`IsEmpty()` makes it easier for users to determine if there is anything stored in the `ProfileChunkedBuffer`.
And `ProfileChunkedBuffer` can now be serialized from a raw pointer, which will be useful when adding markers with an optional stack.
Deserialization should be done to a `UniquePtr<ProfileChunkedBuffer>`, which is already implemented.
Differential Revision: https://phabricator.services.mozilla.com/D87246
This moves the existing MarkerTiming class introduced in bug 1640969 to the BaseProfilerMarkersPrerequesites.h header, and can be used as a marker option.
Some minor clarifying changes:
- `Instant()` is split into two functions: `InstantNow()` and `InstantAt(TimeStamp)`.
- `Interval(TimeStamp, TimeStamp)` must be given both start and end, otherwise `IntervalUntilNowFrom(TimeStamp)` takes the start only and ends "now".
Also the default construction is now reserved for internal marker usage, the private member function `IsUnspecified()` will be used by the add-marker code will replace it with `InstantNow()`.
The serialization contains the phase, and only one or two timestamps as needed, to save space for non-interval timings.
Differential Revision: https://phabricator.services.mozilla.com/D87245
This marker option captures a given thread id.
If left unspecified (by default construction) during the add-marker call, the current thread id will be used then.
Differential Revision: https://phabricator.services.mozilla.com/D87244
The main, and only compulsory, marker option is the `MarkerCategory`, which captures the "category pair", as well as the parent category.
Differential Revision: https://phabricator.services.mozilla.com/D88154
The upcoming profiler-specific add-marker function will need to know which `ProfileChunkedBuffer` to serialize to, `profiler_get_core_buffer()` give access to the profiler's buffer, and `CachedCoreBuffer()` keeps it stored in a function-static object.
Differential Revision: https://phabricator.services.mozilla.com/D87256
These string views are similar to `std::string_view`, but they are optimized to be serialized in the profiler buffer, and later deserialized and streamed to JSON.
They accept literal strings, and keep them as unowned raw pointers and sizes.
They also accept any substring reference, assuming that they will only be used as parameters during function calls, and therefore the dependent string will live during that call where these `StringView`'s are used.
Internally, they also allow optional string ownership, which is only used during deserialization and streaming.
This is hidden, so that users are not tempted to use potentially expensive string allocations during profiling; it's only used *after* profiling, so it's less of an impact to allocate strings then. (But it could still be optimized later on, as part of bug 1577656.)
Differential Revision: https://phabricator.services.mozilla.com/D87242
This patch introduces all new files that contain the new markers C++ API and implementation.
They are mostly empty at this time, only including each other as eventually needed, and with `#ifdef MOZ_GECKO_PROFILER` guards.
Rough inclusion diagram: (header <-- includer)
BaseProfilerMarkerPrerequesites.h <-- ProfilerMarkerPrerequesites.h (Useful types: Input string view, marker options)
^ ^
BaseProfilerMarkerDetail.h <-- ProfilerMarkerDetail.h (Implementation details)
^ ^
BaseProfilerMarkers.h <-- ProfilerMarkers.h (Main API)
^ ^--------- ^ ^---------
BaseProfilerMarkerTypes.h | <-- ProfilerMarkerTypes.h | (Common marker types)
^ BaseProfiler.h <-- GeckoProfiler.h (Existing main profiler headers)
Differential Revision: https://phabricator.services.mozilla.com/D87241
In Win7 and later, some exported functions in kernel32.dll are just a stub
jumping to a function in kernelbase.dll. After the fix for Bug 1642626,
our detour resolves such a stub in kernel32.dll and detours a corresponding function in
kernelbase.dll. This new behavior caused a problem in Win8 when we detour
`DuplicateHandle` because our detour cannot handle the assembly pattern of
`KERNELBASE!DuplicateHandle`.
Win8's `KERNELBASE!DuplicateHandle` has jump instructions whose destination is
within the region where we move instructions to a trampoline.
In the example below, the address `000007f954ad271c` is a destination of the
`JMP` instructions, but when we detour `KERNELBASE!DuplicateHandle`, we move
the original instructions to a trampoline, and that address will point to
an invalid instruction, jumping to which address causes a crash.
A proposed fix is to detour `KERNEL32!DuplicateHandle` without resolving redirection,
that is the behavior before bug 1642626.
```
KERNEL32!DuplicateHandle:
000007f9`54cd2d5c ff2556b61100 jmp qword ptr [KERNEL32!_imp_DuplicateHandle] --> KERNELBASE!DuplicateHandle
```
```
KERNELBASE!DuplicateHandle:
000007f9`54ad2710 4883ec48 sub rsp,48h
000007f9`54ad2714 4c8bd1 mov r10,rcx
000007f9`54ad2717 83faf4 cmp edx,0FFFFFFF4h
000007f9`54ad271a 733b jae KERNELBASE!DuplicateHandle+0x43 (000007f9`54ad2757)
000007f9`54ad271c 8b842480000000 mov eax,dword ptr [rsp+80h]
...
000007f9`54b8f0de 65488b042560000000 mov rax,qword ptr gs:[60h]
000007f9`54b8f0e7 488b5020 mov rdx,qword ptr [rax+20h]
000007f9`54b8f0eb 488b5220 mov rdx,qword ptr [rdx+20h]
000007f9`54b8f0ef e92836f4ff jmp KERNELBASE!DuplicateHandle+0xc (000007f9`54ad271c)
000007f9`54b8f0f4 65488b042560000000 mov rax,qword ptr gs:[60h]
000007f9`54b8f0fd 488b5020 mov rdx,qword ptr [rax+20h]
000007f9`54b8f101 488b5228 mov rdx,qword ptr [rdx+28h]
000007f9`54b8f105 e91236f4ff jmp KERNELBASE!DuplicateHandle+0xc (000007f9`54ad271c)
000007f9`54b8f10a 65488b042560000000 mov rax,qword ptr gs:[60h]
000007f9`54b8f113 488b5020 mov rdx,qword ptr [rax+20h]
000007f9`54b8f117 488b5230 mov rdx,qword ptr [rdx+30h]
000007f9`54b8f11b e9fc35f4ff jmp KERNELBASE!DuplicateHandle+0xc (000007f9`54ad271c)
```
Differential Revision: https://phabricator.services.mozilla.com/D88136
This patch adds a new property `process_type` to the launcher process failure
ping, indicating which process type the browser process failed to initialize
as a sandboxed process.
Depends on D83639
Differential Revision: https://phabricator.services.mozilla.com/D83640
This patch adds winlauncher's HandleLauncherError to DllServices
along with InitializeDllBlocklistOOPInternal so that SandboxBroker
can call HandleLauncherError.
Differential Revision: https://phabricator.services.mozilla.com/D83639
Normally I believe it's good to keep functionally-distinct code in separate functions when appropriate.
However in this case, this `ChunkedJSONWriteFunc::GetTotalLength()` function was only used internally, so it's easy to hide it. It is not very big, so it's less important to keep it separate. And its code (going through all chunks to collect sizes) is similar to the code that follows (going through all chunks to collect their content), so it makes some sense to have these similar things in the same place; if one day this chunking change, both loops would probably have to be modified at the same time.
More importantly to justify this change: It was including the final null terminator, which was a bit inconsistent with the usual `Length()` functions in string containers.
Now that code is only used where absolutely necessary (before allocating an output buffer), so it rightly accounts for the null terminator that is added at the end of the contents.
And in upcoming bug 1612799, `ChunkedJSONWriteFunc` will have a new "retired" state (e.g., after an internal memory allocation failed) in which case a public `GetTotalLength()` function could give misleading results -- should it be 0 (nothing to output), 1 (only the null terminator), 5 ("null"), or the length of some error message? So I think it's better not to expose such an ambiguous function.
It could of course be re-introduced if new needs arise in the future.
Differential Revision: https://phabricator.services.mozilla.com/D87833
In most calls to `SpliceableJSONWriter::Splice(const char*)`:
- The data comes from a `ChunkedJSONWriteFunc` and is copied to a new buffer, which is then copied again through `Write()`. Instead we can copy the data directly from the `ChunkedJSONWriteFunc`; and this is a nice complement to `TakeAndSplice()` below.
- Or the length is already known, so we can pass it to a new `Splice(const char*, size_t)`, which forwards it to `Write(const char*, size_t)`, saving one `strlen` call.
Differential Revision: https://phabricator.services.mozilla.com/D87703
`SpliceableChunkedJSONWriter::ChunkedWriteFunc` returns a `ChunkedJSONWriteFunc*`, which is never null and is either used to:
1. Copy data.
2. Or take ownership of the chunks.
In the first case, `ChunkedWriteFunc()` now returns a `const ChunkedJSONWriteFunc&` (notice "const &"), so only const members may be used to copy the data.
In the second case, a new function `TakeChunkedWriteFunc()` returns `ChunkedJSONWriteFunc&&` (notice "&&"), so it's clear that its chunks can be taken away. Some `DEBUG` assertions help ensure that it's not used anymore after that.
`TakeAndSplice()` now takes a `ChunkedJSONWriteFunc&&`.
All callers have been updated to the more appropriate functions.
Differential Revision: https://phabricator.services.mozilla.com/D87702
This patch makes it possible to serialize and deserialize std::basic_string's of different character types, not just std::string. This will be useful when dealing with char16_t from nsString and others.
We also expose the internal read-contents functions, to allow the user to read a sequence of characters of already-known length.
Differential Revision: https://phabricator.services.mozilla.com/D87237
Hopefully the comments in the actual code are enough to explain what is going
on here.
NOTE: this patch does not represent a finished skeleton UI. There are some
questions in comments within the code, and generally I'm seeking feedback on
whether the overall approach seems sane or not. Gijs, I'm including you for
feedback on whether you think this is maintainable by more frontend-oriented
folks, and Molly, I'm including you for feedback on whether the justification
for writing to a raw pixel buffer seems sound or not, and a general review of
the approach.
Differential Revision: https://phabricator.services.mozilla.com/D86447
See bug for justification. This patch aims to display a blank window prior to
loading/prefetching xul.dll. It also has a placeholder for drawing a
skeleton UI into that window. Note that this is disabled by default based on
a registry value, as there are still kinks to work out (for instance, what
happens if we aren't actually going to display a window, because, say, Firefox
is already running.) This just gives a basic implementation to dogfood, and
facilitates distributing work across multiple contributors.
Onto the details. The patch achieves its goal by creating a window and
assigning its handle to a static variable, which will be consumed inside
nsWindow::Create by the first toplevel window we want to make. nsWindow::Create
will take ownership of the window handle, restyle it to its own liking, and
then proceed as if everything is normal and it had created the window itself.
Differential Revision: https://phabricator.services.mozilla.com/D86263
This change makes everything compile and presumably has some tiny effect on
performance. We also take the opportunity to ensure that the compiler won't
optimize out our inline asm by making the asm volatile and indicating that
it touches memory.
Differential Revision: https://phabricator.services.mozilla.com/D86594
The stack sampling can be abstracted to only use a reference to a `ProfileBuffer`, and the existing `locked_profiler_get_backtrace` can provide its stack-based `ProfileBuffer` that points at a heap-based `ProfileChunkedBuffer` (the one that will be stored in the returned `ProfilerBacktrace`).
And we can now add a public `profiler_capture_backtrace` that only takes a reference to a `ProfileChunkedBuffer`, and fills it with a backtrace.
This will be used by the new marker API, to optionally capture a backtrace in stack-based buffers at the user's request.
Differential Revision: https://phabricator.services.mozilla.com/D86514
A heap-allocate ProfileBuffer is not really needed, so it's more efficient to have one on the stack during capture, and we don't need to keep it in the `ProfilerBacktrace`.
Differential Revision: https://phabricator.services.mozilla.com/D86513
Instead of always taking ownership of both heap-allocated `ProfileBuffer` and `ProfileChunkedBuffer`, `ProfilerBacktrace` can now accept:
- Unique pointers to both or either, similar to what it was before, so a ProfilerBacktrace can be kept for later use.
- Non-owning pointers to both or either, to allow callers to use stack-based buffer(s); null pointers are allowed for totally empty backtraces.
Only the `ProfileChunkedBuffer` contains the actual data, we can create a `ProfileBuffer` on the spot if not provided.
Differential Revision: https://phabricator.services.mozilla.com/D86512
Instead of keeping a pointer to a null-terminated string, it's simpler to keep a proper `std::string`, and it helps to keep the length ready for streaming.
Differential Revision: https://phabricator.services.mozilla.com/D86511
Let `ProfilerBuffer` expose its underlying `ProfileChunkedBuffer`, this will be useful when `ProfilerBacktrace` will only be given a `ProfileBuffer`, and to perform some safety checks.
As a bonus from this change, `StoreMarker()` can be made non-generic -- It was relying on both `ProfileBuffer` and `ProfileChunkedBuffer` to have the same function `PutObjects()`. Consequently, we don't need `ProfileBuffer::PutObjects()` anymore, this removes this clunky pass-through (but useful and the best solution at the time).
Differential Revision: https://phabricator.services.mozilla.com/D86510
Until now the `ProfileBuffer` would erase its attached `ProfileChunkedBuffer` upon destruction.
However:
- The main `ProfileChunkedBuffer` is erased anyway in the `ActivePS`,
- Other `ProfileChunkedBuffer`s are short-lived and don't really need to be erased.
- The upcoming changes to `ProfilerBacktrace` and its users means that we will only keep the `ProfileChunkedBuffer` as backtrace storage, a `ProfileBuffer` will only be needed during capture and then when streaming to JSON; so we don't want the `ProfileChunkedBuffer` to be erased when detached from its capturing `ProfileBuffer`.
- Also, the erasing was done by `ResetChunkManager()` in `~ProfileBuffer()`, which was asymetric with what the constructor does (nothing!). So it's better to leave whoever did the `SetChunkManager()` to deal with the corresponding `ResetChunkManager()` (in the main case `ActivePS`, otherwise short-lived buffers being destroyed at the end of their scope).
Both `ProfileBuffer` destructors were only doing this operation, so we can just remove them completely.
Differential Revision: https://phabricator.services.mozilla.com/D86509
Backtraces and other marker data will be stored directly into a ProfileChunkedBuffer from public code in both profilers, so we will need to have the entry "kinds" available outside of the profiler directories.
This also helps with de-duplicating, since the kinds will now be in one spot and shared by both profilers.
Differential Revision: https://phabricator.services.mozilla.com/D86508
The registers referenced in this patch and the assembly have been tested to
compile; the code changes have not been tested to actually work.
Differential Revision: https://phabricator.services.mozilla.com/D86612
This change doesn't resolve some of the issues in profiler code that have
x86-64-isms in them, but this is at least a start.
Differential Revision: https://phabricator.services.mozilla.com/D86595
SpliceableChunkedJSONWriter::WriteFunc was hiding base-class non-virtual JSONWriter::WriteFunc(), which made it less than ideal (for me) to reason with.
Also made a few subclasses final, to help with possible devirtualization.
Differential Revision: https://phabricator.services.mozilla.com/D86505
The main change is removing ProfileJSONWriter.cpp, making ProfileJSONWriter.h point at BaseProfileJSONWriter.h, and exposing `mozilla::baseprofiler::` classes in the top namespace as expected by users of ProfileJSONWriter.h (to minimize changes).
These two headers are now always present in the "mozilla" include directory, independent of MOZ_GECKO_PROFILER settings.
The rest is just needed tweaks to match the above changes.
Differential Revision: https://phabricator.services.mozilla.com/D86504
Because this header will be used across libraries (mozglue and xul), it is simpler and more efficient to make it fully self-contained instead of using MFBT_API.
It may lead to slightly longer build times, but since it's only used inside the profilers, it won't impact other components.
The compiler can better optimize it in context, and decide what to inline.
Differential Revision: https://phabricator.services.mozilla.com/D86503
That was redundant with the manifest being added with MT (although useful
for mingw builds, that don't use MT), but is also now handled by the
automatic creation of rc files.
Differential Revision: https://phabricator.services.mozilla.com/D86156
The resource file is always generated so being able to configure its name
is not useful. On the other hand, the way things are currently implemented,
the lack of RESFILE also makes RCFILE ignored, which we fix at the same
time.
And remove a spurious RESFILE in widget/windows/moz.build, where no binary
is produced, which means RESFILE had no meaning.
Differential Revision: https://phabricator.services.mozilla.com/D86154
That was redundant with the manifest being added with MT (although useful
for mingw builds, that don't use MT), but is also now handled by the
automatic creation of rc files.
Differential Revision: https://phabricator.services.mozilla.com/D86156
The resource file is always generated so being able to configure its name
is not useful. On the other hand, the way things are currently implemented,
the lack of RESFILE also makes RCFILE ignored, which we fix at the same
time.
And remove a spurious RESFILE in widget/windows/moz.build, where no binary
is produced, which means RESFILE had no meaning.
Differential Revision: https://phabricator.services.mozilla.com/D86154
Previously we didn't compact ObjectGroups, but doing this would hopfully unlock more memory savings in bug 1654853.
Most of the trickiness here comes from accessing objects whose object group is forwarded, so require special-case handling to get their class, compartment etc.
Differential Revision: https://phabricator.services.mozilla.com/D86033
Previously we didn't compact ObjectGroups, but doing this would hopfully unlock more memory savings in bug 1654853.
Most of the trickiness here comes from accessing objects whose object group is forwarded, so require special-case handling to get their class, compartment etc.
Differential Revision: https://phabricator.services.mozilla.com/D86033
After the fix for bug 1642626, we need to detour `KERNELBASE!CloseHandle`
instead of K32's stub, which contains `JAE rel32`.
I also found a mistake in the fix for bug 1642626. When we put a conditional
jump in a trampoline, we need to reverse a condition, but the JAE case mistakenly
filled JAE straight. This patch corrects it to filling JB.
Differential Revision: https://phabricator.services.mozilla.com/D85477
CLOSED TREE
We don't need these macros anymore, for two reasons:
1. We have static analysis to provide the same sort of checks via `MOZ_RAII`
and friends.
2. clang now warns for the "temporary that should have been a declaration" case.
The extra requirements on class construction also show up during debug tests
as performance problems.
This change was automated by using the following sed script:
```
# Remove declarations in classes.
/MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER/d
/MOZ_GUARD_OBJECT_NOTIFIER_INIT/d
# Remove individual macros, carefully.
{
# We don't have to worry about substrings here because the closing
# parenthesis "anchors" the match.
s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM)/)/g;
s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)/)/g;
s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)/)/g;
s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)/)/g;
# Remove the longer identifier first.
s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT//g;
s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM//g;
}
# Remove the actual include.
\@# *include "mozilla/GuardObjects.h"@d
```
and running:
```
find . -name \*.cpp -o -name \*.h | grep -v 'GuardObjects.h' |xargs sed -i -f script 2>/dev/null
mach clang-format
```
Differential Revision: https://phabricator.services.mozilla.com/D85168
We don't need these macros anymore, for two reasons:
1. We have static analysis to provide the same sort of checks via `MOZ_RAII`
and friends.
2. clang now warns for the "temporary that should have been a declaration" case.
The extra requirements on class construction also show up during debug tests
as performance problems.
This change was automated by using the following sed script:
```
# Remove declarations in classes.
/MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER/d
/MOZ_GUARD_OBJECT_NOTIFIER_INIT/d
# Remove individual macros, carefully.
{
# We don't have to worry about substrings here because the closing
# parenthesis "anchors" the match.
s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM)/)/g;
s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM_TO_PARENT)/)/g;
s/MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)/)/g;
s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)/)/g;
# Remove the longer identifier first.
s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT//g;
s/MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM//g;
}
# Remove the actual include.
\@# *include "mozilla/GuardObjects.h"@d
```
and running:
```
find . -name \*.cpp -o -name \*.h | grep -v 'GuardObjects.h' |xargs sed -i -f script 2>/dev/null
mach clang-format
```
Differential Revision: https://phabricator.services.mozilla.com/D85168
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
When the osclientcerts module attempts to use client certificates and keys from
certain tokens, the Windows APIs will attempt to load asepkcs.dll. If Firefox
blocks this library, the keys won't be available. Thus, it needs to be
unblocked.
Due to the architecture of osclientcerts (namely, its dedicated single thread),
using asepkcs.dll via the Windows APIs shouldn't cause the crashes that led to
this module being blocked.
Differential Revision: https://phabricator.services.mozilla.com/D82788
The file defines symbol renames to perform when linking. The list of
symbols to rename varies between an empty list and a full list depending
whether MOZ_MEMORY is set. Practically speaking, the variant with an
empty list is equivalent to not using a def-file at all.
This means we don't need to preprocess it any more, and we can just not
use a def-file when MOZ_MEMORY is not set.
As a side effect, this removes a rule from a Makefile.in.
Differential Revision: https://phabricator.services.mozilla.com/D83034
`nscore.h` includes `xpcom-config.h` which need not be generated for
non-XPCOM consumers. In additon, `nullptr` and `bool` are C++
keywords, so at least some of the comments were dated.
The added include lines address transitive consumers of `nscore.h`.
Differential Revision: https://phabricator.services.mozilla.com/D82640
This requires a workaround for the use of __wrap_dladdr, which can't be
used in logalloc-replay. The workaround involves making __wrap_dladdr
expand to dladdr, but that makes the definition ElfLinker.h conflict
with the one in the Android system headers, so we change it to match,
and adjust ElfLinker.cpp accordingly.
And while here, fix the condition in mozglue/misc to match the condition
around including Linker.h in StackWalk.cpp itself.
Differential Revision: https://phabricator.services.mozilla.com/D82648
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
This is a rebase of a 7-year-old patch that was r=taras. Back then it
was waiting for breakpad changes that never were reviewed. However,
since then, bug 1486524 made the linker always map uncompressed files
directly, making it less necessary to report the library mappings to
the crash reporter, and bug 1291377 disabled the linker altogether on
Android 6.0+, which makes report_mapping unused at all in that case.
Differential Revision: https://phabricator.services.mozilla.com/D81025
AVG AntiVirus hooks ntdll!NtMapViewOfSection by planting two JMP instructions,
jumping to a trampoline area first, then jumping to aswhook.dll.
```
ntdll!NtMapViewOfSection:
00007ffa`6d77c560 e9d33cfebf jmp 00007ffa`2d760238
00007ffa`2d760238 ff25f2ffffff jmp qword ptr [00007ffa`2d760230] --> 00007ffa`541e2ad0
aswhook+0x2ad0:
00007ffa`541e2ad0 4055 push rbp
00007ffa`541e2ad2 53 push rbx
00007ffa`541e2ad3 56 push rsi
```
With this patch, our detour can detour on top of that pattern. The first part is
to remove the MEM_IMAGE check from IsPageAccessible. The second part is to introduce
a loop in ResolveRedirectedAddress to resolve a chain of jumps.
Differential Revision: https://phabricator.services.mozilla.com/D81582
This patch moves the logics of jump detection from ResolveRedirectedAddress to
ReadOnlyTargetFunction to simplify ReadOnlyTargetFunction.
Differential Revision: https://phabricator.services.mozilla.com/D81580
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 header is using `MOZ_RAII` and `MFBT_ABI` from `Attributes.h` and
`Types.h`, respectively, so it should include those headers.
Differential Revision: https://phabricator.services.mozilla.com/D81600
This is a data race, but I don't think it is causing problems at the moment. It will go away when we get rid of ObjectGroups and is not trivial to fix, hence the decision to suppress it.
Differential Revision: https://phabricator.services.mozilla.com/D81327
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
`BLOCK_WIN8_ONLY` was introduced by bug 1268470 to block klsihk64.dll only on
Win8. However, a new blocklist (bug 1445025) does wrong comparison on the OS
version, thus `BLOCK_WIN8_ONLY` has blocked modules on all platforms older than
Win10 including Win7 and Win8.1.
This patch corrects OS comparison and changes the flag to `BLOCK_WIN8_AND_OLDER`
to make it more handy. We also remove `BLOCK_WIN8PLUS_ONLY` which is never used.
Differential Revision: https://phabricator.services.mozilla.com/D78411
Also update documentation to suggest using the `GeneratedFile` template rather than directly referencing `GENERATED_FILES` where possible.
Differential Revision: https://phabricator.services.mozilla.com/D77496
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
If EAF+ is enabled for firefox.exe, the process does not launch because we parse
the PE headers of ntdll.dll at startup, which is prohibited by EAF+.
With this patch, we skip two operations when EAF+ is enabled.
The first one is to cache ntdll's IAT at startup. Because EAF+ is expected to
prevent an injected module from parsing PE headers and modifying IAT, we can skip
this caching safely.
The second one is to load ntdll's debug information for the profiler. With this
patch, the profiler's callstack will not show a raw address instead of a symbol
name. It's a bad side effect, but much better than startup crash.
Differential Revision: https://phabricator.services.mozilla.com/D76959
GetConstructedEventTarget and GetSpecificMessageEventTarget always return
null. The idea was that subclasses could override them, but nobody does any
more.
Differential Revision: https://phabricator.services.mozilla.com/D76984
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