Skip to content

Commit

Permalink
Initial implementation of tracing hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
rubennorte committed Aug 6, 2024
1 parent 6590358 commit 2c44a11
Show file tree
Hide file tree
Showing 25 changed files with 712 additions and 65 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/runtime_build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: (Runtime) Build and Test

on:
push:
branches: [main]
branches: [rubennorte-programmatic-profiler]
pull_request:
paths-ignore:
- compiler/**
Expand Down
13 changes: 13 additions & 0 deletions packages/react-dom/src/client/ReactDOMRoot.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type {ReactNodeList, ReactFormState} from 'shared/ReactTypes';
import type {
FiberRoot,
TransitionTracingCallbacks,
TracingHooks,
} from 'react-reconciler/src/ReactInternalTypes';

import {isValidContainer} from 'react-dom-bindings/src/client/ReactDOMContainer';
Expand All @@ -27,6 +28,7 @@ export type RootType = {
export type CreateRootOptions = {
unstable_strictMode?: boolean,
unstable_transitionCallbacks?: TransitionTracingCallbacks,
unstable_tracingHooks?: TracingHooks,
identifierPrefix?: string,
onUncaughtError?: (
error: mixed,
Expand All @@ -52,6 +54,7 @@ export type HydrateRootOptions = {
// Options for all roots
unstable_strictMode?: boolean,
unstable_transitionCallbacks?: TransitionTracingCallbacks,
unstable_tracingHooks?: TracingHooks,
identifierPrefix?: string,
onUncaughtError?: (
error: mixed,
Expand Down Expand Up @@ -175,6 +178,7 @@ export function createRoot(
let onCaughtError = defaultOnCaughtError;
let onRecoverableError = defaultOnRecoverableError;
let transitionCallbacks = null;
let tracingHooks = null;

if (options !== null && options !== undefined) {
if (__DEV__) {
Expand Down Expand Up @@ -216,6 +220,9 @@ export function createRoot(
if (options.unstable_transitionCallbacks !== undefined) {
transitionCallbacks = options.unstable_transitionCallbacks;
}
if (options.unstable_tracingHooks !== undefined) {
tracingHooks = options.unstable_tracingHooks;
}
}

const root = createContainer(
Expand All @@ -229,6 +236,7 @@ export function createRoot(
onCaughtError,
onRecoverableError,
transitionCallbacks,
tracingHooks,
);
markContainerAsRoot(root.current, container);

Expand Down Expand Up @@ -286,6 +294,7 @@ export function hydrateRoot(
let onRecoverableError = defaultOnRecoverableError;
let transitionCallbacks = null;
let formState = null;
let tracingHooks = null;
if (options !== null && options !== undefined) {
if (options.unstable_strictMode === true) {
isStrictMode = true;
Expand All @@ -310,6 +319,9 @@ export function hydrateRoot(
formState = options.formState;
}
}
if (options.unstable_tracingHooks !== undefined) {
tracingHooks = options.unstable_tracingHooks;
}
}

const root = createHydrationContainer(
Expand All @@ -326,6 +338,7 @@ export function hydrateRoot(
onRecoverableError,
transitionCallbacks,
formState,
tracingHooks,
);
markContainerAsRoot(root.current, container);
// This can't be a comment node since hydration doesn't work on comment nodes anyway.
Expand Down
2 changes: 2 additions & 0 deletions packages/react-dom/src/client/ReactDOMRootFB.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ function legacyCreateRootFromDOMContainer(
// TODO(luna) Support hydration later
null,
null,
null,
);
container._reactRootContainer = root;
markContainerAsRoot(root.current, container);
Expand Down Expand Up @@ -273,6 +274,7 @@ function legacyCreateRootFromDOMContainer(
wwwOnCaughtError,
noopOnRecoverableError,
null, // transitionCallbacks
null, // tracingHooks
);
container._reactRootContainer = root;
markContainerAsRoot(root.current, container);
Expand Down
1 change: 1 addition & 0 deletions packages/react-native-renderer/src/ReactFabric.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ function render(
onCaughtError,
onRecoverableError,
null,
options?.tracingHooks != null ? options.tracingHooks : null,
);
roots.set(containerTag, root);
}
Expand Down
1 change: 1 addition & 0 deletions packages/react-native-renderer/src/ReactNativeRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ function render(
onCaughtError,
onRecoverableError,
null,
null,
);
roots.set(containerTag, root);
}
Expand Down
28 changes: 28 additions & 0 deletions packages/react-native-renderer/src/ReactNativeTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ export type RenderRootOptions = {
error: mixed,
errorInfo: {+componentStack?: ?string},
) => void,
tracingHooks?: ?TracingHooks,
};

/**
Expand Down Expand Up @@ -238,6 +239,33 @@ export opaque type InternalInstanceHandle = mixed;
type PublicInstance = mixed;
type PublicTextInstance = mixed;

export type TracingHooks = {
onCommitStarted?: () => void,
onCommitStopped?: () => void,
onComponentRenderStarted?: (componentName: ?string) => void,
onComponentRenderStopped?: () => void,
onComponentPassiveEffectMountStarted?: (componentName: ?string) => void,
onComponentPassiveEffectMountStopped?: () => void,
onComponentPassiveEffectUnmountStarted?: (componentName: ?string) => void,
onComponentPassiveEffectUnmountStopped?: () => void,
onComponentLayoutEffectMountStarted?: (componentName: ?string) => void,
onComponentLayoutEffectMountStopped?: () => void,
onComponentLayoutEffectUnmountStarted?: (componentName: ?string) => void,
onComponentLayoutEffectUnmountStopped?: () => void,
onComponentErrored?: (thrownValue: mixed) => void,
onComponentSuspended?: () => void,
onLayoutEffectsStarted?: () => void,
onLayoutEffectsStopped?: () => void,
onPassiveEffectsStarted?: () => void,
onPassiveEffectsStopped?: () => void,
onRenderStarted?: () => void,
onRenderYielded?: () => void,
onRenderStopped?: () => void,
onRenderScheduled?: () => void,
onForceUpdateScheduled?: (componentName: ?string) => void,
onStateUpdateScheduled?: (componentName: ?string) => void,
};

export type ReactFabricType = {
findHostInstance_DEPRECATED<TElementType: ElementType>(
componentOrHandle: ?(ElementRef<TElementType> | number),
Expand Down
74 changes: 62 additions & 12 deletions packages/react-reconciler/src/ReactFiberBeginWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,14 @@ import type {TransitionStatus} from './ReactFiberConfig';
import type {Hook} from './ReactFiberHooks';

import {
markComponentRenderStarted,
markComponentRenderStopped,
markComponentRenderStarted as markComponentRenderStartedInDevTools,
markComponentRenderStopped as markComponentRenderStoppedInDevTools,
setIsStrictModeForDevtools,
} from './ReactFiberDevToolsHook';
import {
markComponentRenderStarted as markComponentRenderStartedInTracingHooks,
markComponentRenderStopped as markComponentRenderStoppedInTracingHooks,
} from './ReactFiberTracingHook';
import {
FunctionComponent,
ClassComponent,
Expand Down Expand Up @@ -103,6 +107,7 @@ import {
enableLazyContextPropagation,
enableSchedulingProfiler,
enableTransitionTracing,
enableTracingHooks,
enableLegacyHidden,
enableCPUSuspense,
enableAsyncActions,
Expand Down Expand Up @@ -438,7 +443,13 @@ function updateForwardRef(
let hasId;
prepareToReadContext(workInProgress, renderLanes);
if (enableSchedulingProfiler) {
markComponentRenderStarted(workInProgress);
markComponentRenderStartedInDevTools(workInProgress);
}
if (enableTracingHooks) {
markComponentRenderStartedInTracingHooks(
getWorkInProgressRoot(),
workInProgress,
);
}
if (__DEV__) {
nextChildren = renderWithHooks(
Expand All @@ -462,7 +473,10 @@ function updateForwardRef(
hasId = checkDidRenderIdHook();
}
if (enableSchedulingProfiler) {
markComponentRenderStopped();
markComponentRenderStoppedInDevTools();
}
if (enableTracingHooks) {
markComponentRenderStoppedInTracingHooks(getWorkInProgressRoot());
}

if (current !== null && !didReceiveUpdate) {
Expand Down Expand Up @@ -1168,7 +1182,13 @@ function updateFunctionComponent(
let hasId;
prepareToReadContext(workInProgress, renderLanes);
if (enableSchedulingProfiler) {
markComponentRenderStarted(workInProgress);
markComponentRenderStartedInDevTools(workInProgress);
}
if (enableTracingHooks) {
markComponentRenderStartedInTracingHooks(
getWorkInProgressRoot(),
workInProgress,
);
}
if (__DEV__) {
nextChildren = renderWithHooks(
Expand All @@ -1192,7 +1212,10 @@ function updateFunctionComponent(
hasId = checkDidRenderIdHook();
}
if (enableSchedulingProfiler) {
markComponentRenderStopped();
markComponentRenderStoppedInDevTools();
}
if (enableTracingHooks) {
markComponentRenderStoppedInTracingHooks(getWorkInProgressRoot());
}

if (current !== null && !didReceiveUpdate) {
Expand Down Expand Up @@ -1224,7 +1247,13 @@ export function replayFunctionComponent(

prepareToReadContext(workInProgress, renderLanes);
if (enableSchedulingProfiler) {
markComponentRenderStarted(workInProgress);
markComponentRenderStartedInDevTools(workInProgress);
}
if (enableTracingHooks) {
markComponentRenderStartedInTracingHooks(
getWorkInProgressRoot(),
workInProgress,
);
}
const nextChildren = replaySuspendedComponentWithHooks(
current,
Expand All @@ -1235,7 +1264,10 @@ export function replayFunctionComponent(
);
const hasId = checkDidRenderIdHook();
if (enableSchedulingProfiler) {
markComponentRenderStopped();
markComponentRenderStoppedInDevTools();
}
if (enableTracingHooks) {
markComponentRenderStoppedInTracingHooks(getWorkInProgressRoot());
}

if (current !== null && !didReceiveUpdate) {
Expand Down Expand Up @@ -1410,7 +1442,13 @@ function finishClassComponent(
}
} else {
if (enableSchedulingProfiler) {
markComponentRenderStarted(workInProgress);
markComponentRenderStartedInDevTools(workInProgress);
}
if (enableTracingHooks) {
markComponentRenderStartedInTracingHooks(
getWorkInProgressRoot(),
workInProgress,
);
}
if (__DEV__) {
nextChildren = callRenderInDEV(instance);
Expand All @@ -1429,7 +1467,10 @@ function finishClassComponent(
nextChildren = instance.render();
}
if (enableSchedulingProfiler) {
markComponentRenderStopped();
markComponentRenderStoppedInDevTools();
}
if (enableTracingHooks) {
markComponentRenderStoppedInTracingHooks(getWorkInProgressRoot());
}
}

Expand Down Expand Up @@ -3450,7 +3491,13 @@ function updateContextConsumer(
prepareToReadContext(workInProgress, renderLanes);
const newValue = readContext(context);
if (enableSchedulingProfiler) {
markComponentRenderStarted(workInProgress);
markComponentRenderStartedInDevTools(workInProgress);
}
if (enableTracingHooks) {
markComponentRenderStartedInTracingHooks(
getWorkInProgressRoot(),
workInProgress,
);
}
let newChildren;
if (__DEV__) {
Expand All @@ -3459,7 +3506,10 @@ function updateContextConsumer(
newChildren = render(newValue);
}
if (enableSchedulingProfiler) {
markComponentRenderStopped();
markComponentRenderStoppedInDevTools();
}
if (enableTracingHooks) {
markComponentRenderStoppedInTracingHooks(getWorkInProgressRoot());
}

// React DevTools reads this flag.
Expand Down
24 changes: 19 additions & 5 deletions packages/react-reconciler/src/ReactFiberClassComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
disableLegacyContext,
enableDebugTracing,
enableSchedulingProfiler,
enableTracingHooks,
enableLazyContextPropagation,
enableRefAsProp,
disableDefaultPropsExceptForClasses,
Expand Down Expand Up @@ -68,10 +69,14 @@ import {readContext, checkIfContextChanged} from './ReactFiberNewContext';
import {requestUpdateLane, scheduleUpdateOnFiber} from './ReactFiberWorkLoop';
import {logForceUpdateScheduled, logStateUpdateScheduled} from './DebugTracing';
import {
markForceUpdateScheduled,
markStateUpdateScheduled,
markForceUpdateScheduled as markForceUpdateScheduledInDevTools,
markStateUpdateScheduled as markStateUpdateScheduledInDevTools,
setIsStrictModeForDevtools,
} from './ReactFiberDevToolsHook';
import {
markForceUpdateScheduled as markForceUpdateScheduledInTracingHooks,
markStateUpdateScheduled as markStateUpdateScheduledInTracingHooks,
} from './ReactFiberTracingHook';

const fakeInternalInstance = {};

Expand Down Expand Up @@ -208,7 +213,10 @@ const classComponentUpdater = {
}

if (enableSchedulingProfiler) {
markStateUpdateScheduled(fiber, lane);
markStateUpdateScheduledInDevTools(fiber, lane);
}
if (enableTracingHooks) {
markStateUpdateScheduledInTracingHooks(root, fiber);
}
},
enqueueReplaceState(inst: any, payload: any, callback: null) {
Expand Down Expand Up @@ -242,7 +250,10 @@ const classComponentUpdater = {
}

if (enableSchedulingProfiler) {
markStateUpdateScheduled(fiber, lane);
markStateUpdateScheduledInDevTools(fiber, lane);
}
if (enableTracingHooks) {
markStateUpdateScheduledInTracingHooks(root, fiber);
}
},
// $FlowFixMe[missing-local-annot]
Expand Down Expand Up @@ -276,7 +287,10 @@ const classComponentUpdater = {
}

if (enableSchedulingProfiler) {
markForceUpdateScheduled(fiber, lane);
markForceUpdateScheduledInDevTools(fiber, lane);
}
if (enableTracingHooks) {
markForceUpdateScheduledInTracingHooks(root, fiber);
}
},
};
Expand Down
Loading

0 comments on commit 2c44a11

Please sign in to comment.