WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
215989
REGRESSION(
r262366
): MotionMark1.1 | macOS | Some devices | 1-3% overall regression
https://bugs.webkit.org/show_bug.cgi?id=215989
Summary
REGRESSION(r262366): MotionMark1.1 | macOS | Some devices | 1-3% overall regr...
Dean Jackson
Reported
2020-08-30 12:37:35 PDT
REGRESSION(
r262366
): MotionMark1.1 | macOS | Some devices | 1-3% overall regression
Attachments
Patch
(17.46 KB, patch)
2020-08-30 12:48 PDT
,
Dean Jackson
darin
: review+
Details
Formatted Diff
Diff
Trace (before patch)
(26.30 MB, application/zip)
2020-08-31 17:51 PDT
,
Dean Jackson
no flags
Details
Instruments screenshot
(483.40 KB, image/png)
2020-08-31 17:57 PDT
,
Dean Jackson
no flags
Details
View All
Add attachment
proposed patch, testcase, etc.
Dean Jackson
Comment 1
2020-08-30 12:39:06 PDT
<
rdar://problem/66845937
>
Dean Jackson
Comment 2
2020-08-30 12:48:07 PDT
Created
attachment 407571
[details]
Patch
Darin Adler
Comment 3
2020-08-30 13:08:17 PDT
Comment on
attachment 407571
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=407571&action=review
> Source/WebCore/dom/Document.cpp:8639 > + if (m_canvasesNeedingDisplayPreparation.isEmpty()) > + return;
This isn’t needed. The code below already efficiently does nothing in this case. Making an empty vector, an empty for loop, and an empty clear function are all efficient.
> Source/WebCore/html/CanvasBase.cpp:140 > + if (m_observers.isEmpty()) > + return;
This isn’t needed. The code below already efficiently does nothing in this case. Making an empty vector and an empty for loop are efficient.
> Source/WebCore/html/CanvasBase.cpp:149 > + if (m_observers.isEmpty()) > + return;
This isn’t needed. The code below already efficiently does nothing in this case. Making an empty vector and an empty for loop are efficient.
> Source/WebCore/html/CanvasBase.cpp:162 > + if (m_observers.isEmpty()) { > +#if ASSERT_ENABLED > + m_didNotifyObserversCanvasDestroyed = true; > +#endif > + return; > + }
This isn’t needed. The code below already efficiently does nothing in this case. Making an empty vector, an empty for loop, and an empty clear function are all efficient.
> Source/WebCore/html/HTMLCanvasElement.cpp:1054 > + if (needsPreparationForDisplay()) { > + if (insertionType.connectedToDocument) {
I suggest && rather than a nested if statement.
> Source/WebCore/html/HTMLCanvasElement.cpp:1055 > + auto& doc = parentOfInsertedTree.document();
Please use document, not doc.
> Source/WebCore/html/HTMLCanvasElement.cpp:1060 > + if (is<WebGLRenderingContextBase>(m_context.get())) { > + if (downcast<WebGLRenderingContextBase>(m_context.get())->compositingResultsNeedUpdating())
Three thoughts: 1) Instead of "(m_context.get())->" you can use "(*m_context)." and this applies here and other places in the file. 2) Instead of nested if you can use &&, which I think is clearer, but it ends up being a long line because of repeating the WebGLRenderingContextBase class name twice. 3) Could make compositingResultsNeedUpdating a virtual function and avoid the type check entirely.
> Source/WebCore/html/HTMLCanvasElement.cpp:1072 > + if (needsPreparationForDisplay()) { > + if (removalType.disconnectedFromDocument) {
I suggest && rather than a nested if statement.
> Source/WebCore/html/HTMLCanvasElement.cpp:1084 > + if (!m_context) > + return false;
This isn’t needed. The code below already efficiently returns false when m_context is null.
Dean Jackson
Comment 4
2020-08-31 11:29:39 PDT
I forgot to say that I measured and this does recover the 1-3% slowdown.
Dean Jackson
Comment 5
2020-08-31 11:33:10 PDT
Thanks Darin! I'll make all the suggested changes. (and update the changelog to note that I measured performance). As for the empty functions, I obviously didn't look at the implementation, but I assumed that the copyToVector(empty-HashSet) would have to actually create a Vector in order for the loop to know it was empty. I assume that's so insignificant it doesn't matter?
Darin Adler
Comment 6
2020-08-31 11:57:46 PDT
(In reply to Dean Jackson from
comment #5
)
> I assumed that the copyToVector(empty-HashSet) would have to actually > create a Vector in order for the loop to know it was empty. I assume that's > so insignificant it doesn't matter?
Yes, it has to create a vector. But a 0-sized vector is all on the stack (not the heap) and creating one should not involve any memory allocation and should not be all that different from checking the set for emptiness.
Dean Jackson
Comment 7
2020-08-31 17:51:22 PDT
Created
attachment 407640
[details]
Trace (before patch) If I look at the attached trace (which is without this patch), and search for CanvasBase::notifyObserversCanvasChanged I see copyToVector allocating a buffer which calls into bmalloc.
Dean Jackson
Comment 8
2020-08-31 17:57:09 PDT
Created
attachment 407642
[details]
Instruments screenshot
Darin Adler
Comment 9
2020-08-31 17:57:54 PDT
OK, but that’s not an empty set.
Darin Adler
Comment 10
2020-08-31 17:59:31 PDT
Is this called with non-empty sets too during the test?
Darin Adler
Comment 11
2020-08-31 18:00:06 PDT
Do we really need to copy the vector every time? Can the canvasChanged functions mutate the observers set?
Dean Jackson
Comment 12
2020-08-31 18:33:40 PDT
Oh. I'm a moron! The whole point of this patch was to make that HashSet empty in this case. It isn't empty before the fix.
Dean Jackson
Comment 13
2020-08-31 18:33:53 PDT
Ha. Darin guessed it as I worked it out.
Dean Jackson
Comment 14
2020-08-31 18:38:20 PDT
> Do we really need to copy the vector every time? Can the canvasChanged functions mutate the observers set?
The answer is yes, they technically can. I thought about different ways to avoid this. Right now the vectors don't change because I control the calls inside both the canvas observer updates and the after rendering updates, but someone could something bad if they didn't know. Maybe I could pass const CanvasBases around, but the called functions still need to be non-const.
Dean Jackson
Comment 15
2020-08-31 18:41:03 PDT
I can't pass const CanvasBase, because they ultimately need to call a non-const. But yeah, a canvasChanged call should never mutate the set of observers on itself.
Dean Jackson
Comment 16
2020-08-31 18:43:57 PDT
"notifyObserversCanvasDestroyed" might though, since the notification might do something to remove itself as an observer (even though it's already being deleted).
Dean Jackson
Comment 17
2020-08-31 18:59:40 PDT
> 3) Could make compositingResultsNeedUpdating a virtual function and avoid the type check entirely.
I made compositingResultsNeedUpdating, prepareForDisplay and needsPreparationForDisplay all virtuals, which cleans up the code significantly.
Dean Jackson
Comment 18
2020-09-01 18:47:12 PDT
Committed
r266443
: <
https://trac.webkit.org/changeset/266443
>
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