Bug 1883522 - When running with MOZ_USE_PERFORMANCE_MARKER_FILE=1, mmap the marker file to help out perf + simpleperf + samply. r=jrmuizel

Differential Revision: https://phabricator.services.mozilla.com/D203536
This commit is contained in:
Markus Stange 2024-03-09 23:04:01 +00:00
Родитель c6cb32e0b1
Коммит 88398f1e16
1 изменённых файлов: 55 добавлений и 3 удалений

Просмотреть файл

@ -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,14 +598,61 @@ 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;
}