Skip to content
Merged
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
40 changes: 40 additions & 0 deletions front_end/models/trace/extras/StackTraceForEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,46 @@ export function get(event: Types.Events.Event, parsedTrace: Handlers.Types.Parse
return result;
}

export function getForReactNative(event: Types.Events.Event, parsedTrace: Handlers.Types.ParsedTrace): Protocol.Runtime.StackTrace |
null {
let cacheForTrace = stackTraceForEventInTrace.get(parsedTrace);
if (!cacheForTrace) {
cacheForTrace = new Map();
stackTraceForEventInTrace.set(parsedTrace, cacheForTrace);
}
const resultFromCache = cacheForTrace.get(event);
if (resultFromCache) {
return resultFromCache;
}
let result: Protocol.Runtime.StackTrace|null = null;

if (Types.Events.isUserTiming(event) && Types.Events.isPerformanceMeasureBegin(event)) {
result = extractStackTraceForReactNative(event);
} else if (Types.Extensions.isSyntheticExtensionEntry(event)) {
result = extractStackTraceForReactNative(event.rawSourceEvent);
} else if (Types.Events.isConsoleTimeStamp(event)) {
result = extractStackTraceForReactNative(event);
}

if (result) {
cacheForTrace.set(event, result);
}
return result;
}

export function extractStackTraceForReactNative(event: Types.Events.Event): Protocol.Runtime.StackTrace | null {
const data = event.args?.data;
if (!data) {
return null;
}

if (!data.rnStackTrace) {
return null;
}

return data.rnStackTrace;
}

function getForProfileCall(
event: Types.Events.SyntheticProfileCall, parsedTrace: Handlers.Types.ParsedTrace): Protocol.Runtime.StackTrace {
// When working with a CPU profile the renderer handler won't have
Expand Down
2 changes: 2 additions & 0 deletions front_end/models/trace/types/TraceEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ export interface Args {

export interface ArgsData {
stackTrace?: CallFrame[];
// [RN] Custom field for linking stack traces to User Timings and TimeStamp events.
rnStackTrace?: Protocol.Runtime.StackTrace;
sampleTraceId?: number;
url?: string;
navigationId?: string;
Expand Down
32 changes: 21 additions & 11 deletions front_end/panels/timeline/TimelineUIUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1838,22 +1838,32 @@ export class TimelineUIUtils {
const {startTime} = Trace.Helpers.Timing.eventTimingsMilliSeconds(event);
let initiatorStackLabel = i18nString(UIStrings.initiatorStackTrace);
let stackLabel = i18nString(UIStrings.stackTrace);
const stackTraceForEvent = Trace.Extras.StackTraceForEvent.get(event, parsedTrace);

// [RN] Used to scope down available features for React Native targets
// See https://docs.google.com/document/d/1_mtLIHEd9bFQN4xWBSVDR357GaRo56khB1aOxgWDeu4/edit?tab=t.0 for context.
const isReactNative = Root.Runtime.experiments.isEnabled(
Root.Runtime.ExperimentName.REACT_NATIVE_SPECIFIC_UI,
);
if (stackTraceForEvent && !isReactNative) {
contentHelper.addSection(i18nString(UIStrings.stackTrace));
contentHelper.createChildStackTraceElement(stackTraceForEvent);
// TODO(andoli): also build stack trace component for other events
// that have a stack trace using the StackTraceForEvent helper.
} else if (!isReactNative) {
const stackTrace = Trace.Helpers.Trace.getZeroIndexedStackTraceForEvent(event);
if (stackTrace?.length) {
contentHelper.addSection(stackLabel);
contentHelper.createChildStackTraceElement(TimelineUIUtils.stackTraceFromCallFrames(stackTrace));
if (isReactNative) {
const rnStackTrace = Trace.Extras.StackTraceForEvent.getForReactNative(event, parsedTrace);

if (rnStackTrace) {
contentHelper.addSection(i18nString(UIStrings.stackTrace));
contentHelper.createChildStackTraceElement(rnStackTrace);
}
} else {
const stackTraceForEvent = Trace.Extras.StackTraceForEvent.get(event, parsedTrace);
if (stackTraceForEvent) {
contentHelper.addSection(i18nString(UIStrings.stackTrace));
contentHelper.createChildStackTraceElement(stackTraceForEvent);
// TODO(andoli): also build stack trace component for other events
// that have a stack trace using the StackTraceForEvent helper.
} else {
const stackTrace = Trace.Helpers.Trace.getZeroIndexedStackTraceForEvent(event);
if (stackTrace?.length) {
contentHelper.addSection(stackLabel);
contentHelper.createChildStackTraceElement(TimelineUIUtils.stackTraceFromCallFrames(stackTrace));
}
}
}
switch (event.name) {
Expand Down
Loading