Skip to content

Commit e04cefb

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 70b9d6c commit e04cefb

File tree

7 files changed

+65
-90
lines changed

7 files changed

+65
-90
lines changed

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

Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -205,30 +205,35 @@ export function getNextLanes(root: FiberRoot, wipLanes: Lanes): Lanes {
205205

206206
let nextLanes = NoLanes;
207207

208+
const expiredLanes = root.expiredLanes;
208209
const suspendedLanes = root.suspendedLanes;
209210
const pingedLanes = root.pingedLanes;
210211

211212
// Do not work on any idle work until all the non-idle work has finished,
212213
// even if the work is suspended.
213-
const nonIdlePendingLanes = pendingLanes & NonIdleLanes;
214-
if (nonIdlePendingLanes !== NoLanes) {
215-
const nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes;
216-
if (nonIdleUnblockedLanes !== NoLanes) {
217-
nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes);
218-
} else {
219-
const nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes;
220-
if (nonIdlePingedLanes !== NoLanes) {
221-
nextLanes = getHighestPriorityLanes(nonIdlePingedLanes);
222-
}
223-
}
214+
if (expiredLanes !== NoLanes) {
215+
nextLanes = SyncLane | expiredLanes;
224216
} else {
225-
// The only remaining work is Idle.
226-
const unblockedLanes = pendingLanes & ~suspendedLanes;
227-
if (unblockedLanes !== NoLanes) {
228-
nextLanes = getHighestPriorityLanes(unblockedLanes);
217+
const nonIdlePendingLanes = pendingLanes & NonIdleLanes;
218+
if (nonIdlePendingLanes !== NoLanes) {
219+
const nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes;
220+
if (nonIdleUnblockedLanes !== NoLanes) {
221+
nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes);
222+
} else {
223+
const nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes;
224+
if (nonIdlePingedLanes !== NoLanes) {
225+
nextLanes = getHighestPriorityLanes(nonIdlePingedLanes);
226+
}
227+
}
229228
} else {
230-
if (pingedLanes !== NoLanes) {
231-
nextLanes = getHighestPriorityLanes(pingedLanes);
229+
// The only remaining work is Idle.
230+
const unblockedLanes = pendingLanes & ~suspendedLanes;
231+
if (unblockedLanes !== NoLanes) {
232+
nextLanes = getHighestPriorityLanes(unblockedLanes);
233+
} else {
234+
if (pingedLanes !== NoLanes) {
235+
nextLanes = getHighestPriorityLanes(pingedLanes);
236+
}
232237
}
233238
}
234239
}
@@ -396,7 +401,6 @@ export function markStarvedLanesAsExpired(
396401
// expiration time. If so, we'll assume the update is being starved and mark
397402
// it as expired to force it to finish.
398403
let lanes = pendingLanes;
399-
let expiredLanes = 0;
400404
while (lanes > 0) {
401405
const index = pickArbitraryLaneIndex(lanes);
402406
const lane = 1 << index;
@@ -415,15 +419,11 @@ export function markStarvedLanesAsExpired(
415419
}
416420
} else if (expirationTime <= currentTime) {
417421
// This lane expired
418-
expiredLanes |= lane;
422+
root.expiredLanes |= lane;
419423
}
420424

421425
lanes &= ~lane;
422426
}
423-
424-
if (expiredLanes !== 0) {
425-
markRootExpired(root, expiredLanes);
426-
}
427427
}
428428

429429
// This returns the highest priority pending lanes regardless of whether they
@@ -596,17 +596,7 @@ export function markRootPinged(
596596
}
597597

598598
export function markRootExpired(root: FiberRoot, expiredLanes: Lanes) {
599-
const entanglements = root.entanglements;
600-
const SyncLaneIndex = 0;
601-
entanglements[SyncLaneIndex] |= expiredLanes;
602-
root.entangledLanes |= SyncLane;
603-
root.pendingLanes |= SyncLane;
604-
}
605-
606-
export function areLanesExpired(root: FiberRoot, lanes: Lanes) {
607-
const SyncLaneIndex = 0;
608-
const entanglements = root.entanglements;
609-
return (entanglements[SyncLaneIndex] & lanes) !== NoLanes;
599+
root.expiredLanes |= expiredLanes & root.pendingLanes;
610600
}
611601

612602
export function markRootMutableRead(root: FiberRoot, updateLane: Lane) {
@@ -622,6 +612,7 @@ export function markRootFinished(root: FiberRoot, remainingLanes: Lanes) {
622612
root.suspendedLanes = 0;
623613
root.pingedLanes = 0;
624614

615+
root.expiredLanes &= remainingLanes;
625616
root.mutableReadLanes &= remainingLanes;
626617

627618
root.entangledLanes &= remainingLanes;

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

Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -205,30 +205,35 @@ export function getNextLanes(root: FiberRoot, wipLanes: Lanes): Lanes {
205205

206206
let nextLanes = NoLanes;
207207

208+
const expiredLanes = root.expiredLanes;
208209
const suspendedLanes = root.suspendedLanes;
209210
const pingedLanes = root.pingedLanes;
210211

211212
// Do not work on any idle work until all the non-idle work has finished,
212213
// even if the work is suspended.
213-
const nonIdlePendingLanes = pendingLanes & NonIdleLanes;
214-
if (nonIdlePendingLanes !== NoLanes) {
215-
const nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes;
216-
if (nonIdleUnblockedLanes !== NoLanes) {
217-
nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes);
218-
} else {
219-
const nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes;
220-
if (nonIdlePingedLanes !== NoLanes) {
221-
nextLanes = getHighestPriorityLanes(nonIdlePingedLanes);
222-
}
223-
}
214+
if (expiredLanes !== NoLanes) {
215+
nextLanes = SyncLane | expiredLanes;
224216
} else {
225-
// The only remaining work is Idle.
226-
const unblockedLanes = pendingLanes & ~suspendedLanes;
227-
if (unblockedLanes !== NoLanes) {
228-
nextLanes = getHighestPriorityLanes(unblockedLanes);
217+
const nonIdlePendingLanes = pendingLanes & NonIdleLanes;
218+
if (nonIdlePendingLanes !== NoLanes) {
219+
const nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes;
220+
if (nonIdleUnblockedLanes !== NoLanes) {
221+
nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes);
222+
} else {
223+
const nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes;
224+
if (nonIdlePingedLanes !== NoLanes) {
225+
nextLanes = getHighestPriorityLanes(nonIdlePingedLanes);
226+
}
227+
}
229228
} else {
230-
if (pingedLanes !== NoLanes) {
231-
nextLanes = getHighestPriorityLanes(pingedLanes);
229+
// The only remaining work is Idle.
230+
const unblockedLanes = pendingLanes & ~suspendedLanes;
231+
if (unblockedLanes !== NoLanes) {
232+
nextLanes = getHighestPriorityLanes(unblockedLanes);
233+
} else {
234+
if (pingedLanes !== NoLanes) {
235+
nextLanes = getHighestPriorityLanes(pingedLanes);
236+
}
232237
}
233238
}
234239
}
@@ -396,7 +401,6 @@ export function markStarvedLanesAsExpired(
396401
// expiration time. If so, we'll assume the update is being starved and mark
397402
// it as expired to force it to finish.
398403
let lanes = pendingLanes;
399-
let expiredLanes = 0;
400404
while (lanes > 0) {
401405
const index = pickArbitraryLaneIndex(lanes);
402406
const lane = 1 << index;
@@ -415,15 +419,11 @@ export function markStarvedLanesAsExpired(
415419
}
416420
} else if (expirationTime <= currentTime) {
417421
// This lane expired
418-
expiredLanes |= lane;
422+
root.expiredLanes |= lane;
419423
}
420424

421425
lanes &= ~lane;
422426
}
423-
424-
if (expiredLanes !== 0) {
425-
markRootExpired(root, expiredLanes);
426-
}
427427
}
428428

429429
// This returns the highest priority pending lanes regardless of whether they
@@ -596,17 +596,7 @@ export function markRootPinged(
596596
}
597597

598598
export function markRootExpired(root: FiberRoot, expiredLanes: Lanes) {
599-
const entanglements = root.entanglements;
600-
const SyncLaneIndex = 0;
601-
entanglements[SyncLaneIndex] |= expiredLanes;
602-
root.entangledLanes |= SyncLane;
603-
root.pendingLanes |= SyncLane;
604-
}
605-
606-
export function areLanesExpired(root: FiberRoot, lanes: Lanes) {
607-
const SyncLaneIndex = 0;
608-
const entanglements = root.entanglements;
609-
return (entanglements[SyncLaneIndex] & lanes) !== NoLanes;
599+
root.expiredLanes |= expiredLanes & root.pendingLanes;
610600
}
611601

612602
export function markRootMutableRead(root: FiberRoot, updateLane: Lane) {
@@ -622,6 +612,7 @@ export function markRootFinished(root: FiberRoot, remainingLanes: Lanes) {
622612
root.suspendedLanes = 0;
623613
root.pingedLanes = 0;
624614

615+
root.expiredLanes &= remainingLanes;
625616
root.mutableReadLanes &= remainingLanes;
626617

627618
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
markRootPinged,
158158
markRootExpired,
159159
markRootFinished,
160-
areLanesExpired,
161160
getHighestPriorityLane,
162161
} from './ReactFiberLane.new';
163162
import {
@@ -973,7 +972,7 @@ function performSyncWorkOnRoot(root) {
973972
let exitStatus;
974973
if (
975974
root === workInProgressRoot &&
976-
areLanesExpired(root, workInProgressRootRenderLanes)
975+
includesSomeLane(root.expiredLanes, workInProgressRootRenderLanes)
977976
) {
978977
// There's a partial tree, and at least one of its lanes has expired. Finish
979978
// rendering it before rendering the rest of the expired work.
@@ -1029,16 +1028,12 @@ function performSyncWorkOnRoot(root) {
10291028
return null;
10301029
}
10311030

1032-
// TODO: Do we still need this API? I think we can delete it. Was only used
1033-
// internally.
10341031
export function flushRoot(root: FiberRoot, lanes: Lanes) {
1035-
if (lanes !== NoLanes) {
1036-
markRootExpired(root, lanes);
1037-
ensureRootIsScheduled(root, now());
1038-
if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
1039-
resetRenderTimer();
1040-
flushSyncCallbackQueue();
1041-
}
1032+
markRootExpired(root, lanes);
1033+
ensureRootIsScheduled(root, now());
1034+
if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
1035+
resetRenderTimer();
1036+
flushSyncCallbackQueue();
10421037
}
10431038
}
10441039

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
markRootPinged,
158158
markRootExpired,
159159
markRootFinished,
160-
areLanesExpired,
161160
getHighestPriorityLane,
162161
} from './ReactFiberLane.old';
163162
import {
@@ -973,7 +972,7 @@ function performSyncWorkOnRoot(root) {
973972
let exitStatus;
974973
if (
975974
root === workInProgressRoot &&
976-
areLanesExpired(root, workInProgressRootRenderLanes)
975+
includesSomeLane(root.expiredLanes, workInProgressRootRenderLanes)
977976
) {
978977
// There's a partial tree, and at least one of its lanes has expired. Finish
979978
// rendering it before rendering the rest of the expired work.
@@ -1029,16 +1028,12 @@ function performSyncWorkOnRoot(root) {
10291028
return null;
10301029
}
10311030

1032-
// TODO: Do we still need this API? I think we can delete it. Was only used
1033-
// internally.
10341031
export function flushRoot(root: FiberRoot, lanes: Lanes) {
1035-
if (lanes !== NoLanes) {
1036-
markRootExpired(root, lanes);
1037-
ensureRootIsScheduled(root, now());
1038-
if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
1039-
resetRenderTimer();
1040-
flushSyncCallbackQueue();
1041-
}
1032+
markRootExpired(root, lanes);
1033+
ensureRootIsScheduled(root, now());
1034+
if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
1035+
resetRenderTimer();
1036+
flushSyncCallbackQueue();
10421037
}
10431038
}
10441039

packages/react-reconciler/src/ReactInternalTypes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ type BaseFiberRootProperties = {|
228228
pendingLanes: Lanes,
229229
suspendedLanes: Lanes,
230230
pingedLanes: Lanes,
231+
expiredLanes: Lanes,
231232
mutableReadLanes: Lanes,
232233

233234
finishedLanes: Lanes,

0 commit comments

Comments
 (0)