Skip to content

Commit

Permalink
Rolled temporary didBailout attribute into subtreeTag
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Vaughn committed Jul 11, 2020
1 parent b22b7ca commit 0d1a83e
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 33 deletions.
8 changes: 3 additions & 5 deletions packages/react-reconciler/src/ReactFiber.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
enableBlocksAPI,
} from 'shared/ReactFeatureFlags';
import {NoEffect, Placement} from './ReactSideEffectTags';
import {NoEffect as NoSubtreeEffect} from './ReactSubtreeTags';
import {ConcurrentRoot, BlockingRoot} from './ReactRootTags';
import {
IndeterminateComponent,
Expand Down Expand Up @@ -144,8 +145,7 @@ function FiberNode(

// Effects
this.effectTag = NoEffect;
this.subtreeTag = NoEffect;
this.didBailout = false; // TODO (effects) Move this value into subtreeTag
this.subtreeTag = NoSubtreeEffect;
this.deletions = null;
this.nextEffect = null;

Expand Down Expand Up @@ -290,8 +290,7 @@ export function createWorkInProgress(current: Fiber, pendingProps: any): Fiber {
// We already have an alternate.
// Reset the effect tag.
workInProgress.effectTag = NoEffect;
workInProgress.subtreeTag = NoEffect;
workInProgress.didBailout = false;
workInProgress.subtreeTag = NoSubtreeEffect;
workInProgress.deletions = null;

// The effect list is no longer valid.
Expand Down Expand Up @@ -833,7 +832,6 @@ export function assignFiberPropertiesInDEV(
target.mode = source.mode;
target.effectTag = source.effectTag;
target.subtreeTag = source.subtreeTag;
target.didBailout = source.didBailout;
target.deletions = source.deletions;
target.nextEffect = source.nextEffect;
target.firstEffect = source.firstEffect;
Expand Down
5 changes: 2 additions & 3 deletions packages/react-reconciler/src/ReactFiberBeginWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import {
Deletion,
ForceUpdateForLegacySuspense,
} from './ReactSideEffectTags';
import {DidBailout} from './ReactSubtreeTags';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import {
debugRenderPhaseSideEffectsForStrictMode,
Expand Down Expand Up @@ -2993,9 +2994,7 @@ function bailoutOnAlreadyFinishedWork(
// and we replay the work, even though we skip render phase (by bailing out)
// we don't want to bailout on commit effects too.
// However, this check seems overly aggressive in some cases.
// TODO (effects) Move this value into subtreeTag
workInProgress.didBailout = true;
workInProgress.subtreeTag = NoEffect;
workInProgress.subtreeTag = DidBailout;

// The children don't have any work either. We can skip them.
// TODO: Once we add back resuming, we should check if the children are
Expand Down
77 changes: 53 additions & 24 deletions packages/react-reconciler/src/ReactFiberWorkLoop.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ import {
Placement,
Update,
PlacementAndUpdate,
Deletion,
Ref,
ContentReset,
Snapshot,
Expand All @@ -109,7 +108,17 @@ import {
HostEffectMask,
Hydrating,
HydratingAndUpdate,
BeforeMutationMask,
MutationMask,
LayoutMask,
} from './ReactSideEffectTags';
import {
NoEffect as NoSubtreeTag,
DidBailout,
BeforeMutation,
Mutation,
Layout,
} from './ReactSubtreeTags';
import {
NoLanePriority,
SyncLanePriority,
Expand Down Expand Up @@ -1743,7 +1752,7 @@ function completeUnitOfWork(unitOfWork: Fiber): void {
// Mark the parent fiber as incomplete and clear its effect list.
returnFiber.firstEffect = returnFiber.lastEffect = null;
returnFiber.effectTag |= Incomplete;
returnFiber.subtreeTag = NoEffect;
returnFiber.subtreeTag = NoSubtreeTag;
returnFiber.deletions = null;
}
}
Expand Down Expand Up @@ -1781,8 +1790,10 @@ function resetChildLanes(completedWork: Fiber) {
return;
}

const didBailout = (completedWork.subtreeTag & DidBailout) !== NoSubtreeTag;

let newChildLanes = NoLanes;
let subtreeTag = NoEffect;
let subtreeTag = NoSubtreeTag;
let childrenDidNotComplete = false;

// Bubble up the earliest expiration time.
Expand All @@ -1799,10 +1810,19 @@ function resetChildLanes(completedWork: Fiber) {
mergeLanes(child.lanes, child.childLanes),
);

if (!completedWork.didBailout) {
subtreeTag |= child.subtreeTag;
// TODO (effects) Document why this exception is important
subtreeTag |= child.effectTag & HostEffectMask;
if (!didBailout) {
subtreeTag |= child.subtreeTag & ~DidBailout;

const effectTag = child.effectTag;
if ((effectTag & BeforeMutationMask) !== NoEffect) {
subtreeTag |= BeforeMutation;
}
if ((effectTag & MutationMask) !== NoEffect) {
subtreeTag |= Mutation;
}
if ((effectTag & LayoutMask) !== NoEffect) {
subtreeTag |= Layout;
}
}

if ((child.effectTag & Incomplete) !== NoEffect) {
Expand All @@ -1816,7 +1836,7 @@ function resetChildLanes(completedWork: Fiber) {
// this value will reflect the amount of time spent working on a previous
// render. In that case it should not bubble. We determine whether it was
// cloned by comparing the child pointer.
if (!completedWork.didBailout) {
if (!didBailout) {
actualDuration += child.actualDuration;
}
treeBaseDuration += child.treeBaseDuration;
Expand Down Expand Up @@ -1844,10 +1864,19 @@ function resetChildLanes(completedWork: Fiber) {
mergeLanes(child.lanes, child.childLanes),
);

if (!completedWork.didBailout) {
subtreeTag |= child.subtreeTag;
// TODO (effects) Document why this exception is important
subtreeTag |= child.effectTag & HostEffectMask;
if (!didBailout) {
subtreeTag |= child.subtreeTag & ~DidBailout;

const effectTag = child.effectTag;
if ((effectTag & BeforeMutationMask) !== NoEffect) {
subtreeTag |= BeforeMutation;
}
if ((effectTag & MutationMask) !== NoEffect) {
subtreeTag |= Mutation;
}
if ((effectTag & LayoutMask) !== NoEffect) {
subtreeTag |= Layout;
}
}

if ((child.effectTag & Incomplete) !== NoEffect) {
Expand Down Expand Up @@ -2126,10 +2155,10 @@ function commitBeforeMutationEffects(fiber: Fiber) {
commitBeforeMutationEffectsDeletions(fiber.deletions);
}

if (fiber.child !== null && !fiber.didBailOut) {
const primarySubtreeTag =
fiber.subtreeTag & (Deletion | Snapshot | Passive | Placement);
if (primarySubtreeTag !== NoEffect) {
const didBailout = (fiber.subtreeTag & DidBailout) !== NoSubtreeTag;
if (fiber.child !== null && !didBailout) {
const primarySubtreeTag = fiber.subtreeTag & BeforeMutation;
if (primarySubtreeTag !== NoSubtreeTag) {
commitBeforeMutationEffects(fiber.child);
}
}
Expand Down Expand Up @@ -2219,11 +2248,10 @@ function commitMutationEffects(
fiber.deletions = null;
}

if (fiber.child !== null && !fiber.didBailOut) {
const primarySubtreeTag =
fiber.subtreeTag &
(ContentReset | Deletion | Hydrating | Placement | Ref | Update);
if (primarySubtreeTag !== NoEffect) {
const didBailout = (fiber.subtreeTag & DidBailout) !== NoSubtreeTag;
if (fiber.child !== null && !didBailout) {
const primarySubtreeTag = fiber.subtreeTag & Mutation;
if (primarySubtreeTag !== NoSubtreeTag) {
commitMutationEffects(fiber.child, root, renderPriorityLevel);
}
}
Expand Down Expand Up @@ -2363,9 +2391,10 @@ function commitLayoutEffects(
root: FiberRoot,
committedLanes: Lanes,
) {
if (fiber.child !== null && !fiber.didBailOut) {
const primarySubtreeTag = fiber.subtreeTag & (Update | Callback | Ref);
if (primarySubtreeTag !== NoEffect) {
const didBailout = (fiber.subtreeTag & DidBailout) !== NoSubtreeTag;
if (fiber.child !== null && !didBailout) {
const primarySubtreeTag = fiber.subtreeTag & Layout;
if (primarySubtreeTag !== NoSubtreeTag) {
commitLayoutEffects(fiber.child, root, committedLanes);
}
}
Expand Down
3 changes: 2 additions & 1 deletion packages/react-reconciler/src/ReactInternalTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import type {SuspenseInstance} from './ReactFiberHostConfig';
import type {WorkTag} from './ReactWorkTags';
import type {TypeOfMode} from './ReactTypeOfMode';
import type {SideEffectTag} from './ReactSideEffectTags';
import type {SubtreeTag} from './ReactSubtreeTags';
import type {Lane, LanePriority, Lanes, LaneMap} from './ReactFiberLane';
import type {HookType} from './ReactFiberHooks.old';
import type {RootTag} from './ReactRootTags';
Expand Down Expand Up @@ -126,7 +127,7 @@ export type Fiber = {|

// Effect
effectTag: SideEffectTag,
subtreeTag: SideEffectTag,
subtreeTag: SubtreeTag,
deletions: Array<Fiber> | null,

// Singly linked list fast path to the next fiber with side-effects.
Expand Down
5 changes: 5 additions & 0 deletions packages/react-reconciler/src/ReactSideEffectTags.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,8 @@ export const HostEffectMask = /* */ 0b000011111111111;
export const Incomplete = /* */ 0b000100000000000;
export const ShouldCapture = /* */ 0b001000000000000;
export const ForceUpdateForLegacySuspense = /* */ 0b100000000000000;

// Union of side effect groupings as pertains to subtreeTag
export const BeforeMutationMask = /* */ 0b000001100001010;
export const MutationMask = /* */ 0b000010010011110;
export const LayoutMask = /* */ 0b000000010100100;
16 changes: 16 additions & 0 deletions packages/react-reconciler/src/ReactSubtreeTags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

export type SubtreeTag = number;

export const NoEffect = /* */ 0b0000;
export const DidBailout = /* */ 0b0001;
export const BeforeMutation = /* */ 0b0010;
export const Mutation = /* */ 0b0100;
export const Layout = /* */ 0b1000;

0 comments on commit 0d1a83e

Please sign in to comment.