WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
208382
Garbage collection prevents FontFace.loaded promise from getting resolved
https://bugs.webkit.org/show_bug.cgi?id=208382
Summary
Garbage collection prevents FontFace.loaded promise from getting resolved
Alexey Proskuryakov
Reported
2020-02-28 10:39:20 PST
Created
attachment 391991
[details]
layout test We have some tests that use FontFace.loaded, and they fail (time out) when frequent garbage collection is forced with JSC_slowPathAllocsBetweenGCs=10. They also fail flakily on other bots. Steps to reproduce: Put attached test into LayoutTests, and run as: run-webkit-tests --no-retry --dump-render-tree --additional-env-var=JSC_slowPathAllocsBetweenGCs=10 font-promises-gc.html It should not time out, and should say "SUCCESS".
Attachments
layout test
(1.04 KB, text/html)
2020-02-28 10:39 PST
,
Alexey Proskuryakov
no flags
Details
Patch
(10.81 KB, patch)
2020-02-28 12:21 PST
,
Chris Dumez
no flags
Details
Formatted Diff
Diff
Patch
(10.67 KB, patch)
2020-02-28 13:31 PST
,
Chris Dumez
no flags
Details
Formatted Diff
Diff
Patch
(10.66 KB, patch)
2020-02-28 13:55 PST
,
Chris Dumez
no flags
Details
Formatted Diff
Diff
Patch
(11.29 KB, patch)
2020-02-28 16:26 PST
,
Chris Dumez
no flags
Details
Formatted Diff
Diff
Show Obsolete
(3)
View All
Add attachment
proposed patch, testcase, etc.
Alexey Proskuryakov
Comment 1
2020-02-28 10:48:11 PST
Presumably the promise needs to keep FontFace wrapper alive. I am not familiar with modern GC code enough to fix this in a reasonable amount of time.
Ryosuke Niwa
Comment 2
2020-02-28 11:17:35 PST
FontFace probably needs to be an active DOM object and make it have a pending activity while there is font loading happening
Ryosuke Niwa
Comment 3
2020-02-28 11:18:49 PST
We also need to make sure the promise object itself is kept alive in each DOM wrapper world too
Alexey Proskuryakov
Comment 4
2020-02-28 11:26:14 PST
> FontFace probably needs to be an active DOM object and make it have a pending activity while there is font loading happening
I'm not sure if that would be sufficient. Doesn't promise resolving need to work even when loading isn't happening (either not started, or already finished)? As an aside, I found that custom properties on FontFace wrappers don't survive GC either.
Ryosuke Niwa
Comment 5
2020-02-28 11:56:50 PST
(In reply to Alexey Proskuryakov from
comment #4
)
> > FontFace probably needs to be an active DOM object and make it have a pending activity while there is font loading happening > > I'm not sure if that would be sufficient. Doesn't promise resolving need to > work even when loading isn't happening (either not started, or already > finished)?
Sure.
> As an aside, I found that custom properties on FontFace wrappers don't > survive GC either.
Not surprised. Almost all DOM objects have this bug because people don't know how GC works. FontFace isn't an ActiveDOMObject nor is it reachable from anything so yeah, it'd get GC'ed immediately.
Chris Dumez
Comment 6
2020-02-28 12:21:52 PST
Created
attachment 392005
[details]
Patch
Keith Miller
Comment 7
2020-02-28 12:41:56 PST
(In reply to Ryosuke Niwa from
comment #5
)
> (In reply to Alexey Proskuryakov from
comment #4
) > > As an aside, I found that custom properties on FontFace wrappers don't > > survive GC either. > > Not surprised. Almost all DOM objects have this bug because people don't > know how GC works. FontFace isn't an ActiveDOMObject nor is it reachable > from anything so yeah, it'd get GC'ed immediately.
I thought wrappers were handled by the wrapper map, which is careful to not GC wrappers when it would be observable?
Alexey Proskuryakov
Comment 8
2020-02-28 13:02:59 PST
Comment on
attachment 392005
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=392005&action=review
> LayoutTests/fast/text/font-promises-gc.html:46 > +setInterval(function() { > + document.fonts.forEach(function(f) { > + console.log("Font status: " + f.status); > + }); > +}, 5000);
Delete this? Five seconds is hard to hit, but not impossible on a very busy bot.
Chris Dumez
Comment 9
2020-02-28 13:31:21 PST
Created
attachment 392014
[details]
Patch
Chris Dumez
Comment 10
2020-02-28 13:31:38 PST
(In reply to Alexey Proskuryakov from
comment #8
)
> Comment on
attachment 392005
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=392005&action=review
> > > LayoutTests/fast/text/font-promises-gc.html:46 > > +setInterval(function() { > > + document.fonts.forEach(function(f) { > > + console.log("Font status: " + f.status); > > + }); > > +}, 5000); > > Delete this? Five seconds is hard to hit, but not impossible on a very busy > bot.
My bad :)
Ryosuke Niwa
Comment 11
2020-02-28 13:41:10 PST
Comment on
attachment 392014
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=392014&action=review
> Source/WebCore/css/FontFace.cpp:490 > + return !isContextStopped() && m_isScriptPotentiallyInterestedInLoad && !m_loadedPromise->isFulfilled();
Should we clear m_isScriptPotentiallyInterestedInLoad when we're fulfilled the promise?
Chris Dumez
Comment 12
2020-02-28 13:43:23 PST
Comment on
attachment 392014
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=392014&action=review
>> Source/WebCore/css/FontFace.cpp:490 >> + return !isContextStopped() && m_isScriptPotentiallyInterestedInLoad && !m_loadedPromise->isFulfilled(); > > Should we clear m_isScriptPotentiallyInterestedInLoad when we're fulfilled the promise?
It would not be observable since we call m_loadedPromise->isFulfilled() here. Are you concerned about someone using this boolean for something else later?
Ryosuke Niwa
Comment 13
2020-02-28 13:52:20 PST
(In reply to Chris Dumez from
comment #12
)
> Comment on
attachment 392014
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=392014&action=review
> > >> Source/WebCore/css/FontFace.cpp:490 > >> + return !isContextStopped() && m_isScriptPotentiallyInterestedInLoad && !m_loadedPromise->isFulfilled(); > > > > Should we clear m_isScriptPotentiallyInterestedInLoad when we're fulfilled the promise? > > It would not be observable since we call m_loadedPromise->isFulfilled() > here. Are you concerned about someone using this boolean for something else > later?
Yeah. Also, I also thought it's a misleading. Maybe we can rename the variable to something like m_isPromisePotentiallyScriptObservable?
Ryosuke Niwa
Comment 14
2020-02-28 13:52:56 PST
I think the confusing part of m_isScriptPotentiallyInterestedInLoad is that it sort of implies the load hasn't happened yet.
Chris Dumez
Comment 15
2020-02-28 13:55:33 PST
Created
attachment 392015
[details]
Patch
Chris Dumez
Comment 16
2020-02-28 16:26:25 PST
Created
attachment 392031
[details]
Patch
WebKit Commit Bot
Comment 17
2020-02-28 17:48:32 PST
Comment on
attachment 392031
[details]
Patch Clearing flags on attachment: 392031 Committed
r257676
: <
https://trac.webkit.org/changeset/257676
>
WebKit Commit Bot
Comment 18
2020-02-28 17:48:34 PST
All reviewed patches have been landed. Closing bug.
Radar WebKit Bug Importer
Comment 19
2020-02-28 17:49:16 PST
<
rdar://problem/59910670
>
Alexey Proskuryakov
Comment 20
2020-02-29 12:40:45 PST
This also fixed fast/text/font-weight-fallback.html when running with JSC_slowPathAllocsBetweenGCs. It's using the same pattern, didn't notice it for he workaround in
bug 208383
.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug