Bug 196437 - Retain cycle between CSSFontSelector -> CSSFontFaceSet -> CSSFontFace -> CSSFontSelector
Summary: Retain cycle between CSSFontSelector -> CSSFontFaceSet -> CSSFontFace -> CSSF...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Myles C. Maxfield
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2019-03-31 23:05 PDT by Myles C. Maxfield
Modified: 2020-02-28 14:04 PST (History)
14 users (show)

See Also:


Attachments
WIP (15.00 KB, patch)
2019-03-31 23:05 PDT, Myles C. Maxfield
no flags Details | Formatted Diff | Diff
Dependency graph (508.30 KB, image/jpeg)
2019-03-31 23:08 PDT, Myles C. Maxfield
no flags Details
Patch (2.84 KB, patch)
2020-02-27 15:32 PST, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (2.93 KB, patch)
2020-02-27 16:21 PST, Chris Dumez
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Myles C. Maxfield 2019-03-31 23:05:26 PDT
Retain cycle between CSSFontSelector -> CSSFontFaceSet -> CSSFontFace -> CSSFontSelector
Comment 1 Myles C. Maxfield 2019-03-31 23:05:59 PDT
Created attachment 366386 [details]
WIP
Comment 2 Myles C. Maxfield 2019-03-31 23:08:48 PDT
Created attachment 366387 [details]
Dependency graph
Comment 3 Myles C. Maxfield 2019-03-31 23:13:25 PDT
CSSFontFace::m_fontSelector is used for 4 purposes:

1) When a font loads, it calls CSSFontSelector::fontLoaded(), so the font selector can dispatchInvalidationCallbacks().
2) AllowsUserInstalleFonts, FontLoadTimingOverride, and ShouldIgnoreFontLoadCompletions are queried from the document's settings
3) Starting the font load requires the document->cachedResourceLoader()
4) The FontFace object's getters need to updateStyleIfNeeded() to pull down any CSSOM modifications that may have happened in the past.
Comment 4 Myles C. Maxfield 2019-03-31 23:22:10 PDT
The reason we can't use a simple Client callback for 3) is that load() should still work even if the FontFace isn't attached to any FontFaceSet. It needs to issue a network request even if there is no Document involved.

XHR does this via a ThreadableLoader. We should figure out whether we can use ThreadableLoader too.
Comment 5 Myles C. Maxfield 2019-03-31 23:48:54 PDT
Regressions: Unexpected text-only failures (2)
  fast/css/font-face-multiple-remote-sources.html [ Failure ]
  svg/batik/text/xmlSpace.svg [ Failure ]

Regressions: Unexpected crashes (1)
  fast/text/font-face-set-cssom.html [ Crash ]
Comment 6 Myles C. Maxfield 2019-03-31 23:50:10 PDT
fast/text/font-face-set-cssom.html:


0   com.apple.JavaScriptCore      	0x00000001688d7fd0 WTFCrash + 16 (Assertions.cpp:305)
1   com.apple.WebCore             	0x000000015000c0cb WTFCrashWithInfo(int, char const*, char const*, int) + 27
2   com.apple.WebCore             	0x00000001522d7219 WTF::HashTableConstIterator<WebCore::CSSFontFace::Client*, WebCore::CSSFontFace::Client*, WTF::IdentityExtractor, WTF::PtrHash<WebCore::CSSFontFace::Client*>, WTF::HashTraits<WebCore::CSSFontFace::Client*>, WTF::HashTraits<WebCore::CSSFontFace::Client*> >::checkValidity() const + 105 (HashTable.h:213)
3   com.apple.WebCore             	0x00000001522d7389 WTF::HashTableConstIterator<WebCore::CSSFontFace::Client*, WebCore::CSSFontFace::Client*, WTF::IdentityExtractor, WTF::PtrHash<WebCore::CSSFontFace::Client*>, WTF::HashTraits<WebCore::CSSFontFace::Client*>, WTF::HashTraits<WebCore::CSSFontFace::Client*> >::operator++() + 25 (HashTable.h:181)
4   com.apple.WebCore             	0x00000001522d6733 WTF::HashTableConstIteratorAdapter<WTF::HashTable<WebCore::CSSFontFace::Client*, WebCore::CSSFontFace::Client*, WTF::IdentityExtractor, WTF::PtrHash<WebCore::CSSFontFace::Client*>, WTF::HashTraits<WebCore::CSSFontFace::Client*>, WTF::HashTraits<WebCore::CSSFontFace::Client*> >, WebCore::CSSFontFace::Client*>::operator++() + 35 (HashTable.h:1506)
5   com.apple.WebCore             	0x00000001522c99de void WebCore::iterateClients<WebCore::CSSFontFace::updateStyleIfNeeded()::$_29>(WTF::HashSet<WebCore::CSSFontFace::Client*, WTF::PtrHash<WebCore::CSSFontFace::Client*>, WTF::HashTraits<WebCore::CSSFontFace::Client*> >&, WebCore::CSSFontFace::updateStyleIfNeeded()::$_29) + 382 (CSSFontFace.cpp:58)
6   com.apple.WebCore             	0x00000001522c9859 WebCore::CSSFontFace::updateStyleIfNeeded() + 25 (CSSFontFace.cpp:803)
7   com.apple.WebCore             	0x000000015239c866 WebCore::FontFace::family() const + 54 (FontFace.cpp:301)
Comment 7 Ryosuke Niwa 2019-04-08 13:43:19 PDT
Comment on attachment 366386 [details]
WIP

View in context: https://bugs.webkit.org/attachment.cgi?id=366386&action=review

> Source/WebCore/css/CSSFontFaceSet.h:124
> -    HashSet<CSSFontFaceSetClient*> m_clients;
> +    HashSet<Client*> m_clients;

It's not great that all these Client interfaces rely on implementations to remove themselves.
At minimum, ~Client should delete itself from CSSFontFaceSet.
But we should just try making Client inherit from CanMakeWeakPtr and then just use WeakPtr<Client> here instead.
Comment 8 Ryosuke Niwa 2019-04-08 20:00:59 PDT
Maybe <rdar://problem/46598332> ?
Comment 9 Myles C. Maxfield 2019-11-11 19:50:17 PST
<rdar://problem/46598332>
Comment 10 Chris Dumez 2020-02-27 15:32:36 PST
Created attachment 391930 [details]
Patch
Comment 11 Chris Dumez 2020-02-27 16:21:27 PST
Created attachment 391938 [details]
Patch
Comment 12 WebKit Commit Bot 2020-02-28 08:47:13 PST
Comment on attachment 391938 [details]
Patch

Clearing flags on attachment: 391938

Committed r257639: <https://trac.webkit.org/changeset/257639>
Comment 13 WebKit Commit Bot 2020-02-28 08:47:15 PST
All reviewed patches have been landed.  Closing bug.
Comment 14 Ryosuke Niwa 2020-02-28 14:04:02 PST
Thanks for the fix!