Delay some RenderFrameHost destructions during navigation [chromium/src : main]

0 views
Skip to first unread message

Aldo Culquicondor (Gerrit)

unread,
Sep 12, 2025, 11:47:14 AM (6 days ago) Sep 12
to AyeAye, Chromium Metrics Reviews, chromium...@chromium.org, Chromium LUCI CQ, performance-m...@chromium.org, android-web...@chromium.org, bmcquad...@chromium.org, speed-metrics...@chromium.org, rouslan+au...@chromium.org, pdf-r...@chromium.org, csharris...@chromium.org, chromium-a...@chromium.org, browser-comp...@chromium.org, speed-metr...@chromium.org, extension...@chromium.org, loading-rev...@chromium.org, alexmo...@chromium.org, asvitkine...@chromium.org, creis...@chromium.org, navigation...@chromium.org
Attention needed from Aldo Culquicondor

Message from Aldo Culquicondor

Set Ready For Review

Open in Gerrit

Related details

Attention is currently required from:
  • Aldo Culquicondor
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I089e6c27f920ae403562f97f5785db934ae1f061
Gerrit-Change-Number: 6777031
Gerrit-PatchSet: 13
Gerrit-Owner: Aldo Culquicondor <aco...@chromium.org>
Gerrit-Reviewer: Aldo Culquicondor <aco...@chromium.org>
Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
Gerrit-Attention: Aldo Culquicondor <aco...@chromium.org>
Gerrit-Comment-Date: Fri, 12 Sep 2025 15:47:10 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Aldo Culquicondor (Gerrit)

unread,
Sep 12, 2025, 1:47:48 PM (6 days ago) Sep 12
to Alex Moshchuk, Iman Saboori, AyeAye, Chromium Metrics Reviews, chromium...@chromium.org, Chromium LUCI CQ, performance-m...@chromium.org, android-web...@chromium.org, bmcquad...@chromium.org, speed-metrics...@chromium.org, rouslan+au...@chromium.org, pdf-r...@chromium.org, csharris...@chromium.org, chromium-a...@chromium.org, browser-comp...@chromium.org, speed-metr...@chromium.org, extension...@chromium.org, loading-rev...@chromium.org, alexmo...@chromium.org, asvitkine...@chromium.org, creis...@chromium.org, navigation...@chromium.org
Attention needed from Alex Moshchuk

Aldo Culquicondor added 1 comment

Patchset-level comments
File-level comment, Patchset 14 (Latest):
Aldo Culquicondor . resolved

Hi Alex,
As the one who suggested to explore delaying RFH in this scenario, could you give a first pass to content/browser?

Open in Gerrit

Related details

Attention is currently required from:
  • Alex Moshchuk
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I089e6c27f920ae403562f97f5785db934ae1f061
Gerrit-Change-Number: 6777031
Gerrit-PatchSet: 14
Gerrit-Owner: Aldo Culquicondor <aco...@chromium.org>
Gerrit-Reviewer: Aldo Culquicondor <aco...@chromium.org>
Gerrit-Reviewer: Alex Moshchuk <ale...@chromium.org>
Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
Gerrit-CC: Iman Saboori <isab...@google.com>
Gerrit-Attention: Alex Moshchuk <ale...@chromium.org>
Gerrit-Comment-Date: Fri, 12 Sep 2025 17:47:43 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Alex Moshchuk (Gerrit)

unread,
Sep 15, 2025, 6:53:08 PM (3 days ago) Sep 15
to Aldo Culquicondor, Iman Saboori, AyeAye, Chromium Metrics Reviews, chromium...@chromium.org, Chromium LUCI CQ, performance-m...@chromium.org, android-web...@chromium.org, bmcquad...@chromium.org, speed-metrics...@chromium.org, rouslan+au...@chromium.org, pdf-r...@chromium.org, csharris...@chromium.org, chromium-a...@chromium.org, browser-comp...@chromium.org, speed-metr...@chromium.org, extension...@chromium.org, loading-rev...@chromium.org, alexmo...@chromium.org, asvitkine...@chromium.org, creis...@chromium.org, navigation...@chromium.org
Attention needed from Aldo Culquicondor

Alex Moshchuk added 8 comments

Patchset-level comments
Alex Moshchuk . resolved

Thanks! I didn't look at any test changes yet, but this seems like a good start. Seems like there are still some failures on the Mac bot? Some initial comments below, and I'll also try to discuss this approach tomorrow with the CSA team.

File content/browser/renderer_host/render_frame_host_impl.cc
Line 6619, Patchset 14 (Latest): // RenderFrameDeleted();
Alex Moshchuk . unresolved

Remove debug comment?

Line 12098, Patchset 14 (Latest): features::kRfhCheckOneChildAtATime.Get()) {
Alex Moshchuk . unresolved

Should probably check the feature flag as well?

Line 12101, Patchset 14 (Latest): base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
Alex Moshchuk . unresolved

I'm not sure about this part of the optimization. Is there evidence that it is needed? Further breaking up the destruction into a bunch of tasks strikes me as increasing complexity and IIUC potentially redoing a bunch of the traversal work (e.g., if we traversed a complex hierarchy of 50 frames and only deleted one frame, we'll post this task and then traverse the whole hierarchy again to see if there's any other frames to delete, rather than only doing the traversal once.)

Line 12134, Patchset 14 (Latest): // the dead branches now. This is a performance optimization.
Alex Moshchuk . unresolved

Maybe move this comment out in front of the "if" and explain how the feature gates whether the RFHs that are ready to be deleted are destroyed synchronously or asynchronously, which might allow the current task (where a navigation might be committing) to finish sooner.

Line 12137, Patchset 14 (Latest): }
Alex Moshchuk . unresolved

I wonder if a third option is possible here, which is to do nothing. In theory, this shouldn't affect correctness, as all frames with unload handlers will still be deleted once they receive their unload ACKs and trigger other branches to be cleaned up, but I can't remember if any subframes without unload handlers will still be cleaned up if we do nothing here. Curious if that's something you tried?

File content/common/features.cc
Line 162, Patchset 14 (Latest):// happen on PendingDeletionCheckCompletedOnSubTree.
Alex Moshchuk . unresolved

nit: lowercase t in "Subtree" to match the function's actual name

Line 166, Patchset 14 (Latest):BASE_FEATURE_PARAM(bool,
Alex Moshchuk . unresolved

Can you describe the purpose of this param as well?

Open in Gerrit

Related details

Attention is currently required from:
  • Aldo Culquicondor
Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement is not satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I089e6c27f920ae403562f97f5785db934ae1f061
    Gerrit-Change-Number: 6777031
    Gerrit-PatchSet: 14
    Gerrit-Owner: Aldo Culquicondor <aco...@chromium.org>
    Gerrit-Reviewer: Aldo Culquicondor <aco...@chromium.org>
    Gerrit-Reviewer: Alex Moshchuk <ale...@chromium.org>
    Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
    Gerrit-CC: Iman Saboori <isab...@google.com>
    Gerrit-Attention: Aldo Culquicondor <aco...@chromium.org>
    Gerrit-Comment-Date: Mon, 15 Sep 2025 22:52:58 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Aldo Culquicondor (Gerrit)

    unread,
    Sep 17, 2025, 11:39:34 AM (yesterday) Sep 17
    to Alex Moshchuk, Iman Saboori, AyeAye, Chromium Metrics Reviews, chromium...@chromium.org, Chromium LUCI CQ, devtools...@chromium.org, performance-m...@chromium.org, android-web...@chromium.org, bmcquad...@chromium.org, speed-metrics...@chromium.org, rouslan+au...@chromium.org, pdf-r...@chromium.org, csharris...@chromium.org, chromium-a...@chromium.org, browser-comp...@chromium.org, speed-metr...@chromium.org, extension...@chromium.org, loading-rev...@chromium.org, alexmo...@chromium.org, asvitkine...@chromium.org, creis...@chromium.org, navigation...@chromium.org
    Attention needed from Alex Moshchuk

    Aldo Culquicondor added 8 comments

    Patchset-level comments
    Alex Moshchuk . resolved

    Thanks! I didn't look at any test changes yet, but this seems like a good start. Seems like there are still some failures on the Mac bot? Some initial comments below, and I'll also try to discuss this approach tomorrow with the CSA team.

    Aldo Culquicondor

    That last test was much harder to fix, but it revealed an assumption that didn't hold anymore when the feature is enabled. See ~FrameTreeNode.

    File content/browser/renderer_host/render_frame_host_impl.cc
    Line 6619, Patchset 14: // RenderFrameDeleted();
    Alex Moshchuk . resolved

    Remove debug comment?

    Aldo Culquicondor

    Oops, removed.

    Line 12098, Patchset 14: features::kRfhCheckOneChildAtATime.Get()) {
    Alex Moshchuk . resolved

    Should probably check the feature flag as well?

    Aldo Culquicondor

    Done

    Line 12101, Patchset 14: base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
    Alex Moshchuk . resolved

    I'm not sure about this part of the optimization. Is there evidence that it is needed? Further breaking up the destruction into a bunch of tasks strikes me as increasing complexity and IIUC potentially redoing a bunch of the traversal work (e.g., if we traversed a complex hierarchy of 50 frames and only deleted one frame, we'll post this task and then traverse the whole hierarchy again to see if there's any other frames to delete, rather than only doing the traversal once.)

    Aldo Culquicondor

    I figured I would let the study tell me whether this is necessary. I plan to have two arms. There is evidence from flamegraphs and traces that we might be spending hundreds of milliseconds on PendingDeletionCheckCompletedOnSubtree right now.

    Line 12134, Patchset 14: // the dead branches now. This is a performance optimization.
    Alex Moshchuk . resolved

    Maybe move this comment out in front of the "if" and explain how the feature gates whether the RFHs that are ready to be deleted are destroyed synchronously or asynchronously, which might allow the current task (where a navigation might be committing) to finish sooner.

    Aldo Culquicondor

    Moved the comment to the header file.

    Line 12137, Patchset 14: }
    Alex Moshchuk . resolved

    I wonder if a third option is possible here, which is to do nothing. In theory, this shouldn't affect correctness, as all frames with unload handlers will still be deleted once they receive their unload ACKs and trigger other branches to be cleaned up, but I can't remember if any subframes without unload handlers will still be cleaned up if we do nothing here. Curious if that's something you tried?

    Aldo Culquicondor

    Would the browser tests have all the machinery necessary to send the unload ACKs? Right now, if I comment out the post task, the tests fail because they don't satisfy rfh_deleted_observer->WaitUntilDeleted(), so it doesn't look like it will work. There's probably a bit too many assumptions now that the deletions are synchronous.

    File content/common/features.cc
    Line 162, Patchset 14:// happen on PendingDeletionCheckCompletedOnSubTree.
    Alex Moshchuk . resolved

    nit: lowercase t in "Subtree" to match the function's actual name

    Aldo Culquicondor

    Done

    Line 166, Patchset 14:BASE_FEATURE_PARAM(bool,
    Alex Moshchuk . resolved

    Can you describe the purpose of this param as well?

    Aldo Culquicondor

    Done

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Alex Moshchuk
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement is not satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I089e6c27f920ae403562f97f5785db934ae1f061
    Gerrit-Change-Number: 6777031
    Gerrit-PatchSet: 15
    Gerrit-Owner: Aldo Culquicondor <aco...@chromium.org>
    Gerrit-Reviewer: Aldo Culquicondor <aco...@chromium.org>
    Gerrit-Reviewer: Alex Moshchuk <ale...@chromium.org>
    Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
    Gerrit-CC: Iman Saboori <isab...@google.com>
    Gerrit-Attention: Alex Moshchuk <ale...@chromium.org>
    Gerrit-Comment-Date: Wed, 17 Sep 2025 15:39:28 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Alex Moshchuk <ale...@chromium.org>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Alex Moshchuk (Gerrit)

    unread,
    Sep 17, 2025, 2:11:20 PM (yesterday) Sep 17
    to Aldo Culquicondor, Iman Saboori, AyeAye, Chromium Metrics Reviews, chromium...@chromium.org, Chromium LUCI CQ, devtools...@chromium.org, performance-m...@chromium.org, android-web...@chromium.org, bmcquad...@chromium.org, speed-metrics...@chromium.org, rouslan+au...@chromium.org, pdf-r...@chromium.org, csharris...@chromium.org, chromium-a...@chromium.org, browser-comp...@chromium.org, speed-metr...@chromium.org, extension...@chromium.org, loading-rev...@chromium.org, alexmo...@chromium.org, asvitkine...@chromium.org, creis...@chromium.org, navigation...@chromium.org
    Attention needed from Aldo Culquicondor

    Alex Moshchuk added 3 comments

    Patchset-level comments
    File-level comment, Patchset 14:
    Alex Moshchuk . unresolved

    Thanks! I didn't look at any test changes yet, but this seems like a good start. Seems like there are still some failures on the Mac bot? Some initial comments below, and I'll also try to discuss this approach tomorrow with the CSA team.

    Aldo Culquicondor

    That last test was much harder to fix, but it revealed an assumption that didn't hold anymore when the feature is enabled. See ~FrameTreeNode.

    Alex Moshchuk

    Oh, this is concerning. Can you provide more details about which test was failing and where? Is it FrameNavigationEntry_RecreatedInjectedSrcdocSubframe? If so, I'm surprised it would only fail on Mac, since it's enabled on all platforms. I wonder if it was flaky to start with, and your CL just made it worse. (Also, mac_rel still seems to be failing.)

    More importantly, I don't really understand the fix in the latest PS, and don't think this is the right direction for it. Conceptually it doesn't make much sense to pass in a nav entry ID to places like RemoveChild(). But also, I'd expect the test to have the same problem if any of the subframes registered an unload handler, which would make their RFH destruction asynchronous even without this CL. Can you try that and see if the test still fails? If so, it would indicate that there's an independent problem with the FNE pruning logic added in https://chromium-review.googlesource.com/c/chromium/src/+/767627 that we should file a bug for and fix separately from this CL. Maybe the FNE pruning should still happen when we enter pending deletion state, and not when we complete the unload handlers and/or destroy the RFH/FTN later, or maybe we should always look up the nav entry ID of a subframe FTN from its `parent_` RFH's nav_entry_id() and never look at the last committed one.

    File content/browser/renderer_host/render_frame_host_impl.cc
    Line 12101, Patchset 14: base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
    Alex Moshchuk . unresolved

    I'm not sure about this part of the optimization. Is there evidence that it is needed? Further breaking up the destruction into a bunch of tasks strikes me as increasing complexity and IIUC potentially redoing a bunch of the traversal work (e.g., if we traversed a complex hierarchy of 50 frames and only deleted one frame, we'll post this task and then traverse the whole hierarchy again to see if there's any other frames to delete, rather than only doing the traversal once.)

    Aldo Culquicondor

    I figured I would let the study tell me whether this is necessary. I plan to have two arms. There is evidence from flamegraphs and traces that we might be spending hundreds of milliseconds on PendingDeletionCheckCompletedOnSubtree right now.

    Alex Moshchuk

    Hundreds of milliseconds on PendingDeletionCheckCompletedOnSubtree is pretty wild. Do you have a sample trace where this is the case? I took a look at a [trace](https://chrometto.googleplex.com/chrometto/open_trace?p=%5Bnull%2Cnull%2Cnull%2Cnull%2Cnull%2C%5B%228b96a5ebcacc8ad6db01220a323032352f30372f3138%22%2Cnull%2Cnull%2C%5B%5B%22RenderFrameHostManager%3A%3AUnloadOldFrame%22%2C30000%2C40000%5D%5D%5D%5D&trace_id=8b96a5ebcacc8ad6db01220a323032352f30372f3138) linked in your doc but didn't see any cases where PendingDeletionCheckCompletedOnSubtree was overly long or involved more than a couple of ~RFHI destructors. The per-frame PostTasks would really only make sense if we see a single PendingDeletionCheckCompletedOnSubtree comprised of a bunch of several smaller ~RFHIs, rather than one ~RFHI taking a long time (which is what I saw in that trace).

    The concern with per-frame PostTasks is that they're adding a bunch of new states with partially destroyed frame trees, making races and bugs more likely (being in pending deletion state has always been kind of fragile), in addition to accumulating the overhead of posting many tasks and re-traversing the tree for larger hierarchies. So there's a complexity cost to supporting this experiment arm, and I'd like to make sure it's justified (as compared to starting with a single PostTask to see if it gets us most of the way there).

    Alex Moshchuk . resolved

    I wonder if a third option is possible here, which is to do nothing. In theory, this shouldn't affect correctness, as all frames with unload handlers will still be deleted once they receive their unload ACKs and trigger other branches to be cleaned up, but I can't remember if any subframes without unload handlers will still be cleaned up if we do nothing here. Curious if that's something you tried?

    Aldo Culquicondor

    Would the browser tests have all the machinery necessary to send the unload ACKs? Right now, if I comment out the post task, the tests fail because they don't satisfy rfh_deleted_observer->WaitUntilDeleted(), so it doesn't look like it will work. There's probably a bit too many assumptions now that the deletions are synchronous.

    Alex Moshchuk

    Ack. Looking at the code again, it seems that if neither the navigating frame nor any of its descendants have unload handlers, and we're navigating in a subframe, there's nothing else to trigger this destruction. And this is consistent with the test fixes you've done which seems to be only touching subframe cases. So we probably do need to keep the call.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Aldo Culquicondor
    Submit Requirements:
      • requirement satisfiedCode-Coverage
      • requirement is not satisfiedCode-Owners
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: chromium/src
      Gerrit-Branch: main
      Gerrit-Change-Id: I089e6c27f920ae403562f97f5785db934ae1f061
      Gerrit-Change-Number: 6777031
      Gerrit-PatchSet: 15
      Gerrit-Owner: Aldo Culquicondor <aco...@chromium.org>
      Gerrit-Reviewer: Aldo Culquicondor <aco...@chromium.org>
      Gerrit-Reviewer: Alex Moshchuk <ale...@chromium.org>
      Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
      Gerrit-CC: Iman Saboori <isab...@google.com>
      Gerrit-Attention: Aldo Culquicondor <aco...@chromium.org>
      Gerrit-Comment-Date: Wed, 17 Sep 2025 18:11:11 +0000
      Gerrit-HasComments: Yes
      Gerrit-Has-Labels: No
      Comment-In-Reply-To: Alex Moshchuk <ale...@chromium.org>
      Comment-In-Reply-To: Aldo Culquicondor <aco...@chromium.org>
      satisfied_requirement
      unsatisfied_requirement
      open
      diffy

      Aldo Culquicondor (Gerrit)

      unread,
      Sep 17, 2025, 4:50:26 PM (yesterday) Sep 17
      to Alex Moshchuk, Iman Saboori, AyeAye, Chromium Metrics Reviews, chromium...@chromium.org, Chromium LUCI CQ, devtools...@chromium.org, performance-m...@chromium.org, android-web...@chromium.org, bmcquad...@chromium.org, speed-metrics...@chromium.org, rouslan+au...@chromium.org, pdf-r...@chromium.org, csharris...@chromium.org, chromium-a...@chromium.org, browser-comp...@chromium.org, speed-metr...@chromium.org, extension...@chromium.org, loading-rev...@chromium.org, alexmo...@chromium.org, asvitkine...@chromium.org, creis...@chromium.org, navigation...@chromium.org
      Attention needed from Alex Moshchuk

      Aldo Culquicondor added 2 comments

      Patchset-level comments
      Alex Moshchuk . unresolved

      Thanks! I didn't look at any test changes yet, but this seems like a good start. Seems like there are still some failures on the Mac bot? Some initial comments below, and I'll also try to discuss this approach tomorrow with the CSA team.

      Aldo Culquicondor

      That last test was much harder to fix, but it revealed an assumption that didn't hold anymore when the feature is enabled. See ~FrameTreeNode.

      Alex Moshchuk

      Oh, this is concerning. Can you provide more details about which test was failing and where? Is it FrameNavigationEntry_RecreatedInjectedSrcdocSubframe? If so, I'm surprised it would only fail on Mac, since it's enabled on all platforms. I wonder if it was flaky to start with, and your CL just made it worse. (Also, mac_rel still seems to be failing.)

      More importantly, I don't really understand the fix in the latest PS, and don't think this is the right direction for it. Conceptually it doesn't make much sense to pass in a nav entry ID to places like RemoveChild(). But also, I'd expect the test to have the same problem if any of the subframes registered an unload handler, which would make their RFH destruction asynchronous even without this CL. Can you try that and see if the test still fails? If so, it would indicate that there's an independent problem with the FNE pruning logic added in https://chromium-review.googlesource.com/c/chromium/src/+/767627 that we should file a bug for and fix separately from this CL. Maybe the FNE pruning should still happen when we enter pending deletion state, and not when we complete the unload handlers and/or destroy the RFH/FTN later, or maybe we should always look up the nav entry ID of a subframe FTN from its `parent_` RFH's nav_entry_id() and never look at the last committed one.

      Aldo Culquicondor

      The test wasn't initially flaky, but this CL made it flaky. It was failing on Linux too, but somehow the rate of failure was lower so that it passed the bots.

      But also, I'd expect the test to have the same problem if any of the subframes registered an unload handler, which would make their RFH destruction asynchronous even without this CL. Can you try that and see if the test still fails?

      No, they are not failing, I have run them hundreds of times with my feature disabled and they never failed. Doesn't that mean that there isn't an unload handler for those tests? Any other tests I could check?

      Maybe the FNE pruning should still happen when we enter pending deletion state, and not when we complete the unload handlers and/or destroy the RFH/FTN later, or maybe we should always look up the nav entry ID of a subframe FTN from its parent_ RFH's nav_entry_id() and never look at the last committed one.

      I think we need to do the FNE prunning when entering the deletion state. I tried using the parent's nav_entry_id, but it had already changed to the last committed entry too (hence why I added that hacky parameter).

      File content/browser/renderer_host/render_frame_host_impl.cc
      Line 12101, Patchset 14: base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
      Alex Moshchuk . unresolved

      I'm not sure about this part of the optimization. Is there evidence that it is needed? Further breaking up the destruction into a bunch of tasks strikes me as increasing complexity and IIUC potentially redoing a bunch of the traversal work (e.g., if we traversed a complex hierarchy of 50 frames and only deleted one frame, we'll post this task and then traverse the whole hierarchy again to see if there's any other frames to delete, rather than only doing the traversal once.)

      Aldo Culquicondor

      I figured I would let the study tell me whether this is necessary. I plan to have two arms. There is evidence from flamegraphs and traces that we might be spending hundreds of milliseconds on PendingDeletionCheckCompletedOnSubtree right now.

      Alex Moshchuk

      Hundreds of milliseconds on PendingDeletionCheckCompletedOnSubtree is pretty wild. Do you have a sample trace where this is the case? I took a look at a [trace](https://chrometto.googleplex.com/chrometto/open_trace?p=%5Bnull%2Cnull%2Cnull%2Cnull%2Cnull%2C%5B%228b96a5ebcacc8ad6db01220a323032352f30372f3138%22%2Cnull%2Cnull%2C%5B%5B%22RenderFrameHostManager%3A%3AUnloadOldFrame%22%2C30000%2C40000%5D%5D%5D%5D&trace_id=8b96a5ebcacc8ad6db01220a323032352f30372f3138) linked in your doc but didn't see any cases where PendingDeletionCheckCompletedOnSubtree was overly long or involved more than a couple of ~RFHI destructors. The per-frame PostTasks would really only make sense if we see a single PendingDeletionCheckCompletedOnSubtree comprised of a bunch of several smaller ~RFHIs, rather than one ~RFHI taking a long time (which is what I saw in that trace).

      The concern with per-frame PostTasks is that they're adding a bunch of new states with partially destroyed frame trees, making races and bugs more likely (being in pending deletion state has always been kind of fragile), in addition to accumulating the overhead of posting many tasks and re-traversing the tree for larger hierarchies. So there's a complexity cost to supporting this experiment arm, and I'd like to make sure it's justified (as compared to starting with a single PostTask to see if it gets us most of the way there).

      Aldo Culquicondor

      Yeah, in most cases there is just one ~RFH that takes a long time, in some cases followed by shorter ones. Again, I was trying to get the study to tell me whether it was overkill. But I see your point about more races, so yeah, let's start simpler. I'll remove it in my next update.

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Alex Moshchuk
      Submit Requirements:
      • requirement satisfiedCode-Coverage
      • requirement is not satisfiedCode-Owners
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: chromium/src
      Gerrit-Branch: main
      Gerrit-Change-Id: I089e6c27f920ae403562f97f5785db934ae1f061
      Gerrit-Change-Number: 6777031
      Gerrit-PatchSet: 15
      Gerrit-Owner: Aldo Culquicondor <aco...@chromium.org>
      Gerrit-Reviewer: Aldo Culquicondor <aco...@chromium.org>
      Gerrit-Reviewer: Alex Moshchuk <ale...@chromium.org>
      Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
      Gerrit-CC: Iman Saboori <isab...@google.com>
      Gerrit-Attention: Alex Moshchuk <ale...@chromium.org>
      Gerrit-Comment-Date: Wed, 17 Sep 2025 20:50:22 +0000
      satisfied_requirement
      unsatisfied_requirement
      open
      diffy

      Alex Moshchuk (Gerrit)

      unread,
      Sep 17, 2025, 5:49:00 PM (yesterday) Sep 17
      to Aldo Culquicondor, Iman Saboori, AyeAye, Chromium Metrics Reviews, chromium...@chromium.org, Chromium LUCI CQ, devtools...@chromium.org, performance-m...@chromium.org, android-web...@chromium.org, bmcquad...@chromium.org, speed-metrics...@chromium.org, rouslan+au...@chromium.org, pdf-r...@chromium.org, csharris...@chromium.org, chromium-a...@chromium.org, browser-comp...@chromium.org, speed-metr...@chromium.org, extension...@chromium.org, loading-rev...@chromium.org, alexmo...@chromium.org, asvitkine...@chromium.org, creis...@chromium.org, navigation...@chromium.org
      Attention needed from Aldo Culquicondor

      Alex Moshchuk added 1 comment

      Patchset-level comments
      Alex Moshchuk . unresolved

      Thanks! I didn't look at any test changes yet, but this seems like a good start. Seems like there are still some failures on the Mac bot? Some initial comments below, and I'll also try to discuss this approach tomorrow with the CSA team.

      Aldo Culquicondor

      That last test was much harder to fix, but it revealed an assumption that didn't hold anymore when the feature is enabled. See ~FrameTreeNode.

      Alex Moshchuk

      Oh, this is concerning. Can you provide more details about which test was failing and where? Is it FrameNavigationEntry_RecreatedInjectedSrcdocSubframe? If so, I'm surprised it would only fail on Mac, since it's enabled on all platforms. I wonder if it was flaky to start with, and your CL just made it worse. (Also, mac_rel still seems to be failing.)

      More importantly, I don't really understand the fix in the latest PS, and don't think this is the right direction for it. Conceptually it doesn't make much sense to pass in a nav entry ID to places like RemoveChild(). But also, I'd expect the test to have the same problem if any of the subframes registered an unload handler, which would make their RFH destruction asynchronous even without this CL. Can you try that and see if the test still fails? If so, it would indicate that there's an independent problem with the FNE pruning logic added in https://chromium-review.googlesource.com/c/chromium/src/+/767627 that we should file a bug for and fix separately from this CL. Maybe the FNE pruning should still happen when we enter pending deletion state, and not when we complete the unload handlers and/or destroy the RFH/FTN later, or maybe we should always look up the nav entry ID of a subframe FTN from its `parent_` RFH's nav_entry_id() and never look at the last committed one.

      Aldo Culquicondor

      The test wasn't initially flaky, but this CL made it flaky. It was failing on Linux too, but somehow the rate of failure was lower so that it passed the bots.

      But also, I'd expect the test to have the same problem if any of the subframes registered an unload handler, which would make their RFH destruction asynchronous even without this CL. Can you try that and see if the test still fails?

      No, they are not failing, I have run them hundreds of times with my feature disabled and they never failed. Doesn't that mean that there isn't an unload handler for those tests? Any other tests I could check?

      Maybe the FNE pruning should still happen when we enter pending deletion state, and not when we complete the unload handlers and/or destroy the RFH/FTN later, or maybe we should always look up the nav entry ID of a subframe FTN from its parent_ RFH's nav_entry_id() and never look at the last committed one.

      I think we need to do the FNE prunning when entering the deletion state. I tried using the parent's nav_entry_id, but it had already changed to the last committed entry too (hence why I added that hacky parameter).

      Alex Moshchuk

      The test wasn't initially flaky, but this CL made it flaky. It was failing on Linux too, but somehow the rate of failure was lower so that it passed the bots.

      But also, I'd expect the test to have the same problem if any of the subframes registered an unload handler, which would make their RFH destruction asynchronous even without this CL. Can you try that and see if the test still fails?

      No, they are not failing, I have run them hundreds of times with my feature disabled and they never failed. Doesn't that mean that there isn't an unload handler for those tests? Any other tests I could check?

      Right, I would only expect them to fail without your CL if you modify the existing test so that the subframes have an unload handler. Was the failure happening [here](https://source.chromium.org/chromium/chromium/src/+/main:content/browser/renderer_host/navigation_controller_impl_browsertest.cc;l=8007;drc=f57cc21393cfc33b95bbf88117df6f8fba371a95)? If so, I'd run something like this:
      ```
      ASSERT_TRUE(ExecJs(root->child_at(0), "window.onpagehide = ()=>{}"));
      ASSERT_TRUE(ExecJs(root->child_at(0)->child_at(0), "window.onpagehide = ()=>{}"));
      ```
      before step 2 and see if that causes the test to fail (without your CL). You might also need to modify navigation_controller/inject_iframe_srcdoc_with_nested_frame.html so that the grandchild iframe points to "/cross-site/foo.com/navigation_controller/form.html" instead of just "form.html", so that it's an OOPIF (required to involve async unload handling).


      > Maybe the FNE pruning should still happen when we enter pending deletion state, and not when we complete the unload handlers and/or destroy the RFH/FTN later, or maybe we should always look up the nav entry ID of a subframe FTN from its parent_ RFH's nav_entry_id() and never look at the last committed one.

      I think we need to do the FNE prunning when entering the deletion state. I tried using the parent's nav_entry_id, but it had already changed to the last committed entry too (hence why I added that hacky parameter).

      Oh, interesting - the nav_entry_id change should really only be possible if the main frame navigation stayed in the same RFH - which shouldn't really be the case anymore thanks to RenderDocument, but these tests do cover running both with and without RenderDocument. And I see that the only test variant that failed was explicitly without RenderDocument (RDCrashedFrame_, and not RDAllFrames_). Maybe that means that this problem doesn't exist with RenderDocument (which should launch very soon). But also, I'm confused because in that state the new logic shouldn't be invoked at commit time, because we aren't swapping the main RFH and hence not even entering pending deletion.

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Aldo Culquicondor
      Submit Requirements:
      • requirement satisfiedCode-Coverage
      • requirement is not satisfiedCode-Owners
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: chromium/src
      Gerrit-Branch: main
      Gerrit-Change-Id: I089e6c27f920ae403562f97f5785db934ae1f061
      Gerrit-Change-Number: 6777031
      Gerrit-PatchSet: 15
      Gerrit-Owner: Aldo Culquicondor <aco...@chromium.org>
      Gerrit-Reviewer: Aldo Culquicondor <aco...@chromium.org>
      Gerrit-Reviewer: Alex Moshchuk <ale...@chromium.org>
      Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
      Gerrit-CC: Iman Saboori <isab...@google.com>
      Gerrit-Attention: Aldo Culquicondor <aco...@chromium.org>
      Gerrit-Comment-Date: Wed, 17 Sep 2025 21:48:50 +0000
      satisfied_requirement
      unsatisfied_requirement
      open
      diffy

      Aldo Culquicondor (Gerrit)

      unread,
      3:26 PM (4 hours ago) 3:26 PM
      to Alex Moshchuk, Iman Saboori, AyeAye, Chromium Metrics Reviews, chromium...@chromium.org, Chromium LUCI CQ, devtools...@chromium.org, performance-m...@chromium.org, android-web...@chromium.org, bmcquad...@chromium.org, speed-metrics...@chromium.org, rouslan+au...@chromium.org, pdf-r...@chromium.org, csharris...@chromium.org, chromium-a...@chromium.org, browser-comp...@chromium.org, speed-metr...@chromium.org, extension...@chromium.org, loading-rev...@chromium.org, alexmo...@chromium.org, asvitkine...@chromium.org, creis...@chromium.org, navigation...@chromium.org
      Attention needed from Alex Moshchuk

      Aldo Culquicondor added 1 comment

      Patchset-level comments
      Aldo Culquicondor

      But also, I'm confused because in that state the new logic shouldn't be invoked at commit time, because we aren't swapping the main RFH and hence not even entering pending deletion.

      Not sure what you mean by new logic but, in RDCrashedFrame, there is a call for Detach for the iframe created by a script when navigating away.

      Open in Gerrit

      Related details

      Attention is currently required from:
      • Alex Moshchuk
      Submit Requirements:
      • requirement satisfiedCode-Coverage
      • requirement is not satisfiedCode-Owners
      • requirement is not satisfiedCode-Review
      • requirement is not satisfiedNo-Unresolved-Comments
      Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
      Gerrit-MessageType: comment
      Gerrit-Project: chromium/src
      Gerrit-Branch: main
      Gerrit-Change-Id: I089e6c27f920ae403562f97f5785db934ae1f061
      Gerrit-Change-Number: 6777031
      Gerrit-PatchSet: 15
      Gerrit-Owner: Aldo Culquicondor <aco...@chromium.org>
      Gerrit-Reviewer: Aldo Culquicondor <aco...@chromium.org>
      Gerrit-Reviewer: Alex Moshchuk <ale...@chromium.org>
      Gerrit-CC: Chromium Metrics Reviews <chromium-met...@google.com>
      Gerrit-CC: Iman Saboori <isab...@google.com>
      Gerrit-Attention: Alex Moshchuk <ale...@chromium.org>
      Gerrit-Comment-Date: Thu, 18 Sep 2025 19:26:37 +0000
      satisfied_requirement
      unsatisfied_requirement
      open
      diffy
      Reply all
      Reply to author
      Forward
      0 new messages