Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 4f0e36f521e9f70b230734dc726cb0960af22b4c
https://github.com/WebKit/WebKit/commit/4f0e36f521e9f70b230734dc726cb0960af22b4c
Author: Basuke Suzuki <[email protected]>
Date: 2026-05-12 (Tue, 12 May 2026)
Changed paths:
M Source/WebKit/Shared/WebBackForwardListItem.cpp
M Source/WebKit/Shared/WebBackForwardListItem.h
M Source/WebKit/UIProcess/WebBackForwardCache.cpp
M Source/WebKit/UIProcess/WebBackForwardCacheEntry.cpp
M Source/WebKit/UIProcess/WebBackForwardCacheEntry.h
M Tools/TestWebKitAPI/Tests/WebKit/WKWebView/ProcessSwapOnNavigation.mm
Log Message:
-----------
[BFCache] Share SuspendedPageProxy across same-process BFCache entries
https://bugs.webkit.org/show_bug.cgi?id=314237
rdar://176395569
Reviewed by Sihui Liu.
This bug affects both Site-Isolation and non-Site-Isolation environments. In
either case it manifests as a full reload of an otherwise-cacheable page on
certain back-navigation patterns, and additionally destroys every other BFCache
entry living in the same WebProcess.
Repro: navigate a/1 -> a/2 (same-site, a/1 enters in-process BFCache during the
commit) -> b/1 (cross-site swap; a SuspendedPageProxy is created and attached
only to a/2's BackForwardListItem) -> goBack directly to a/1.
Pre-fix, a/1's BFCache entry has no SuspendedPageProxy, so Path A of
WebProcessPool::processForNavigationInternal misses. The lastProcessIdentifier
fallback returns the suspended a process without SPP context, and
WebPageProxy::decidePolicyForNavigationActionAsyncShared then calls
removeEntriesForPageAndProcess. That drops the only Ref to the
SuspendedPageProxy, tears down the existing WebPage in the a process, and
forces a full reload of a/1 -- losing a/2's BFCache entry as collateral.
Fix by sharing the SuspendedPageProxy with all same-process BFCache entries
when it is added, and clearing it from all same-process entries when it is
taken for unsuspension. The new test exercises the four-step navigation above
and verifies both back-restoration of a/1 and forward-restoration of a/2 arrive
via pageshow.persisted=true.
Also relax the ~WebBackForwardCacheEntry guard so ClearCachedPage is still
sent on capacity eviction when a SuspendedPageProxy is held. With sharing the
SPP is retained by other entries and is not destroyed by this drop, so the
previous `!m_suspendedPage` skip would leak the evicted frame's cached data
in the suspended WebProcess. m_backForwardFrameItemID is still cleared by
takeSuspendedPage(), so the restore path remains a no-op.
Test: Tools/TestWebKitAPI/Tests/WebKit/WKWebView/ProcessSwapOnNavigation.mm
* Source/WebKit/Shared/WebBackForwardListItem.cpp:
(WebKit::WebBackForwardListItem::backForwardCacheEntryForProcess const):
* Source/WebKit/Shared/WebBackForwardListItem.h:
* Source/WebKit/UIProcess/WebBackForwardCache.cpp:
(WebKit::WebBackForwardCache::addEntry):
(WebKit::WebBackForwardCache::takeSuspendedPage):
* Source/WebKit/UIProcess/WebBackForwardCacheEntry.cpp:
(WebKit::WebBackForwardCacheEntry::~WebBackForwardCacheEntry):
(WebKit::WebBackForwardCacheEntry::setSuspendedPage):
(WebKit::WebBackForwardCacheEntry::clearSuspendedPage):
* Source/WebKit/UIProcess/WebBackForwardCacheEntry.h:
* Tools/TestWebKitAPI/Tests/WebKit/WKWebView/ProcessSwapOnNavigation.mm:
((ProcessSwap, BackForwardCacheRestoreSkippedSameProcessItem)):
Canonical link: https://commits.webkit.org/313096@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications