diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:27 +0000 |
commit | 40a355a42d4a9444dc753c04c6608dade2f06a23 (patch) | |
tree | 871fc667d2de662f171103ce5ec067014ef85e61 /dom/performance/Performance.cpp | |
parent | Adding upstream version 124.0.1. (diff) | |
download | firefox-adbda400be353e676059e335c3c0aaf99e719475.tar.xz firefox-adbda400be353e676059e335c3c0aaf99e719475.zip |
Adding upstream version 125.0.1.upstream/125.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/performance/Performance.cpp')
-rw-r--r-- | dom/performance/Performance.cpp | 60 |
1 files changed, 57 insertions, 3 deletions
diff --git a/dom/performance/Performance.cpp b/dom/performance/Performance.cpp index ecbc3b4c68..ce2557100d 100644 --- a/dom/performance/Performance.cpp +++ b/dom/performance/Performance.cpp @@ -8,6 +8,11 @@ #include <sstream> +#if defined(XP_LINUX) +# include <fcntl.h> +# include <sys/mman.h> +#endif + #include "ETWTools.h" #include "GeckoProfiler.h" #include "nsRFPService.h" @@ -593,18 +598,66 @@ std::pair<TimeStamp, TimeStamp> Performance::GetTimeStampsForMarker( return std::make_pair(startTimeStamp, endTimeStamp); } +static FILE* MaybeOpenMarkerFile() { + if (!getenv("MOZ_USE_PERFORMANCE_MARKER_FILE")) { + return nullptr; + } + +#ifdef XP_LINUX + // We treat marker files similar to Jitdump files (see PerfSpewer.cpp) and + // mmap them if needed. + int fd = open(GetMarkerFilename().c_str(), O_CREAT | O_TRUNC | O_RDWR, 0666); + FILE* markerFile = fdopen(fd, "w+"); + + if (!markerFile) { + return nullptr; + } + + // On Linux and Android, we need to mmap the file so that the path makes it + // into the perf.data file or into samply. + // On non-Android, make the mapping executable, otherwise the MMAP event may + // not be recorded by perf (see perf_event_open mmap_data). + // But on Android, don't make the mapping executable, because doing so can + // make the mmap call fail on some Android devices. It's also not required on + // Android because simpleperf sets mmap_data = 1 for unrelated reasons (it + // wants to know about vdex files for Java JIT profiling, see + // SetRecordNotExecutableMaps). + int protection = PROT_READ; +# ifndef ANDROID + protection |= PROT_EXEC; +# endif + + // Mmap just the first page - that's enough to ensure the path makes it into + // the recording. + long page_size = sysconf(_SC_PAGESIZE); + void* mmap_address = mmap(nullptr, page_size, protection, MAP_PRIVATE, fd, 0); + if (mmap_address == MAP_FAILED) { + fclose(markerFile); + return nullptr; + } + return markerFile; +#else + // On macOS, we just need to `open` or `fopen` the marker file, and samply + // will know its path because it hooks those functions - no mmap needed. + // On Windows, there's no need to use MOZ_USE_PERFORMANCE_MARKER_FILE because + // we have ETW trace events for UserTiming measures. Still, we want this code + // to compile successfully on Windows, so we use fopen rather than + // open+fdopen. + return fopen(GetMarkerFilename().c_str(), "w+"); +#endif +} + // This emits markers to an external marker-[pid].txt file for use by an // external profiler like samply or etw-gecko void Performance::MaybeEmitExternalProfilerMarker( const nsAString& aName, Maybe<const PerformanceMeasureOptions&> aOptions, Maybe<const nsAString&> aStartMark, const Optional<nsAString>& aEndMark) { - static FILE* markerFile = getenv("MOZ_USE_PERFORMANCE_MARKER_FILE") - ? fopen(GetMarkerFilename().c_str(), "w+") - : nullptr; + static FILE* markerFile = MaybeOpenMarkerFile(); if (!markerFile) { return; } +#if defined(XP_LINUX) || defined(XP_WIN) || defined(XP_MACOSX) ErrorResult rv; auto [startTimeStamp, endTimeStamp] = GetTimeStampsForMarker(aStartMark, aEndMark, aOptions, rv); @@ -612,6 +665,7 @@ void Performance::MaybeEmitExternalProfilerMarker( if (NS_WARN_IF(rv.Failed())) { return; } +#endif #ifdef XP_LINUX uint64_t rawStart = startTimeStamp.RawClockMonotonicNanosecondsSinceBoot(); |