Bug 1957016 - Move the capturing profile part to recording-utils.sys.mjs r=canaltinova,profiler-reviewers

The capturing profile part is complex enough that we can extract it to
RecordingUtils. Then it's available if other code needs it, including on
Android.

Differential Revision: https://phabricator.services.mozilla.com/D243184
This commit is contained in:
Julien Wajsberg
2025-04-02 08:28:01 +00:00
parent 3477c3fc9c
commit a3a1494302
2 changed files with 60 additions and 29 deletions

View File

@@ -103,35 +103,14 @@ export async function captureProfile(pageContext) {
return;
}
// Pause profiler before we collect the profile, so that we don't capture
// more samples while the parent process waits for subprocess profiles.
Services.profiler.Pause();
/**
* @type {MockedExports.ProfileGenerationAdditionalInformation | undefined}
*/
let additionalInfo;
/**
* @type {ProfileCaptureResult}
*/
const profileCaptureResult = await Services.profiler
.getProfileDataAsGzippedArrayBuffer()
.then(
({ profile, additionalInformation }) => {
additionalInfo = additionalInformation;
return { type: "SUCCESS", profile };
},
error => {
console.error(error);
return { type: "ERROR", error };
}
);
const { profileCaptureResult, additionalInformation } = await lazy
.RecordingUtils()
.getProfileDataAsGzippedArrayBufferThenStop();
const profilerViewMode = lazy
.PrefsPresets()
.getProfilerViewModeForCurrentPreset(pageContext);
const sharedLibraries = additionalInfo?.sharedLibraries
? additionalInfo.sharedLibraries
const sharedLibraries = additionalInformation?.sharedLibraries
? additionalInformation.sharedLibraries
: Services.profiler.sharedLibraries;
const objdirs = lazy.PrefsPresets().getObjdirPrefValue();
@@ -148,8 +127,6 @@ export async function captureProfile(pageContext) {
profileCaptureResult,
symbolicationService
);
Services.profiler.StopProfiler();
}
/**

View File

@@ -4,7 +4,8 @@
// @ts-check
/**
* @typedef {import("../../client/performance-new/@types/perf").GetActiveBrowserID} GetActiveBrowserID
* @typedef {import("perf").GetActiveBrowserID} GetActiveBrowserID
* @typedef {import("perf").ProfileCaptureResult} ProfileCaptureResult
*/
/**
@@ -28,8 +29,61 @@ export function getActiveBrowserID() {
return 0;
}
/**
* @typedef {Object} ProfileCaptureResultAndAdditionalInformation
* @property {ProfileCaptureResult} profileCaptureResult
* @property {MockedExports.ProfileGenerationAdditionalInformation} [additionalInformation]
*/
/**
* Fetch the profile data from Firefox, then stop the profiler.
*
* @returns {Promise<ProfileCaptureResultAndAdditionalInformation>}
*/
export async function getProfileDataAsGzippedArrayBufferThenStop() {
if (!Services.profiler.IsActive()) {
// The profiler is not active, ignore.
return {
profileCaptureResult: {
type: "ERROR",
error: new Error("The profiler is not active."),
},
};
}
if (Services.profiler.IsPaused()) {
// The profiler is already paused for capture, ignore.
return {
profileCaptureResult: {
type: "ERROR",
error: new Error("The profiler is already paused."),
},
};
}
// Pause profiler before we collect the profile, so that we don't capture
// more samples while the parent process waits for subprocess profiles.
Services.profiler.Pause();
try {
const { profile, additionalInformation } =
await Services.profiler.getProfileDataAsGzippedArrayBuffer();
return {
profileCaptureResult: { type: "SUCCESS", profile },
additionalInformation,
};
} catch (unknownError) {
const error = /** @type {Error} */ (unknownError);
return { profileCaptureResult: { type: "ERROR", error } };
} finally {
// We're purposefully not using `await`, to minimize the time the user has
// to wait until the result is returned.
Services.profiler.StopProfiler();
}
}
// This file also exports a named object containing other exports to play well
// with defineESModuleGetters.
export const RecordingUtils = {
getActiveBrowserID,
getProfileDataAsGzippedArrayBufferThenStop,
};