Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs-developer/CHANGELOG-formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ Note that this is not an exhaustive list. Processed profile format upgraders can

## Processed profile format

### Version 72

FileIO marker schemas now have a `tableLabel`. Marker label templates can wrap optional segments in `[[` and `]]`; an optional segment is omitted when any payload field it references is absent or empty.

### Version 71

The frame table (`profile.shared.frameTable`) representation changed in such a way that all its columns can now be typed arrays when using [JsonSlabs](https://github.com/mstange/json-slabs/) profiles.
Expand Down
2 changes: 1 addition & 1 deletion src/app-logic/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const GECKO_PROFILE_VERSION = 36;
// The current version of the "processed" profile format.
// Please don't forget to update the processed profile format changelog in
// `docs-developer/CHANGELOG-formats.md`.
export const PROCESSED_PROFILE_VERSION = 71;
export const PROCESSED_PROFILE_VERSION = 72;

// The following are the margin sizes for the left and right of the timeline. Independent
// components need to share these values.
Expand Down
81 changes: 59 additions & 22 deletions src/profile-logic/marker-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,28 @@ export function getSchemaFromMarker(

// Matches ternary expressions inside marker labels, ie {marker.data.field ? 'truthy' : 'falsy'}
const TERNARY_RE = /^\s*([\w.]+)\s*\?\s*'([^']*)'\s*:\s*'([^']*)'\s*$/;
const OPTIONAL_SEGMENT_RE = /\[\[([\s\S]*?)\]\]/;
const OPTIONAL_SEGMENT_PAYLOAD_KEY_RE =
/\{\s*marker\.data\.([^.{}\s?]+)(?=\s*(?:\}|\?))/g;

export const FILE_IO_TABLE_LABEL =
'[[({marker.data.source}) ]]{marker.data.operation}[[ — {marker.data.filename}]]';

export function addFileIoTableLabel(schema: {
name: string;
tableLabel?: string;
}): void {
if (schema.name === 'FileIO' && schema.tableLabel === undefined) {
schema.tableLabel = FILE_IO_TABLE_LABEL;
}
}

/**
* Marker schema can create a dynamic tooltip label. For instance a schema with
* a `tooltipLabel` field of "Event at {marker.data.url}" would create a label based
* off of the "url" property in the payload.
* Segments wrapped in `[[` and `]]` are omitted when any payload field they
* reference is absent or empty.
*
* Note that this is only exported for unit tests.
*/
Expand All @@ -127,6 +144,47 @@ export function parseLabel(
stringTable: StringTable,
label: string
): (marker: Marker) => string {
const segments = label.split(OPTIONAL_SEGMENT_RE);
if (segments.length > 1) {
const computeSegments = segments.map((segment, index) => {
const computeSegment = parseLabel(
markerSchema,
categories,
stringTable,
segment
);
if (index % 2 === 0) {
return computeSegment;
}

const payloadKeys = Array.from(
segment.matchAll(OPTIONAL_SEGMENT_PAYLOAD_KEY_RE),
(match) => match[1]
);
if (payloadKeys.length === 0) {
return (marker: Marker) => `[[${computeSegment(marker)}]]`;
}

return (marker: Marker) => {
for (const payloadKey of payloadKeys) {
const value = (marker.data as any)?.[payloadKey];
if (value === undefined || value === null || value === '') {
return '';
}
}
return computeSegment(marker);
};
});

return (marker: Marker) => {
let result: string = '';
for (const computeSegment of computeSegments) {
result += computeSegment(marker);
}
return result;
};
}

// Split the label on the "{key}" capture groups.
// Each (zero-indexed) even entry will be a raw string label.
// Each (zero-indexed) odd entry will be a key to the payload.
Expand Down Expand Up @@ -301,28 +359,7 @@ const fallbacks: Record<LabelKey, (marker: any) => string> = {

chartLabel: (_marker) => '',

tableLabel: (marker: Marker) => {
let description = '';

if (marker.data) {
const data = marker.data;
switch (data.type) {
case 'FileIO':
if (data.source) {
description = `(${data.source}) `;
}
description += data.operation;
if (data.filename) {
description = data.operation
? `${description} — ${data.filename}`
: data.filename;
}
break;
default:
}
}
return description;
},
tableLabel: (_marker) => '',

copyLabel: (marker) => marker.name,
};
Expand Down
9 changes: 7 additions & 2 deletions src/profile-logic/process-profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ import {
toFloat64Array,
toFloat64ArraySetNullToZero,
} from '../utils/typed-arrays';
import { computeStringIndexMarkerFieldsByDataType } from '../profile-logic/marker-schema';
import {
addFileIoTableLabel,
computeStringIndexMarkerFieldsByDataType,
} from '../profile-logic/marker-schema';
import { convertJsTracerToThread } from '../profile-logic/js-tracer';

import type { StringTable } from '../utils/string-table';
Expand Down Expand Up @@ -1722,7 +1725,7 @@ function _convertGeckoMarkerSchema(
description = staticFields[staticDescriptionFieldIndex].value;
}

return {
const processedMarkerSchema = {
name,
tooltipLabel,
tableLabel,
Expand All @@ -1734,6 +1737,8 @@ function _convertGeckoMarkerSchema(
colorField,
isStackBased,
};
addFileIoTableLabel(processedMarkerSchema);
return processedMarkerSchema;
}

/**
Expand Down
7 changes: 7 additions & 0 deletions src/profile-logic/processed-profile-versioning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { StringTable } from '../utils/string-table';
import { timeCode } from '../utils/time-code';
import { PROCESSED_PROFILE_VERSION } from '../app-logic/constants';
import { ProfileVersionError } from './errors';
import { addFileIoTableLabel } from './marker-schema';
import type { Profile } from 'firefox-profiler/types';

export type ProfileUpgradeInfo = {
Expand Down Expand Up @@ -3433,6 +3434,12 @@ const _upgraders: {
frameTable.address = new Uint32Array(frameTable.address);
}
},
[72]: (profile: any) => {
// Ensure FileIO marker schemas provide their schema-driven table label.
for (const schema of profile.meta.markerSchema ?? []) {
addFileIoTableLabel(schema);
}
},
// If you add a new upgrader here, please document the change in
// `docs-developer/CHANGELOG-formats.md`.
};
Expand Down
2 changes: 2 additions & 0 deletions src/test/fixtures/profiles/marker-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import type { MarkerSchema } from 'firefox-profiler/types';
import { FILE_IO_TABLE_LABEL } from '../../../profile-logic/marker-schema';

export const markerSchemaForTests: MarkerSchema[] = [
{
Expand All @@ -27,6 +28,7 @@ export const markerSchemaForTests: MarkerSchema[] = [
},
{
name: 'FileIO',
tableLabel: FILE_IO_TABLE_LABEL,
display: ['marker-chart', 'marker-table'],
fields: [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Object {
"markerSchema": Array [],
"oscpu": "macOS 14.6.1",
"pausedRanges": Array [],
"preprocessedProfileVersion": 71,
"preprocessedProfileVersion": 72,
"processType": 0,
"product": "a.out",
"sampleUnits": Object {
Expand Down Expand Up @@ -1488,7 +1488,7 @@ Object {
"markerSchema": Array [],
"oscpu": "macOS 14.6.1",
"pausedRanges": Array [],
"preprocessedProfileVersion": 71,
"preprocessedProfileVersion": 72,
"processType": 0,
"product": "a.out",
"sampleUnits": Object {
Expand Down Expand Up @@ -2889,7 +2889,7 @@ Object {
"markerSchema": Array [],
"oscpu": "macOS 14.6.1",
"pausedRanges": Array [],
"preprocessedProfileVersion": 71,
"preprocessedProfileVersion": 72,
"processType": 0,
"product": "a.out",
"sampleUnits": Object {
Expand Down Expand Up @@ -4290,7 +4290,7 @@ Object {
"markerSchema": Array [],
"oscpu": "macOS 14.6.1",
"pausedRanges": Array [],
"preprocessedProfileVersion": 71,
"preprocessedProfileVersion": 72,
"processType": 0,
"product": "a.out",
"sampleUnits": Object {
Expand Down
3 changes: 2 additions & 1 deletion src/test/store/__snapshots__/profile-view.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ Object {
},
],
"name": "FileIO",
"tableLabel": "[[({marker.data.source}) ]]{marker.data.operation}[[ — {marker.data.filename}]]",
},
Object {
"display": Array [
Expand Down Expand Up @@ -428,7 +429,7 @@ Object {
"oscpu": "",
"physicalCPUs": 0,
"platform": "",
"preprocessedProfileVersion": 71,
"preprocessedProfileVersion": 72,
"processType": 0,
"product": "Firefox",
"sourceURL": "",
Expand Down
Loading
Loading