Skip to content

Commit 162188d

Browse files
committed
Partial revert of "Entangled expired lanes with SyncLane (facebook#21083)"
This partially reverts facebook#21083 while keeping the new behavior. It adds back the `root.expiredLanes` field, instead of using the `entanglements` array.
1 parent 60f378f commit 162188d

File tree

7 files changed

+77
-100
lines changed

7 files changed

+77
-100
lines changed

packages/react-reconciler/src/ReactFiberLane.new.js

Lines changed: 31 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -286,38 +286,44 @@ export function getNextLanes(root: FiberRoot, wipLanes: Lanes): Lanes {
286286
let nextLanes = NoLanes;
287287
let nextLanePriority = NoLanePriority;
288288

289+
const expiredLanes = root.expiredLanes;
289290
const suspendedLanes = root.suspendedLanes;
290291
const pingedLanes = root.pingedLanes;
291292

292-
// Do not work on any idle work until all the non-idle work has finished,
293-
// even if the work is suspended.
294-
const nonIdlePendingLanes = pendingLanes & NonIdleLanes;
295-
if (nonIdlePendingLanes !== NoLanes) {
296-
const nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes;
297-
if (nonIdleUnblockedLanes !== NoLanes) {
298-
nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes);
299-
nextLanePriority = return_highestLanePriority;
300-
} else {
301-
const nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes;
302-
if (nonIdlePingedLanes !== NoLanes) {
303-
nextLanes = getHighestPriorityLanes(nonIdlePingedLanes);
293+
// Check if any work has expired.
294+
if (expiredLanes !== NoLanes) {
295+
nextLanes = expiredLanes | SyncLane;
296+
nextLanePriority = return_highestLanePriority = SyncLanePriority;
297+
} else {
298+
// Do not work on any idle work until all the non-idle work has finished,
299+
// even if the work is suspended.
300+
const nonIdlePendingLanes = pendingLanes & NonIdleLanes;
301+
if (nonIdlePendingLanes !== NoLanes) {
302+
const nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes;
303+
if (nonIdleUnblockedLanes !== NoLanes) {
304+
nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes);
304305
nextLanePriority = return_highestLanePriority;
306+
} else {
307+
const nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes;
308+
if (nonIdlePingedLanes !== NoLanes) {
309+
nextLanes = getHighestPriorityLanes(nonIdlePingedLanes);
310+
nextLanePriority = return_highestLanePriority;
311+
}
305312
}
306-
}
307-
} else {
308-
// The only remaining work is Idle.
309-
const unblockedLanes = pendingLanes & ~suspendedLanes;
310-
if (unblockedLanes !== NoLanes) {
311-
nextLanes = getHighestPriorityLanes(unblockedLanes);
312-
nextLanePriority = return_highestLanePriority;
313313
} else {
314-
if (pingedLanes !== NoLanes) {
315-
nextLanes = getHighestPriorityLanes(pingedLanes);
314+
// The only remaining work is Idle.
315+
const unblockedLanes = pendingLanes & ~suspendedLanes;
316+
if (unblockedLanes !== NoLanes) {
317+
nextLanes = getHighestPriorityLanes(unblockedLanes);
316318
nextLanePriority = return_highestLanePriority;
319+
} else {
320+
if (pingedLanes !== NoLanes) {
321+
nextLanes = getHighestPriorityLanes(pingedLanes);
322+
nextLanePriority = return_highestLanePriority;
323+
}
317324
}
318325
}
319326
}
320-
321327
if (nextLanes === NoLanes) {
322328
// This should only be reachable if we're suspended
323329
// TODO: Consider warning in this path if a fallback timer is not scheduled.
@@ -455,7 +461,6 @@ export function markStarvedLanesAsExpired(
455461
// expiration time. If so, we'll assume the update is being starved and mark
456462
// it as expired to force it to finish.
457463
let lanes = pendingLanes;
458-
let expiredLanes = 0;
459464
while (lanes > 0) {
460465
const index = pickArbitraryLaneIndex(lanes);
461466
const lane = 1 << index;
@@ -474,15 +479,11 @@ export function markStarvedLanesAsExpired(
474479
}
475480
} else if (expirationTime <= currentTime) {
476481
// This lane expired
477-
expiredLanes |= lane;
482+
root.expiredLanes |= lane;
478483
}
479484

480485
lanes &= ~lane;
481486
}
482-
483-
if (expiredLanes !== 0) {
484-
markRootExpired(root, expiredLanes);
485-
}
486487
}
487488

488489
// This returns the highest priority pending lanes regardless of whether they
@@ -665,17 +666,7 @@ export function markRootPinged(
665666
}
666667

667668
export function markRootExpired(root: FiberRoot, expiredLanes: Lanes) {
668-
const entanglements = root.entanglements;
669-
const SyncLaneIndex = 0;
670-
entanglements[SyncLaneIndex] |= expiredLanes;
671-
root.entangledLanes |= SyncLane;
672-
root.pendingLanes |= SyncLane;
673-
}
674-
675-
export function areLanesExpired(root: FiberRoot, lanes: Lanes) {
676-
const SyncLaneIndex = 0;
677-
const entanglements = root.entanglements;
678-
return (entanglements[SyncLaneIndex] & lanes) !== NoLanes;
669+
root.expiredLanes |= expiredLanes & root.pendingLanes;
679670
}
680671

681672
export function markRootMutableRead(root: FiberRoot, updateLane: Lane) {
@@ -691,6 +682,7 @@ export function markRootFinished(root: FiberRoot, remainingLanes: Lanes) {
691682
root.suspendedLanes = 0;
692683
root.pingedLanes = 0;
693684

685+
root.expiredLanes &= remainingLanes;
694686
root.mutableReadLanes &= remainingLanes;
695687

696688
root.entangledLanes &= remainingLanes;

packages/react-reconciler/src/ReactFiberLane.old.js

Lines changed: 31 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -286,38 +286,44 @@ export function getNextLanes(root: FiberRoot, wipLanes: Lanes): Lanes {
286286
let nextLanes = NoLanes;
287287
let nextLanePriority = NoLanePriority;
288288

289+
const expiredLanes = root.expiredLanes;
289290
const suspendedLanes = root.suspendedLanes;
290291
const pingedLanes = root.pingedLanes;
291292

292-
// Do not work on any idle work until all the non-idle work has finished,
293-
// even if the work is suspended.
294-
const nonIdlePendingLanes = pendingLanes & NonIdleLanes;
295-
if (nonIdlePendingLanes !== NoLanes) {
296-
const nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes;
297-
if (nonIdleUnblockedLanes !== NoLanes) {
298-
nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes);
299-
nextLanePriority = return_highestLanePriority;
300-
} else {
301-
const nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes;
302-
if (nonIdlePingedLanes !== NoLanes) {
303-
nextLanes = getHighestPriorityLanes(nonIdlePingedLanes);
293+
// Check if any work has expired.
294+
if (expiredLanes !== NoLanes) {
295+
nextLanes = expiredLanes | SyncLane;
296+
nextLanePriority = return_highestLanePriority = SyncLanePriority;
297+
} else {
298+
// Do not work on any idle work until all the non-idle work has finished,
299+
// even if the work is suspended.
300+
const nonIdlePendingLanes = pendingLanes & NonIdleLanes;
301+
if (nonIdlePendingLanes !== NoLanes) {
302+
const nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes;
303+
if (nonIdleUnblockedLanes !== NoLanes) {
304+
nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes);
304305
nextLanePriority = return_highestLanePriority;
306+
} else {
307+
const nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes;
308+
if (nonIdlePingedLanes !== NoLanes) {
309+
nextLanes = getHighestPriorityLanes(nonIdlePingedLanes);
310+
nextLanePriority = return_highestLanePriority;
311+
}
305312
}
306-
}
307-
} else {
308-
// The only remaining work is Idle.
309-
const unblockedLanes = pendingLanes & ~suspendedLanes;
310-
if (unblockedLanes !== NoLanes) {
311-
nextLanes = getHighestPriorityLanes(unblockedLanes);
312-
nextLanePriority = return_highestLanePriority;
313313
} else {
314-
if (pingedLanes !== NoLanes) {
315-
nextLanes = getHighestPriorityLanes(pingedLanes);
314+
// The only remaining work is Idle.
315+
const unblockedLanes = pendingLanes & ~suspendedLanes;
316+
if (unblockedLanes !== NoLanes) {
317+
nextLanes = getHighestPriorityLanes(unblockedLanes);
316318
nextLanePriority = return_highestLanePriority;
319+
} else {
320+
if (pingedLanes !== NoLanes) {
321+
nextLanes = getHighestPriorityLanes(pingedLanes);
322+
nextLanePriority = return_highestLanePriority;
323+
}
317324
}
318325
}
319326
}
320-
321327
if (nextLanes === NoLanes) {
322328
// This should only be reachable if we're suspended
323329
// TODO: Consider warning in this path if a fallback timer is not scheduled.
@@ -455,7 +461,6 @@ export function markStarvedLanesAsExpired(
455461
// expiration time. If so, we'll assume the update is being starved and mark
456462
// it as expired to force it to finish.
457463
let lanes = pendingLanes;
458-
let expiredLanes = 0;
459464
while (lanes > 0) {
460465
const index = pickArbitraryLaneIndex(lanes);
461466
const lane = 1 << index;
@@ -474,15 +479,11 @@ export function markStarvedLanesAsExpired(
474479
}
475480
} else if (expirationTime <= currentTime) {
476481
// This lane expired
477-
expiredLanes |= lane;
482+
root.expiredLanes |= lane;
478483
}
479484

480485
lanes &= ~lane;
481486
}
482-
483-
if (expiredLanes !== 0) {
484-
markRootExpired(root, expiredLanes);
485-
}
486487
}
487488

488489
// This returns the highest priority pending lanes regardless of whether they
@@ -665,17 +666,7 @@ export function markRootPinged(
665666
}
666667

667668
export function markRootExpired(root: FiberRoot, expiredLanes: Lanes) {
668-
const entanglements = root.entanglements;
669-
const SyncLaneIndex = 0;
670-
entanglements[SyncLaneIndex] |= expiredLanes;
671-
root.entangledLanes |= SyncLane;
672-
root.pendingLanes |= SyncLane;
673-
}
674-
675-
export function areLanesExpired(root: FiberRoot, lanes: Lanes) {
676-
const SyncLaneIndex = 0;
677-
const entanglements = root.entanglements;
678-
return (entanglements[SyncLaneIndex] & lanes) !== NoLanes;
669+
root.expiredLanes |= expiredLanes & root.pendingLanes;
679670
}
680671

681672
export function markRootMutableRead(root: FiberRoot, updateLane: Lane) {
@@ -691,6 +682,7 @@ export function markRootFinished(root: FiberRoot, remainingLanes: Lanes) {
691682
root.suspendedLanes = 0;
692683
root.pingedLanes = 0;
693684

685+
root.expiredLanes &= remainingLanes;
694686
root.mutableReadLanes &= remainingLanes;
695687

696688
root.entangledLanes &= remainingLanes;

packages/react-reconciler/src/ReactFiberRoot.new.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ function FiberRootNode(containerInfo, tag, hydrate) {
4848
this.pendingLanes = NoLanes;
4949
this.suspendedLanes = NoLanes;
5050
this.pingedLanes = NoLanes;
51+
this.expiredLanes = NoLanes;
5152
this.mutableReadLanes = NoLanes;
5253
this.finishedLanes = NoLanes;
5354

packages/react-reconciler/src/ReactFiberRoot.old.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ function FiberRootNode(containerInfo, tag, hydrate) {
4848
this.pendingLanes = NoLanes;
4949
this.suspendedLanes = NoLanes;
5050
this.pingedLanes = NoLanes;
51+
this.expiredLanes = NoLanes;
5152
this.mutableReadLanes = NoLanes;
5253
this.finishedLanes = NoLanes;
5354

packages/react-reconciler/src/ReactFiberWorkLoop.new.js

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,6 @@ import {
157157
markRootExpired,
158158
markRootFinished,
159159
lanePriorityToSchedulerPriority,
160-
areLanesExpired,
161160
} from './ReactFiberLane.new';
162161
import {
163162
DiscreteEventPriority,
@@ -967,7 +966,7 @@ function performSyncWorkOnRoot(root) {
967966
let exitStatus;
968967
if (
969968
root === workInProgressRoot &&
970-
areLanesExpired(root, workInProgressRootRenderLanes)
969+
includesSomeLane(root.expiredLanes, workInProgressRootRenderLanes)
971970
) {
972971
// There's a partial tree, and at least one of its lanes has expired. Finish
973972
// rendering it before rendering the rest of the expired work.
@@ -1023,16 +1022,12 @@ function performSyncWorkOnRoot(root) {
10231022
return null;
10241023
}
10251024

1026-
// TODO: Do we still need this API? I think we can delete it. Was only used
1027-
// internally.
10281025
export function flushRoot(root: FiberRoot, lanes: Lanes) {
1029-
if (lanes !== NoLanes) {
1030-
markRootExpired(root, lanes);
1031-
ensureRootIsScheduled(root, now());
1032-
if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
1033-
resetRenderTimer();
1034-
flushSyncCallbackQueue();
1035-
}
1026+
markRootExpired(root, lanes);
1027+
ensureRootIsScheduled(root, now());
1028+
if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
1029+
resetRenderTimer();
1030+
flushSyncCallbackQueue();
10361031
}
10371032
}
10381033

packages/react-reconciler/src/ReactFiberWorkLoop.old.js

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,6 @@ import {
157157
markRootExpired,
158158
markRootFinished,
159159
lanePriorityToSchedulerPriority,
160-
areLanesExpired,
161160
} from './ReactFiberLane.old';
162161
import {
163162
DiscreteEventPriority,
@@ -967,7 +966,7 @@ function performSyncWorkOnRoot(root) {
967966
let exitStatus;
968967
if (
969968
root === workInProgressRoot &&
970-
areLanesExpired(root, workInProgressRootRenderLanes)
969+
includesSomeLane(root.expiredLanes, workInProgressRootRenderLanes)
971970
) {
972971
// There's a partial tree, and at least one of its lanes has expired. Finish
973972
// rendering it before rendering the rest of the expired work.
@@ -1023,16 +1022,12 @@ function performSyncWorkOnRoot(root) {
10231022
return null;
10241023
}
10251024

1026-
// TODO: Do we still need this API? I think we can delete it. Was only used
1027-
// internally.
10281025
export function flushRoot(root: FiberRoot, lanes: Lanes) {
1029-
if (lanes !== NoLanes) {
1030-
markRootExpired(root, lanes);
1031-
ensureRootIsScheduled(root, now());
1032-
if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
1033-
resetRenderTimer();
1034-
flushSyncCallbackQueue();
1035-
}
1026+
markRootExpired(root, lanes);
1027+
ensureRootIsScheduled(root, now());
1028+
if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
1029+
resetRenderTimer();
1030+
flushSyncCallbackQueue();
10361031
}
10371032
}
10381033

packages/react-reconciler/src/ReactInternalTypes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ type BaseFiberRootProperties = {|
230230
pendingLanes: Lanes,
231231
suspendedLanes: Lanes,
232232
pingedLanes: Lanes,
233+
expiredLanes: Lanes,
233234
mutableReadLanes: Lanes,
234235

235236
finishedLanes: Lanes,

0 commit comments

Comments
 (0)