From 38a297d50035d86290a44d6e9bd8bc19f335013b Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Tue, 20 Dec 2016 20:56:02 -0800 Subject: [PATCH 1/8] Always reset context before beginning new work This consolidates the reset of context to one single place right before any new work is started. This place is burried in a bit of an awkward place but findNextUnitOfWork happens right before any new work starts. That way we're guaranteed to have an empty stack before we start anything new. The benefit of this is that we don't have to rely .return being null when entering beginWork but we also don't have to check it every time in the hot path. --- .../shared/fiber/ReactFiberBeginWork.js | 9 +-------- .../shared/fiber/ReactFiberCompleteWork.js | 1 + .../shared/fiber/ReactFiberScheduler.js | 17 ++++++++++++++--- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/renderers/shared/fiber/ReactFiberBeginWork.js b/src/renderers/shared/fiber/ReactFiberBeginWork.js index 17142c6a06de..b12418dbc69e 100644 --- a/src/renderers/shared/fiber/ReactFiberBeginWork.js +++ b/src/renderers/shared/fiber/ReactFiberBeginWork.js @@ -36,7 +36,6 @@ var { hasContextChanged, pushContextProvider, pushTopLevelContextObject, - resetContext, } = require('ReactFiberContext'); var { IndeterminateComponent, @@ -80,7 +79,6 @@ module.exports = function( const { pushHostContext, pushHostContainer, - resetHostContainer, } = hostContext; const { @@ -437,6 +435,7 @@ module.exports = function( if (isHostComponent) { pushHostContext(workInProgress); } else { + // TODO: Unify this switch with the other branches above. switch (workInProgress.tag) { case ClassComponent: if (isContextProvider(workInProgress)) { @@ -473,12 +472,6 @@ module.exports = function( } function beginWork(current : ?Fiber, workInProgress : Fiber, priorityLevel : PriorityLevel) : ?Fiber { - if (!workInProgress.return) { - // Don't start new work with context on the stack. - resetContext(); - resetHostContainer(); - } - if (workInProgress.pendingWorkPriority === NoWork || workInProgress.pendingWorkPriority > priorityLevel) { return bailoutOnLowPriority(current, workInProgress); diff --git a/src/renderers/shared/fiber/ReactFiberCompleteWork.js b/src/renderers/shared/fiber/ReactFiberCompleteWork.js index 16e044456bb9..214d471d7efa 100644 --- a/src/renderers/shared/fiber/ReactFiberCompleteWork.js +++ b/src/renderers/shared/fiber/ReactFiberCompleteWork.js @@ -189,6 +189,7 @@ module.exports = function( return null; } case HostRoot: { + // TODO: Pop the host container after #8607 lands. workInProgress.memoizedProps = workInProgress.pendingProps; const fiberRoot = (workInProgress.stateNode : FiberRoot); if (fiberRoot.pendingContext) { diff --git a/src/renderers/shared/fiber/ReactFiberScheduler.js b/src/renderers/shared/fiber/ReactFiberScheduler.js index 7ab79b05b107..defece414bdd 100644 --- a/src/renderers/shared/fiber/ReactFiberScheduler.js +++ b/src/renderers/shared/fiber/ReactFiberScheduler.js @@ -58,6 +58,7 @@ var { } = require('ReactFiberUpdateQueue'); var { + resetContext, unwindContext, } = require('ReactFiberContext'); @@ -153,6 +154,11 @@ module.exports = function(config : HostConfig(config : HostConfig(config : HostConfig Date: Tue, 20 Dec 2016 21:36:35 -0800 Subject: [PATCH 2/8] Move all the begin work stuff into their own helper functions This just moves things around to continue the pattern that we already started. --- .../shared/fiber/ReactFiberBeginWork.js | 69 ++++++++++--------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/src/renderers/shared/fiber/ReactFiberBeginWork.js b/src/renderers/shared/fiber/ReactFiberBeginWork.js index b12418dbc69e..cb7688c7cb08 100644 --- a/src/renderers/shared/fiber/ReactFiberBeginWork.js +++ b/src/renderers/shared/fiber/ReactFiberBeginWork.js @@ -169,6 +169,7 @@ module.exports = function( function updateFragment(current, workInProgress) { var nextChildren = workInProgress.pendingProps; reconcileChildren(current, workInProgress, nextChildren); + return workInProgress.child; } function updateFunctionalComponent(current, workInProgress) { @@ -242,6 +243,30 @@ module.exports = function( return workInProgress.child; } + function updateHostRoot(current, workInProgress, priorityLevel) { + const root = (workInProgress.stateNode : FiberRoot); + if (root.pendingContext) { + pushTopLevelContextObject( + root.pendingContext, + root.pendingContext !== root.context + ); + } else { + pushTopLevelContextObject(root.context, false); + } + + pushHostContainer(root.containerInfo); + + const updateQueue = workInProgress.updateQueue; + if (updateQueue) { + const prevState = workInProgress.memoizedState; + const state = beginUpdateQueue(workInProgress, updateQueue, null, prevState, null, priorityLevel); + const element = state.element; + reconcileChildren(current, workInProgress, element); + workInProgress.memoizedState = state; + } + return workInProgress.child; + } + function updateHostComponent(current, workInProgress) { const nextProps = workInProgress.pendingProps; const prevProps = current ? current.memoizedProps : null; @@ -342,9 +367,13 @@ module.exports = function( throw new Error('Should be resolved by now'); } reconcileChildren(current, workInProgress, coroutine.children); + // This doesn't take arbitrary time so we could synchronously just begin + // eagerly do the work of workInProgress.child as an optimization. + return workInProgress.child; } function updatePortalComponent(current, workInProgress) { + pushHostContainer(workInProgress.stateNode.containerInfo); const priorityLevel = workInProgress.pendingWorkPriority; const nextChildren = workInProgress.pendingProps; if (!current) { @@ -363,6 +392,7 @@ module.exports = function( } else { reconcileChildren(current, workInProgress, nextChildren); } + return workInProgress.child; } /* @@ -517,31 +547,8 @@ module.exports = function( return updateFunctionalComponent(current, workInProgress); case ClassComponent: return updateClassComponent(current, workInProgress, priorityLevel); - case HostRoot: { - const root = (workInProgress.stateNode : FiberRoot); - if (root.pendingContext) { - pushTopLevelContextObject( - root.pendingContext, - root.pendingContext !== root.context - ); - } else { - pushTopLevelContextObject(root.context, false); - } - - pushHostContainer(root.containerInfo); - - if (updateQueue) { - const prevState = workInProgress.memoizedState; - const state = beginUpdateQueue(workInProgress, updateQueue, null, prevState, null, priorityLevel); - const element = state.element; - reconcileChildren(current, workInProgress, element); - workInProgress.memoizedState = state; - } - - // A yield component is just a placeholder, we can just run through the - // next one immediately. - return workInProgress.child; - } + case HostRoot: + return updateHostRoot(current, workInProgress, priorityLevel); case HostComponent: return updateHostComponent(current, workInProgress); case HostText: @@ -553,21 +560,15 @@ module.exports = function( workInProgress.tag = CoroutineComponent; // Intentionally fall through since this is now the same. case CoroutineComponent: - updateCoroutineComponent(current, workInProgress); - // This doesn't take arbitrary time so we could synchronously just begin - // eagerly do the work of workInProgress.child as an optimization. - return workInProgress.child; + return updateCoroutineComponent(current, workInProgress); case YieldComponent: // A yield component is just a placeholder, we can just run through the // next one immediately. return null; case HostPortal: - pushHostContainer(workInProgress.stateNode.containerInfo); - updatePortalComponent(current, workInProgress); - return workInProgress.child; + return updatePortalComponent(current, workInProgress); case Fragment: - updateFragment(current, workInProgress); - return workInProgress.child; + return updateFragment(current, workInProgress); default: throw new Error('Unknown unit of work tag'); } From 5a32fdb8e5e41d23cf6b2590d50c5ec1e1d53b21 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Tue, 20 Dec 2016 22:41:38 -0800 Subject: [PATCH 3/8] Compare memoized props in functional component branch The functional component branch is a bit special since it has sCU in it. The class component branch actually already covers this in a bit convoluted way. I will next replicate this check in each other branch. --- .../shared/fiber/ReactFiberBeginWork.js | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/renderers/shared/fiber/ReactFiberBeginWork.js b/src/renderers/shared/fiber/ReactFiberBeginWork.js index cb7688c7cb08..f219c7066cd3 100644 --- a/src/renderers/shared/fiber/ReactFiberBeginWork.js +++ b/src/renderers/shared/fiber/ReactFiberBeginWork.js @@ -174,26 +174,33 @@ module.exports = function( function updateFunctionalComponent(current, workInProgress) { var fn = workInProgress.type; - var props = workInProgress.pendingProps; - var context = getMaskedContext(workInProgress); + var nextProps = workInProgress.pendingProps; - // TODO: Disable this before release, since it is not part of the public API - // I use this for testing to compare the relative overhead of classes. - if (typeof fn.shouldComponentUpdate === 'function') { - if (workInProgress.memoizedProps !== null) { - if (!fn.shouldComponentUpdate(workInProgress.memoizedProps, props)) { - return bailoutOnAlreadyFinishedWork(current, workInProgress); - } + const memoizedProps = workInProgress.memoizedProps; + if (hasContextChanged()) { + // Normally we can bail out on props equality but if context has changed + // we don't do the bailout and we have to reuse existing props instead. + if (nextProps === null) { + nextProps = current && current.memoizedProps; } + } else if (nextProps === null || memoizedProps === nextProps || ( + // TODO: Disable this before release, since it is not part of the public API + // I use this for testing to compare the relative overhead of classes. + typeof fn.shouldComponentUpdate === 'function' && + !fn.shouldComponentUpdate(memoizedProps, nextProps) + )) { + return bailoutOnAlreadyFinishedWork(current, workInProgress); } + var context = getMaskedContext(workInProgress); + var nextChildren; if (__DEV__) { ReactCurrentOwner.current = workInProgress; - nextChildren = fn(props, context); + nextChildren = fn(nextProps, context); } else { - nextChildren = fn(props, context); + nextChildren = fn(nextProps, context); } reconcileChildren(current, workInProgress, nextChildren); return workInProgress.child; From 0907a49abd709308e95a93e11dde16d67c06dd43 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Wed, 21 Dec 2016 11:34:13 -0800 Subject: [PATCH 4/8] Add bailout to HostRoot This doesn't need to compare props because it doesn't use props, only state. --- src/renderers/shared/fiber/ReactFiberBeginWork.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/renderers/shared/fiber/ReactFiberBeginWork.js b/src/renderers/shared/fiber/ReactFiberBeginWork.js index f219c7066cd3..e43e3e6f8302 100644 --- a/src/renderers/shared/fiber/ReactFiberBeginWork.js +++ b/src/renderers/shared/fiber/ReactFiberBeginWork.js @@ -267,11 +267,18 @@ module.exports = function( if (updateQueue) { const prevState = workInProgress.memoizedState; const state = beginUpdateQueue(workInProgress, updateQueue, null, prevState, null, priorityLevel); + if (prevState === state) { + // If the state is the same as before, that's a bailout because we had + // no work matching this priority. + return bailoutOnAlreadyFinishedWork(current, workInProgress); + } const element = state.element; reconcileChildren(current, workInProgress, element); workInProgress.memoizedState = state; + return workInProgress.child; } - return workInProgress.child; + // If there is no update queue, that's a bailout because the root has no props. + return bailoutOnAlreadyFinishedWork(current, workInProgress); } function updateHostComponent(current, workInProgress) { From 21dccad47f26eed4709f59aaf9a897c358f957aa Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Tue, 20 Dec 2016 23:47:37 -0800 Subject: [PATCH 5/8] Move props equality check into each branch Now we only bail out once we've entered each branch. This has some repetition with regard to hasContextChanged but I'm hoping we can just get rid of all those branches at some point since they're mostly for backwards compatibility right now. --- .../shared/fiber/ReactFiberBeginWork.js | 75 +++++++++++++------ 1 file changed, 51 insertions(+), 24 deletions(-) diff --git a/src/renderers/shared/fiber/ReactFiberBeginWork.js b/src/renderers/shared/fiber/ReactFiberBeginWork.js index e43e3e6f8302..a798c0300866 100644 --- a/src/renderers/shared/fiber/ReactFiberBeginWork.js +++ b/src/renderers/shared/fiber/ReactFiberBeginWork.js @@ -168,6 +168,15 @@ module.exports = function( function updateFragment(current, workInProgress) { var nextChildren = workInProgress.pendingProps; + if (hasContextChanged()) { + // Normally we can bail out on props equality but if context has changed + // we don't do the bailout and we have to reuse existing props instead. + if (nextChildren === null) { + nextChildren = current && current.memoizedProps; + } + } else if (nextChildren === null || workInProgress.memoizedProps === nextChildren) { + return bailoutOnAlreadyFinishedWork(current, workInProgress); + } reconcileChildren(current, workInProgress, nextChildren); return workInProgress.child; } @@ -282,8 +291,22 @@ module.exports = function( } function updateHostComponent(current, workInProgress) { - const nextProps = workInProgress.pendingProps; + let nextProps = workInProgress.pendingProps; const prevProps = current ? current.memoizedProps : null; + const memoizedProps = workInProgress.memoizedProps; + if (hasContextChanged()) { + // Normally we can bail out on props equality but if context has changed + // we don't do the bailout and we have to reuse existing props instead. + if (nextProps === null) { + nextProps = prevProps; + if (!nextProps) { + throw new Error('We should always have pending or current props.'); + } + } + } else if (nextProps === null || memoizedProps === nextProps) { + return bailoutOnAlreadyFinishedWork(current, workInProgress); + } + let nextChildren = nextProps.children; const isDirectTextChild = shouldSetTextContent(nextProps); @@ -376,11 +399,20 @@ module.exports = function( } function updateCoroutineComponent(current, workInProgress) { - var coroutine = (workInProgress.pendingProps : ?ReactCoroutine); - if (!coroutine) { - throw new Error('Should be resolved by now'); + var nextCoroutine = (workInProgress.pendingProps : null | ReactCoroutine); + if (hasContextChanged()) { + // Normally we can bail out on props equality but if context has changed + // we don't do the bailout and we have to reuse existing props instead. + if (nextCoroutine === null) { + nextCoroutine = current && current.memoizedProps; + if (!nextCoroutine) { + throw new Error('We should always have pending or current props.'); + } + } + } else if (nextCoroutine === null || workInProgress.memoizedProps === nextCoroutine) { + return bailoutOnAlreadyFinishedWork(current, workInProgress); } - reconcileChildren(current, workInProgress, coroutine.children); + reconcileChildren(current, workInProgress, nextCoroutine.children); // This doesn't take arbitrary time so we could synchronously just begin // eagerly do the work of workInProgress.child as an optimization. return workInProgress.child; @@ -389,7 +421,20 @@ module.exports = function( function updatePortalComponent(current, workInProgress) { pushHostContainer(workInProgress.stateNode.containerInfo); const priorityLevel = workInProgress.pendingWorkPriority; - const nextChildren = workInProgress.pendingProps; + let nextChildren = workInProgress.pendingProps; + if (hasContextChanged()) { + // Normally we can bail out on props equality but if context has changed + // we don't do the bailout and we have to reuse existing props instead. + if (nextChildren === null) { + nextChildren = current && current.memoizedProps; + if (!nextChildren) { + throw new Error('We should always have pending or current props.'); + } + } + } else if (nextChildren === null || workInProgress.memoizedProps === nextChildren) { + return bailoutOnAlreadyFinishedWork(current, workInProgress); + } + if (!current) { // Portals are special because we don't append the children during mount // but at commit. Therefore we need to track insertions which the normal @@ -536,24 +581,6 @@ module.exports = function( workInProgress.child = workInProgress.progressedChild; } - const pendingProps = workInProgress.pendingProps; - const memoizedProps = workInProgress.memoizedProps; - const updateQueue = workInProgress.updateQueue; - - // This is kept as a single expression to take advantage of short-circuiting. - const hasNewProps = ( - pendingProps !== null && ( // hasPendingProps && ( - memoizedProps === null || // hasNoMemoizedProps || - pendingProps !== memoizedProps // memoizedPropsDontMatch - ) // ) - ); - if (!hasNewProps) { - const hasUpdate = updateQueue && hasPendingUpdate(updateQueue, priorityLevel); - if (!hasUpdate && !hasContextChanged()) { - return bailoutOnAlreadyFinishedWork(current, workInProgress); - } - } - switch (workInProgress.tag) { case IndeterminateComponent: return mountIndeterminateComponent(current, workInProgress, priorityLevel); From b7548b20300226f72cead5e3997db439c23ca601 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Tue, 20 Dec 2016 23:51:14 -0800 Subject: [PATCH 6/8] Delete hasPendingUpdate This is no longer needed. It is effectively covered by other branches that tries to being merging the update queue which yields the same state object as before if there is no work. That in turn bails out. We can shortcut in the relevant paths if needed. --- src/renderers/shared/fiber/ReactFiberBeginWork.js | 1 - src/renderers/shared/fiber/ReactFiberUpdateQueue.js | 9 --------- 2 files changed, 10 deletions(-) diff --git a/src/renderers/shared/fiber/ReactFiberBeginWork.js b/src/renderers/shared/fiber/ReactFiberBeginWork.js index a798c0300866..5b383adf6b04 100644 --- a/src/renderers/shared/fiber/ReactFiberBeginWork.js +++ b/src/renderers/shared/fiber/ReactFiberBeginWork.js @@ -26,7 +26,6 @@ var { cloneChildFibers, } = require('ReactChildFiber'); var { - hasPendingUpdate, beginUpdateQueue, } = require('ReactFiberUpdateQueue'); var ReactTypeOfWork = require('ReactTypeOfWork'); diff --git a/src/renderers/shared/fiber/ReactFiberUpdateQueue.js b/src/renderers/shared/fiber/ReactFiberUpdateQueue.js index fdabc5e9d80f..fb1c6f500b3b 100644 --- a/src/renderers/shared/fiber/ReactFiberUpdateQueue.js +++ b/src/renderers/shared/fiber/ReactFiberUpdateQueue.js @@ -80,15 +80,6 @@ function comparePriority(a : PriorityLevel, b : PriorityLevel) : number { return a - b; } -function hasPendingUpdate(queue : UpdateQueue, priorityLevel : PriorityLevel) : boolean { - if (!queue.first) { - return false; - } - // Return true if the first pending update has greater or equal priority. - return comparePriority(queue.first.priorityLevel, priorityLevel) <= 0; -} -exports.hasPendingUpdate = hasPendingUpdate; - // Ensures that a fiber has an update queue, creating a new one if needed. // Returns the new or existing queue. function ensureUpdateQueue(fiber : Fiber) : UpdateQueue { From 9a210114e464d717e0ba9f2d3e5d936adfbad1db Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Wed, 21 Dec 2016 00:05:46 -0800 Subject: [PATCH 7/8] Move isHostComponent branches out of bailout Since we only call bailout from within the host component branch now, we can just move this to the branch where we already know that this is a host component. As part of this I noticed that we don't always push the host context so I moved that to the beginning of the branch. --- .../shared/fiber/ReactFiberBeginWork.js | 70 ++++++++----------- 1 file changed, 31 insertions(+), 39 deletions(-) diff --git a/src/renderers/shared/fiber/ReactFiberBeginWork.js b/src/renderers/shared/fiber/ReactFiberBeginWork.js index 5b383adf6b04..fb8307339683 100644 --- a/src/renderers/shared/fiber/ReactFiberBeginWork.js +++ b/src/renderers/shared/fiber/ReactFiberBeginWork.js @@ -290,6 +290,8 @@ module.exports = function( } function updateHostComponent(current, workInProgress) { + pushHostContext(workInProgress); + let nextProps = workInProgress.pendingProps; const prevProps = current ? current.memoizedProps : null; const memoizedProps = workInProgress.memoizedProps; @@ -303,6 +305,24 @@ module.exports = function( } } } else if (nextProps === null || memoizedProps === nextProps) { + if (memoizedProps.hidden && + workInProgress.pendingWorkPriority !== OffscreenPriority) { + // This subtree still has work, but it should be deprioritized so we need + // to bail out and not do any work yet. + // TODO: It would be better if this tree got its correct priority set + // during scheduleUpdate instead because otherwise we'll start a higher + // priority reconciliation first before we can get down here. However, + // that is a bit tricky since workInProgress and current can have + // different "hidden" settings. + let child = workInProgress.progressedChild; + while (child) { + // To ensure that this subtree gets its priority reset, the children + // need to be reset. + child.pendingWorkPriority = OffscreenPriority; + child = child.sibling; + } + return null; + } return bailoutOnAlreadyFinishedWork(current, workInProgress); } @@ -359,7 +379,6 @@ module.exports = function( // Abort and don't process children yet. return null; } else { - pushHostContext(workInProgress); reconcileChildren(current, workInProgress, nextChildren); return workInProgress.child; } @@ -474,28 +493,6 @@ module.exports = function( function bailoutOnAlreadyFinishedWork(current, workInProgress : Fiber) : ?Fiber { const priorityLevel = workInProgress.pendingWorkPriority; - const isHostComponent = workInProgress.tag === HostComponent; - - if (isHostComponent && - workInProgress.memoizedProps.hidden && - workInProgress.pendingWorkPriority !== OffscreenPriority) { - // This subtree still has work, but it should be deprioritized so we need - // to bail out and not do any work yet. - // TODO: It would be better if this tree got its correct priority set - // during scheduleUpdate instead because otherwise we'll start a higher - // priority reconciliation first before we can get down here. However, - // that is a bit tricky since workInProgress and current can have - // different "hidden" settings. - let child = workInProgress.progressedChild; - while (child) { - // To ensure that this subtree gets its priority reset, the children - // need to be reset. - child.pendingWorkPriority = OffscreenPriority; - child = child.sibling; - } - return null; - } - // TODO: We should ideally be able to bail out early if the children have no // more work to do. However, since we don't have a separation of this // Fiber's priority and its children yet - we don't know without doing lots @@ -519,23 +516,18 @@ module.exports = function( cloneChildFibers(current, workInProgress); markChildAsProgressed(current, workInProgress, priorityLevel); - // Put context on the stack because we will work on children - if (isHostComponent) { - pushHostContext(workInProgress); - } else { - // TODO: Unify this switch with the other branches above. - switch (workInProgress.tag) { - case ClassComponent: - if (isContextProvider(workInProgress)) { - pushContextProvider(workInProgress, false); - } - break; - case HostRoot: - case HostPortal: - pushHostContainer(workInProgress.stateNode.containerInfo); - break; - } + switch (workInProgress.tag) { + case ClassComponent: + if (isContextProvider(workInProgress)) { + pushContextProvider(workInProgress, false); + } + break; + case HostRoot: + case HostPortal: + pushHostContainer(workInProgress.stateNode.containerInfo); + break; } + // TODO: this is annoyingly duplicating non-jump codepaths. return workInProgress.child; From 26c82cea7244c333ee671a02ef976b87faa1d0a5 Mon Sep 17 00:00:00 2001 From: Sebastian Markbage Date: Wed, 21 Dec 2016 00:10:00 -0800 Subject: [PATCH 8/8] Move other branches out of the bail out This is the same thing as the previous commit but with class, root and portal. I noticed host and portal now already covers this case in their branches since pushHostContainer is always at the top. --- .../shared/fiber/ReactFiberBeginWork.js | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/renderers/shared/fiber/ReactFiberBeginWork.js b/src/renderers/shared/fiber/ReactFiberBeginWork.js index fb8307339683..a1cede0ee337 100644 --- a/src/renderers/shared/fiber/ReactFiberBeginWork.js +++ b/src/renderers/shared/fiber/ReactFiberBeginWork.js @@ -243,6 +243,11 @@ module.exports = function( workInProgress.effectTag |= Update; } } + + // Don't forget to push the context before returning. + if (isContextProvider(workInProgress)) { + pushContextProvider(workInProgress, false); + } return bailoutOnAlreadyFinishedWork(current, workInProgress); } @@ -515,21 +520,6 @@ module.exports = function( cloneChildFibers(current, workInProgress); markChildAsProgressed(current, workInProgress, priorityLevel); - - switch (workInProgress.tag) { - case ClassComponent: - if (isContextProvider(workInProgress)) { - pushContextProvider(workInProgress, false); - } - break; - case HostRoot: - case HostPortal: - pushHostContainer(workInProgress.stateNode.containerInfo); - break; - } - - // TODO: this is annoyingly duplicating non-jump codepaths. - return workInProgress.child; }