New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 803224 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Closed: Jan 2018
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Android , Windows , Chrome , Mac
Pri: 2
Type: Bug



Sign in to add a comment

CSSImageGeneratorValue caching is broken

Project Member Reported by schenney@chromium.org, Jan 17 2018

Issue description

In working to refactor CSSGeneratedImageValue, I have discovered that the cache management is broken.

In the AddCLient method, the client may have been added already for a non-empty size,
and subsequently now a different size, at which point we increment the count on a SizeAndCount value for the original size.

The upshot of this is that some generated images are never removed. It's a memory leak.

The underlying cause may be broken assumption about the ordering of AddClient/RemoveClient. In particular, when we need a new size we add the client at the new size then remove it at the old size, when it would be much better to do it the other way around.
 

Comment 1 by f...@opera.com, Jan 17 2018

Summary: CSSImageGeneratorValue caching is broken (was: CSSGeneratedImageValue caching is broken)
Heh, I discovered the same thing last week. I believe I concluded that a leak is not easy (if even possible) to trigger. (I tried constructing a test that would leak, but it wasn't obvious that it ever did. Two registrations of the same client on the same CSSImageGeneratorValue isn't entirely easy to manage it seems...)
While poking a bit at that I ended up refactoring the caching bits (|images_| and |sizes_|). I can share that if it's of any interest.
Project Member

Comment 2 by bugdroid1@chromium.org, Jan 18 2018

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/bd10ce90e022727c04c308ab5cbb0c433a6b369a

commit bd10ce90e022727c04c308ab5cbb0c433a6b369a
Author: Fredrik Söderquist <fs@opera.com>
Date: Thu Jan 18 20:51:46 2018

[CI] Rework size-based caching logic in CSSImageGeneratorValue

Rather than (ab)using AddClient/RemoveClient when updating the
cache for a client, move the actual cache to a helper class
(GeneratedImageCache) and then call the appropriate methods on
that object instead.

Bug:  803224 
Change-Id: Ifbb3edf8f25dbeef2f9f1fdd9840a0b32991e274
Reviewed-on: https://chromium-review.googlesource.com/873875
Reviewed-by: Stephen Chenney <schenney@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#530261}
[modify] https://crrev.com/bd10ce90e022727c04c308ab5cbb0c433a6b369a/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.cpp
[modify] https://crrev.com/bd10ce90e022727c04c308ab5cbb0c433a6b369a/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.h

Project Member

Comment 3 by bugdroid1@chromium.org, Jan 19 2018

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/7eae1bfd98044958313b126967a24977e26b1be2

commit 7eae1bfd98044958313b126967a24977e26b1be2
Author: Fredrik Söderquist <fs@opera.com>
Date: Fri Jan 19 17:27:13 2018

[CI] Remove unused argument from CSSImageGeneratorValue::AddClient

An "empty" size is always passed to AddClient, so the argument can be
removed. This also allows simplifying the caching logic (since the
size is always empty, which won't create a cache entry.)

Also change the find()+insert() sequence for |clients_| to use
only insert() instead, saving a hash lookup. Simplify the SizeAndCount
constructor since it never needs any non-zero initialization.

Bug:  803224 
Change-Id: I7efc7a130e8e93c1e2680116c429cb93e57d2d3f
Reviewed-on: https://chromium-review.googlesource.com/876086
Reviewed-by: Stephen Chenney <schenney@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#530547}
[modify] https://crrev.com/7eae1bfd98044958313b126967a24977e26b1be2/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.cpp
[modify] https://crrev.com/7eae1bfd98044958313b126967a24977e26b1be2/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.h
[modify] https://crrev.com/7eae1bfd98044958313b126967a24977e26b1be2/third_party/WebKit/Source/core/style/StyleGeneratedImage.cpp

Project Member

Comment 4 by bugdroid1@chromium.org, Jan 19 2018

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/3e03499bc5d86cbabf5e77280e6757d0202703d2

commit 3e03499bc5d86cbabf5e77280e6757d0202703d2
Author: Fredrik Söderquist <fs@opera.com>
Date: Fri Jan 19 22:04:15 2018

[CI] Remove LayoutObject dependency from CSS*GradientValue

Rather than passing a LayoutObject around we can pass around the
<Document, ComputedStyle> tuple that is the bits of data that is needed.

While a it, change CSSGradientValue::GetStopColors to return the vector
of Colors instead of using an out-variable.

Bug:  803224 
Change-Id: Ib89bf3c0e47495886b5b715504a90b262348c6f2
Reviewed-on: https://chromium-review.googlesource.com/875925
Reviewed-by: Stephen Chenney <schenney@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#530626}
[modify] https://crrev.com/3e03499bc5d86cbabf5e77280e6757d0202703d2/third_party/WebKit/Source/core/css/CSSGradientValue.cpp
[modify] https://crrev.com/3e03499bc5d86cbabf5e77280e6757d0202703d2/third_party/WebKit/Source/core/css/CSSGradientValue.h
[modify] https://crrev.com/3e03499bc5d86cbabf5e77280e6757d0202703d2/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp

Project Member

Comment 5 by bugdroid1@chromium.org, Jan 20 2018

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/2ce3871f3d54a3e2b32704ea9e2e5ba69c7ae033

commit 2ce3871f3d54a3e2b32704ea9e2e5ba69c7ae033
Author: Stephen Chenney <schenney@chromium.org>
Date: Sat Jan 20 00:04:01 2018

[CI] Fix caching of image size in CSSGeneratedImageValue

The CSSGeneratedImageValue image and client cache has only
one slot for the size of the image associated with any given
client, but the client could be registered with an empty size
and a non-empty size. In such cases we would not over-write
the non-empty size with the empty size, despite having deleted
the non-empty image. Subsequently removing the client again
would try to remove the non-empty one instead.

This patch adds DCHECKs to catch these cases, and fixes the
logic to only store non-empty sizes. Comments are added explaining
the invariant that the client only be present at one non-empty size
at any given time.

R=fs@opera.com
BUG= 803224 

Change-Id: Ie5601aaffe6e3eace4ff4a989dc892bea4fd381b
Reviewed-on: https://chromium-review.googlesource.com/876900
Reviewed-by: Fredrik Söderquist <fs@opera.com>
Commit-Queue: Stephen Chenney <schenney@chromium.org>
Cr-Commit-Position: refs/heads/master@{#530674}
[modify] https://crrev.com/2ce3871f3d54a3e2b32704ea9e2e5ba69c7ae033/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.cpp
[modify] https://crrev.com/2ce3871f3d54a3e2b32704ea9e2e5ba69c7ae033/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.h

Status: Fixed (was: Assigned)

Sign in to add a comment