<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[209914] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/209914">209914</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2016-12-16 00:42:29 -0800 (Fri, 16 Dec 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>svg/as-image/svg-image-with-data-uri-use-data-uri.svg is flaky after <a href="http://trac.webkit.org/projects/webkit/changeset/207754">r207754</a>
https://bugs.webkit.org/show_bug.cgi?id=163887
&lt;rdar://problem/29266436&gt;

Patch by Youenn Fablet &lt;youennf@gmail.com&gt; on 2016-12-16
Reviewed by Alex Christensen.

Source/WebCore:

Test: http/tests/security/cross-origin-cached-images-with-memory-pressure.html

With the introduction of cached resource cloning, an Image may be referenced by several CachedImage.
This did not work well with Image observer system as it mandates a one-to-one relationship.

Introducing CachedImageObserver to restore the one-to-one relationship between Image and its observer.
CachedImageObserver can keep references for more than one CachedImage.

In the future, it might be better to split more clearly CachedImageObserver and its API from CachedImage.
Or remove the concept of CachedResource cloning and find new ways to provide CachedResource origin information to clients.

* loader/cache/CachedImage.cpp:
(WebCore::CachedImage::load): Moved boolean image observer fields to CachedImageObserver.
(WebCore::CachedImage::setBodyDataFrom): Keeping a reference of the image observer when cloning the resource.
(WebCore::CachedImage::createImage): Creating the observer when creating the image.
(WebCore::CachedImage::CachedImageObserver::CachedImageObserver):
(WebCore::CachedImage::CachedImageObserver::decodedSizeChanged):
(WebCore::CachedImage::CachedImageObserver::didDraw):
(WebCore::CachedImage::CachedImageObserver::animationAdvanced):
(WebCore::CachedImage::CachedImageObserver::changedInRect):
(WebCore::CachedImage::clearImage):
* loader/cache/CachedImage.h:
* loader/cache/CachedResource.cpp:
(WebCore::CachedResource::setBodyDataFrom): Now that each cached image receives decodedSizeChanged callback, we need to set its size correctly.

LayoutTests:

* http/tests/security/cross-origin-cached-images-with-memory-pressure-expected.txt: Added.
* http/tests/security/cross-origin-cached-images-with-memory-pressure.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedImagecpp">trunk/Source/WebCore/loader/cache/CachedImage.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedImageh">trunk/Source/WebCore/loader/cache/CachedImage.h</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedResourcecpp">trunk/Source/WebCore/loader/cache/CachedResource.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestshttptestssecuritycrossorigincachedimageswithmemorypressureexpectedtxt">trunk/LayoutTests/http/tests/security/cross-origin-cached-images-with-memory-pressure-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestssecuritycrossorigincachedimageswithmemorypressurehtml">trunk/LayoutTests/http/tests/security/cross-origin-cached-images-with-memory-pressure.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (209913 => 209914)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-12-16 07:12:23 UTC (rev 209913)
+++ trunk/LayoutTests/ChangeLog        2016-12-16 08:42:29 UTC (rev 209914)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2016-12-16  Youenn Fablet  &lt;youennf@gmail.com&gt;
+
+        svg/as-image/svg-image-with-data-uri-use-data-uri.svg is flaky after r207754
+        https://bugs.webkit.org/show_bug.cgi?id=163887
+        &lt;rdar://problem/29266436&gt;
+
+        Reviewed by Alex Christensen.
+
+        * http/tests/security/cross-origin-cached-images-with-memory-pressure-expected.txt: Added.
+        * http/tests/security/cross-origin-cached-images-with-memory-pressure.html: Added.
+
</ins><span class="cx"> 2016-12-15  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         text-align: justify and word-spacing combine to overflow column
</span></span></pre></div>
<a id="trunkLayoutTestshttptestssecuritycrossorigincachedimageswithmemorypressureexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/security/cross-origin-cached-images-with-memory-pressure-expected.txt (0 => 209914)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/security/cross-origin-cached-images-with-memory-pressure-expected.txt                                (rev 0)
+++ trunk/LayoutTests/http/tests/security/cross-origin-cached-images-with-memory-pressure-expected.txt        2016-12-16 08:42:29 UTC (rev 209914)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+Tests source origin difference for cached resources.
+
+This succeeds if not crashing after applying memory pressure (https://bugs.webkit.org/show_bug.cgi?id=163887).
+Test 1 PASS: Loaded img data:image/svg+xml;base64, PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJMaWdodFNlYUdyZWVuIi8+PHJlY3QgeD0iMjAiIHk9IjIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJyZWQiLz48aW1hZ2UgeD0iMjAiIHk9IjIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB4bGluazpocmVmPSJkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBITjJaeUI0Yld4dWN6MGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNakF3TUM5emRtY2lJSGh0Ykc1ek9uaHNhVzVyUFNKb2RIUncNCk9pOHZkM2QzTG5jekxtOXlaeTh4T1RrNUwzaHNhVzVySWo0OGNtVmpkQ0I0UFNJd0lpQjVQU0l3SWlCM2FXUjBhRDBpTVRBd0pTSWcNCmFHVnBaMmgwUFNJeE1EQWxJaUJtYVd4c1BTSm5jbVZsYmlJdlBqeHlaV04wSUhnOUlqSXdJaUI1UFNJeU1DSWdkMmxrZEdnOUlqRXcNCk1DVWlJR2hsYVdkb2REMGlNVEF3SlNJZ1ptbHNiRDBpY21Wa0lpOCtQR2x0WVdkbElIZzlJakl3SWlCNVBTSXlNQ0lnZDJsa2RHZzkNCklqRXdNQ1VpSUdobGFXZG9kRDBpTVRBd0pTSWdlR3hwYm1zNmFISmxaajBpWkdGMFlUcHBiV0ZuWlM5emRtY3JlRzFzTzJKaGMyVTINCk5DeFFTRTR5V25sQ05HSlhlSF
 ZqZWpCcFlVaFNNR05FYjNaTU0yUXpaSGsxTTAxNU5YWmpiV04yVFdwQmQwMURPWHBrYldOcFNVaG8NCmRHSkhOWHBQYm1oellWYzFjbEJUU205a1NGSjNEUXBQYVRoMlpETmtNMHh1WTNwTWJUbDVXbms0ZUU5VWF6Vk1NMmh6WVZjMWNrbHENCk5EaGpiVlpxWkVOQ05GQlRTWGRKYVVJMVVGTkpkMGxwUWpOaFYxSXdZVVF3YVUxVVFYZEtVMGxuRFFwaFIxWndXakpvTUZCVFNYaE4NClJFRnNTV2xDYldGWGVITlFVMHB6WVZka2IyUkZaSGxhVjFaMVNXazRLMUJJU214Wk0xRm5aVVF3YVUxcVFXbEpTR3M1U1dwSmQwbHANClFqTmhWMUl3RFFwaFJEQnBUVlJCZDBwVFNXZGhSMVp3V2pKb01GQlRTWGhOUkVGc1NXbENiV0ZYZUhOUVUwcDVXbGRSYVV4Nk5EaGgNClZ6Rm9XakpWWjJWRU1HbE5ha0ZwU1Vock9VbHFTWGRKYVVJekRRcGhWMUl3WVVRd2FVMVVRWGRLVTBsbllVZFdjRm95YURCUVUwbDQNClRVUkJiRWxwUWpSaVIyeDFZWHB3YjJOdFZtMVFVMHByV1ZoU2FFOXRiSFJaVjJSc1RETk9NbHA1ZERSaVYzYzNEUXBaYlVaNldsUloNCk1FeEdRa2xVYWtwaFpWVkpNRmxzWkRSa1YwNDJUVWRzYUZOR1NYZFpNRkoyWkd0M2VscEVUbXRsVkZWNlZGaHJNV1J0VG5SWk0xcE8NCllXdEdNMVJWVFRWbGJWSjBEUXBaTW14S1UwZG9NRmxyWXpGbGF6bDFZVWhPYUZaNlZubFZSazVMWWpKU1NWVnVZMDVEYXpsd1QwaGENCmEwMHlVWHBVUnpWcVpXdDRkRTlZYkdGbFZHZzBWREZTY2s1VmQzcGhTRTVvRFFwV2VsWjVVMWR2TUU
 5SFRuUldiWEJyVVRCSk1GVkcNClRrcGtNR3h3VVdwV1VWVXdiRE5UVjJ4RFRUSkdXRlZxUW1oU1JFSndWRlpTUW1Rd2NGUlRWMk5PUTIxR1NGWnVRbUZOYldkM0RRcFYNClJrNUtaVVV4UlZGWGVFcGhWVXAwV1Zaa05HTXhRbFJUYms1b1ZucEdjMVZxVGt0aVJuQllUa2RzVFdWcVVUUlpNakZYWVcxU1JGRnENClVsRlZNR3cxVkZWT1Nsb3lWbFZOUjJ4T0RRcGhhMFp3VTFWb2EyTkdjRWxWYlRoT1EyeENWRk5ZYUU1U1JVWnpVMWRzUTJJeGNGaGkNClJ6Vm9VMFpGTlZOWGNFWmtNREZFVmxkc1NsSXhjSGRaYTJRelQxVnNkVk50ZUdGUk1Hd3lEUXBWUjNBMFkwZEtXRkp0TldGVk1Fa3cNClZVWk9TbVZWTVVSVFYyUnNWa1JDY0ZSWGNFSmhWV3hKV2toQlRrTnNjRWxWYlRsUlZUQnNORlJWVWtKaVJXeHdVVzA1WVZZeWVIVloNClZXaFNEUXBQVld4eFVsaGtUbEV4Vm5CVFZXaHZZekpHV0U1WVNsQmlWMmcxVjJ4a1drOVZiSFJWYldoclVqQlZNbGxXWTNoaFJtOTUNClZsaGFhbEo2Vm5WVWVrcExZVWROZVZaVVNVNURhelZFRFFwbFNFSlhZVEJ3VVZaWE5XcGtNVTEzV2tjMWFVMUZXa05WVmxaSFZERlYNCmVGWnRPVk5XYkZwMVZWWldSMUZzU1hoU2EwcFNWbFZhUkZsVVFrOVJiR1JXVW10S1VsWlZiM3BVYTJoRERRcFdNVnBXVW10S1VsWlYNCldrTldNRlV4VmtaV2NWRnJiMDVEYkVaWlUyNXdUMUl3TUhsV1ZsWkhVV3hHVm1SRmRGUmlSWEJIVlcxNFYySkdVblZUYWtKT1VtdGENClIxWkhkRWRSYkVaV0RRcGlSRTVQ
 VFVVMVJsZHRjRzVPVm05NVdYcEdVbUY2YTNwWmEyaEhXVlphUm1GR1VtbFhSa3AxVlZSQ2MySnMNClJsWlNiRTFPUTJ4S1ZsUnJTbEpOUlZwNVZsZDBSMkpzUmxoaVJYQmhEUXBOUlZwRFZsZDBWMUpHUmxaVWEwcG9UVlZ3UTFkcVFrZGoNClJrNVlXa1ZLVWxacmNFZFZWRUpIVWtaR1dHUkdUbEpXTWxKRFdWWldjMkpzUmxaU2JFNVRWbFUxUTFWVVFrZGpiRlp5RFFwU2JUUk8NClEyeEdXR0pGY0dGTlJWcERWbGQwVjFKR1JsWlVhMHBvVFZWd1ExZHFRa2RqUms1WVdrVktVbFpyY0VkVlZFSkhVa1pHV0dSR1RsSlcNCk1sSkRXVlpXYzJKc1JsWlNiRTVURFFwV1ZUVkRWVlJDUjJOc1ZuSlNiVFZTVmpKNFMxZHFRa2RSYkZaeVZtdFJUa05zUmxaVWEwcG8NClRWVndRMWRxUWtkalJrNVlXa1ZLVWxacmNFZFZWRUpIVWtaR1dHUkdUbEpXTWxKRERRcFpWbFp6WW14R1ZsSnNUbE5XVlRWRFZWUkMNClIyTnNWbkpTYlRWU1ZqSlNTMVZzVmtkU2JGWnlWbXRTVWxaVk5VTlpWRVpMVVcxU2RWTnRNRTVEYlU1elZXeEtWVkpYVW05Vk1GSlANCkRRcGxSbXh5VW10S1VsWlZXa05WVjNSM1ZURmFWVlpyV21waVdGSk1WMnBLYTJKc1FsVk5SMnhSWVc1a01sbFdZM2hoUm05NVZsTjANClVWRjZiRFphUnpGcVN6QlNVbUl3TlVSYWVqQTVEUXBKYWpRNFRESnNkRmxYWkd4UWFuZDJZek5hYmxCblBUMGlQand2YVcxaFoyVSsNClBDOXpkbWMrIj48L2ltYWdlPjwvc3ZnPg== from localhost:8000 (crossOrigin=anonymous)
+Test 2 PASS: Loaded img data:image/svg+xml;base64, PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJMaWdodFNlYUdyZWVuIi8+PHJlY3QgeD0iMjAiIHk9IjIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJyZWQiLz48aW1hZ2UgeD0iMjAiIHk9IjIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB4bGluazpocmVmPSJkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBITjJaeUI0Yld4dWN6MGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNakF3TUM5emRtY2lJSGh0Ykc1ek9uaHNhVzVyUFNKb2RIUncNCk9pOHZkM2QzTG5jekxtOXlaeTh4T1RrNUwzaHNhVzVySWo0OGNtVmpkQ0I0UFNJd0lpQjVQU0l3SWlCM2FXUjBhRDBpTVRBd0pTSWcNCmFHVnBaMmgwUFNJeE1EQWxJaUJtYVd4c1BTSm5jbVZsYmlJdlBqeHlaV04wSUhnOUlqSXdJaUI1UFNJeU1DSWdkMmxrZEdnOUlqRXcNCk1DVWlJR2hsYVdkb2REMGlNVEF3SlNJZ1ptbHNiRDBpY21Wa0lpOCtQR2x0WVdkbElIZzlJakl3SWlCNVBTSXlNQ0lnZDJsa2RHZzkNCklqRXdNQ1VpSUdobGFXZG9kRDBpTVRBd0pTSWdlR3hwYm1zNmFISmxaajBpWkdGMFlUcHBiV0ZuWlM5emRtY3JlRzFzTzJKaGMyVTINCk5DeFFTRTR5V25sQ05HSlhlSF
 ZqZWpCcFlVaFNNR05FYjNaTU0yUXpaSGsxTTAxNU5YWmpiV04yVFdwQmQwMURPWHBrYldOcFNVaG8NCmRHSkhOWHBQYm1oellWYzFjbEJUU205a1NGSjNEUXBQYVRoMlpETmtNMHh1WTNwTWJUbDVXbms0ZUU5VWF6Vk1NMmh6WVZjMWNrbHENCk5EaGpiVlpxWkVOQ05GQlRTWGRKYVVJMVVGTkpkMGxwUWpOaFYxSXdZVVF3YVUxVVFYZEtVMGxuRFFwaFIxWndXakpvTUZCVFNYaE4NClJFRnNTV2xDYldGWGVITlFVMHB6WVZka2IyUkZaSGxhVjFaMVNXazRLMUJJU214Wk0xRm5aVVF3YVUxcVFXbEpTR3M1U1dwSmQwbHANClFqTmhWMUl3RFFwaFJEQnBUVlJCZDBwVFNXZGhSMVp3V2pKb01GQlRTWGhOUkVGc1NXbENiV0ZYZUhOUVUwcDVXbGRSYVV4Nk5EaGgNClZ6Rm9XakpWWjJWRU1HbE5ha0ZwU1Vock9VbHFTWGRKYVVJekRRcGhWMUl3WVVRd2FVMVVRWGRLVTBsbllVZFdjRm95YURCUVUwbDQNClRVUkJiRWxwUWpSaVIyeDFZWHB3YjJOdFZtMVFVMHByV1ZoU2FFOXRiSFJaVjJSc1RETk9NbHA1ZERSaVYzYzNEUXBaYlVaNldsUloNCk1FeEdRa2xVYWtwaFpWVkpNRmxzWkRSa1YwNDJUVWRzYUZOR1NYZFpNRkoyWkd0M2VscEVUbXRsVkZWNlZGaHJNV1J0VG5SWk0xcE8NCllXdEdNMVJWVFRWbGJWSjBEUXBaTW14S1UwZG9NRmxyWXpGbGF6bDFZVWhPYUZaNlZubFZSazVMWWpKU1NWVnVZMDVEYXpsd1QwaGENCmEwMHlVWHBVUnpWcVpXdDRkRTlZYkdGbFZHZzBWREZTY2s1VmQzcGhTRTVvRFFwV2VsWjVVMWR2TUU
 5SFRuUldiWEJyVVRCSk1GVkcNClRrcGtNR3h3VVdwV1VWVXdiRE5UVjJ4RFRUSkdXRlZxUW1oU1JFSndWRlpTUW1Rd2NGUlRWMk5PUTIxR1NGWnVRbUZOYldkM0RRcFYNClJrNUtaVVV4UlZGWGVFcGhWVXAwV1Zaa05HTXhRbFJUYms1b1ZucEdjMVZxVGt0aVJuQllUa2RzVFdWcVVUUlpNakZYWVcxU1JGRnENClVsRlZNR3cxVkZWT1Nsb3lWbFZOUjJ4T0RRcGhhMFp3VTFWb2EyTkdjRWxWYlRoT1EyeENWRk5ZYUU1U1JVWnpVMWRzUTJJeGNGaGkNClJ6Vm9VMFpGTlZOWGNFWmtNREZFVmxkc1NsSXhjSGRaYTJRelQxVnNkVk50ZUdGUk1Hd3lEUXBWUjNBMFkwZEtXRkp0TldGVk1Fa3cNClZVWk9TbVZWTVVSVFYyUnNWa1JDY0ZSWGNFSmhWV3hKV2toQlRrTnNjRWxWYlRsUlZUQnNORlJWVWtKaVJXeHdVVzA1WVZZeWVIVloNClZXaFNEUXBQVld4eFVsaGtUbEV4Vm5CVFZXaHZZekpHV0U1WVNsQmlWMmcxVjJ4a1drOVZiSFJWYldoclVqQlZNbGxXWTNoaFJtOTUNClZsaGFhbEo2Vm5WVWVrcExZVWROZVZaVVNVNURhelZFRFFwbFNFSlhZVEJ3VVZaWE5XcGtNVTEzV2tjMWFVMUZXa05WVmxaSFZERlYNCmVGWnRPVk5XYkZwMVZWWldSMUZzU1hoU2EwcFNWbFZhUkZsVVFrOVJiR1JXVW10S1VsWlZiM3BVYTJoRERRcFdNVnBXVW10S1VsWlYNCldrTldNRlV4VmtaV2NWRnJiMDVEYkVaWlUyNXdUMUl3TUhsV1ZsWkhVV3hHVm1SRmRGUmlSWEJIVlcxNFYySkdVblZUYWtKT1VtdGENClIxWkhkRWRSYkVaV0RRcGlSRTVQ
 VFVVMVJsZHRjRzVPVm05NVdYcEdVbUY2YTNwWmEyaEhXVlphUm1GR1VtbFhSa3AxVlZSQ2MySnMNClJsWlNiRTFPUTJ4S1ZsUnJTbEpOUlZwNVZsZDBSMkpzUmxoaVJYQmhEUXBOUlZwRFZsZDBWMUpHUmxaVWEwcG9UVlZ3UTFkcVFrZGoNClJrNVlXa1ZLVWxacmNFZFZWRUpIVWtaR1dHUkdUbEpXTWxKRFdWWldjMkpzUmxaU2JFNVRWbFUxUTFWVVFrZGpiRlp5RFFwU2JUUk8NClEyeEdXR0pGY0dGTlJWcERWbGQwVjFKR1JsWlVhMHBvVFZWd1ExZHFRa2RqUms1WVdrVktVbFpyY0VkVlZFSkhVa1pHV0dSR1RsSlcNCk1sSkRXVlpXYzJKc1JsWlNiRTVURFFwV1ZUVkRWVlJDUjJOc1ZuSlNiVFZTVmpKNFMxZHFRa2RSYkZaeVZtdFJUa05zUmxaVWEwcG8NClRWVndRMWRxUWtkalJrNVlXa1ZLVWxacmNFZFZWRUpIVWtaR1dHUkdUbEpXTWxKRERRcFpWbFp6WW14R1ZsSnNUbE5XVlRWRFZWUkMNClIyTnNWbkpTYlRWU1ZqSlNTMVZzVmtkU2JGWnlWbXRTVWxaVk5VTlpWRVpMVVcxU2RWTnRNRTVEYlU1elZXeEtWVkpYVW05Vk1GSlANCkRRcGxSbXh5VW10S1VsWlZXa05WVjNSM1ZURmFWVlpyV21waVdGSk1WMnBLYTJKc1FsVk5SMnhSWVc1a01sbFdZM2hoUm05NVZsTjANClVWRjZiRFphUnpGcVN6QlNVbUl3TlVSYWVqQTVEUXBKYWpRNFRESnNkRmxYWkd4UWFuZDJZek5hYmxCblBUMGlQand2YVcxaFoyVSsNClBDOXpkbWMrIj48L2ltYWdlPjwvc3ZnPg== from localhost:8080 (crossOrigin=anonymous)
+PASS applying memory pressure
+  
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestssecuritycrossorigincachedimageswithmemorypressurehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/security/cross-origin-cached-images-with-memory-pressure.html (0 => 209914)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/security/cross-origin-cached-images-with-memory-pressure.html                                (rev 0)
+++ trunk/LayoutTests/http/tests/security/cross-origin-cached-images-with-memory-pressure.html        2016-12-16 08:42:29 UTC (rev 209914)
</span><span class="lines">@@ -0,0 +1,110 @@
</span><ins>+&lt;html&gt;
+&lt;body&gt;
+&lt;p&gt;Tests source origin difference for cached resources.&lt;/p
+&lt;p&gt;This succeeds if not crashing after applying memory pressure (https://bugs.webkit.org/show_bug.cgi?id=163887).&lt;/p&gt;
+&lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+&lt;div&gt;
+    &lt;iframe id=&quot;iframe1&quot;&gt;&lt;/iframe&gt;
+    &lt;iframe id=&quot;iframe2&quot;&gt;&lt;/iframe&gt;
+&lt;/div&gt;
+&lt;script&gt;
+if (window.testRunner) {
+   testRunner.dumpAsText();
+   testRunner.waitUntilDone();
+}
+
+window.addEventListener(&quot;message&quot;, function(event) {
+    document.getElementById('console').innerHTML += event.data + &quot;&lt;br/&gt;&quot;;
+    loadNextFrame();
+});
+
+var iframeURL8000 = &quot;http://localhost:8000/security/resources/cross-origin-cached-resource-iframe.html&quot;;
+var iframeURL8080 = &quot;http://localhost:8080/security/resources/cross-origin-cached-resource-iframe.html&quot;;
+
+var allowAllImage1 = &quot;data:image/svg+xml;base64, &quot; +
+        &quot;PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRw&quot; +
+        &quot;Oi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIg&quot; +
+        &quot;aGVpZ2h0PSIxMDAlIiBmaWxsPSJMaWdodFNlYUdyZWVuIi8+PHJlY3QgeD0iMjAiIHk9IjIwIiB3&quot; +
+        &quot;aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJyZWQiLz48aW1hZ2UgeD0iMjAiIHk9IjIw&quot; +
+        &quot;IiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB4bGluazpocmVmPSJkYXRhOmltYWdlL3N2Zyt4&quot; +
+        &quot;bWw7YmFzZTY0LFBITjJaeUI0Yld4dWN6MGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNakF3TUM5&quot; +
+        &quot;emRtY2lJSGh0Ykc1ek9uaHNhVzVyUFNKb2RIUncNCk9pOHZkM2QzTG5jekxtOXlaeTh4T1RrNUwz&quot; +
+        &quot;aHNhVzVySWo0OGNtVmpkQ0I0UFNJd0lpQjVQU0l3SWlCM2FXUjBhRDBpTVRBd0pTSWcNCmFHVnBa&quot; +
+        &quot;MmgwUFNJeE1EQWxJaUJtYVd4c1BTSm5jbVZsYmlJdlBqeHlaV04wSUhnOUlqSXdJaUI1UFNJeU1D&quot; +
+        &quot;SWdkMmxrZEdnOUlqRXcNCk1DVWlJR2hsYVdkb2REMGlNVEF3SlNJZ1ptbHNiRDBpY21Wa0lpOCtQ&quot; +
+        &quot;R2x0WVdkbElIZzlJakl3SWlCNVBTSXlNQ0lnZDJsa2RHZzkNCklqRXdNQ1VpSUdobGFXZG9kRDBp&quot; +
+        &quot;TVRBd0pTSWdlR3hwYm1zNmFISmxaajBpWkdGMFlUcHBiV0ZuWlM5emRtY3JlRzFzTzJKaGMyVTIN&quot; +
+        &quot;Ck5DeFFTRTR5V25sQ05HSlhlSFZqZWpCcFlVaFNNR05FYjNaTU0yUXpaSGsxTTAxNU5YWmpiV04y&quot; +
+        &quot;VFdwQmQwMURPWHBrYldOcFNVaG8NCmRHSkhOWHBQYm1oellWYzFjbEJUU205a1NGSjNEUXBQYVRo&quot; +
+        &quot;MlpETmtNMHh1WTNwTWJUbDVXbms0ZUU5VWF6Vk1NMmh6WVZjMWNrbHENCk5EaGpiVlpxWkVOQ05G&quot; +
+        &quot;QlRTWGRKYVVJMVVGTkpkMGxwUWpOaFYxSXdZVVF3YVUxVVFYZEtVMGxuRFFwaFIxWndXakpvTUZC&quot; +
+        &quot;VFNYaE4NClJFRnNTV2xDYldGWGVITlFVMHB6WVZka2IyUkZaSGxhVjFaMVNXazRLMUJJU214Wk0x&quot; +
+        &quot;Rm5aVVF3YVUxcVFXbEpTR3M1U1dwSmQwbHANClFqTmhWMUl3RFFwaFJEQnBUVlJCZDBwVFNXZGhS&quot; +
+        &quot;MVp3V2pKb01GQlRTWGhOUkVGc1NXbENiV0ZYZUhOUVUwcDVXbGRSYVV4Nk5EaGgNClZ6Rm9XakpW&quot; +
+        &quot;WjJWRU1HbE5ha0ZwU1Vock9VbHFTWGRKYVVJekRRcGhWMUl3WVVRd2FVMVVRWGRLVTBsbllVZFdj&quot; +
+        &quot;Rm95YURCUVUwbDQNClRVUkJiRWxwUWpSaVIyeDFZWHB3YjJOdFZtMVFVMHByV1ZoU2FFOXRiSFJa&quot; +
+        &quot;VjJSc1RETk9NbHA1ZERSaVYzYzNEUXBaYlVaNldsUloNCk1FeEdRa2xVYWtwaFpWVkpNRmxzWkRS&quot; +
+        &quot;a1YwNDJUVWRzYUZOR1NYZFpNRkoyWkd0M2VscEVUbXRsVkZWNlZGaHJNV1J0VG5SWk0xcE8NCllX&quot; +
+        &quot;dEdNMVJWVFRWbGJWSjBEUXBaTW14S1UwZG9NRmxyWXpGbGF6bDFZVWhPYUZaNlZubFZSazVMWWpK&quot; +
+        &quot;U1NWVnVZMDVEYXpsd1QwaGENCmEwMHlVWHBVUnpWcVpXdDRkRTlZYkdGbFZHZzBWREZTY2s1VmQz&quot; +
+        &quot;cGhTRTVvRFFwV2VsWjVVMWR2TUU5SFRuUldiWEJyVVRCSk1GVkcNClRrcGtNR3h3VVdwV1VWVXdi&quot; +
+        &quot;RE5UVjJ4RFRUSkdXRlZxUW1oU1JFSndWRlpTUW1Rd2NGUlRWMk5PUTIxR1NGWnVRbUZOYldkM0RR&quot; +
+        &quot;cFYNClJrNUtaVVV4UlZGWGVFcGhWVXAwV1Zaa05HTXhRbFJUYms1b1ZucEdjMVZxVGt0aVJuQllU&quot; +
+        &quot;a2RzVFdWcVVUUlpNakZYWVcxU1JGRnENClVsRlZNR3cxVkZWT1Nsb3lWbFZOUjJ4T0RRcGhhMFp3&quot; +
+        &quot;VTFWb2EyTkdjRWxWYlRoT1EyeENWRk5ZYUU1U1JVWnpVMWRzUTJJeGNGaGkNClJ6Vm9VMFpGTlZO&quot; +
+        &quot;WGNFWmtNREZFVmxkc1NsSXhjSGRaYTJRelQxVnNkVk50ZUdGUk1Hd3lEUXBWUjNBMFkwZEtXRkp0&quot; +
+        &quot;TldGVk1Fa3cNClZVWk9TbVZWTVVSVFYyUnNWa1JDY0ZSWGNFSmhWV3hKV2toQlRrTnNjRWxWYlRs&quot; +
+        &quot;UlZUQnNORlJWVWtKaVJXeHdVVzA1WVZZeWVIVloNClZXaFNEUXBQVld4eFVsaGtUbEV4Vm5CVFZX&quot; +
+        &quot;aHZZekpHV0U1WVNsQmlWMmcxVjJ4a1drOVZiSFJWYldoclVqQlZNbGxXWTNoaFJtOTUNClZsaGFh&quot; +
+        &quot;bEo2Vm5WVWVrcExZVWROZVZaVVNVNURhelZFRFFwbFNFSlhZVEJ3VVZaWE5XcGtNVTEzV2tjMWFV&quot; +
+        &quot;MUZXa05WVmxaSFZERlYNCmVGWnRPVk5XYkZwMVZWWldSMUZzU1hoU2EwcFNWbFZhUkZsVVFrOVJi&quot; +
+        &quot;R1JXVW10S1VsWlZiM3BVYTJoRERRcFdNVnBXVW10S1VsWlYNCldrTldNRlV4VmtaV2NWRnJiMDVE&quot; +
+        &quot;YkVaWlUyNXdUMUl3TUhsV1ZsWkhVV3hHVm1SRmRGUmlSWEJIVlcxNFYySkdVblZUYWtKT1VtdGEN&quot; +
+        &quot;ClIxWkhkRWRSYkVaV0RRcGlSRTVQVFVVMVJsZHRjRzVPVm05NVdYcEdVbUY2YTNwWmEyaEhXVlph&quot; +
+        &quot;Um1GR1VtbFhSa3AxVlZSQ2MySnMNClJsWlNiRTFPUTJ4S1ZsUnJTbEpOUlZwNVZsZDBSMkpzUmxo&quot; +
+        &quot;aVJYQmhEUXBOUlZwRFZsZDBWMUpHUmxaVWEwcG9UVlZ3UTFkcVFrZGoNClJrNVlXa1ZLVWxacmNF&quot; +
+        &quot;ZFZWRUpIVWtaR1dHUkdUbEpXTWxKRFdWWldjMkpzUmxaU2JFNVRWbFUxUTFWVVFrZGpiRlp5RFFw&quot; +
+        &quot;U2JUUk8NClEyeEdXR0pGY0dGTlJWcERWbGQwVjFKR1JsWlVhMHBvVFZWd1ExZHFRa2RqUms1WVdr&quot; +
+        &quot;VktVbFpyY0VkVlZFSkhVa1pHV0dSR1RsSlcNCk1sSkRXVlpXYzJKc1JsWlNiRTVURFFwV1ZUVkRW&quot; +
+        &quot;VlJDUjJOc1ZuSlNiVFZTVmpKNFMxZHFRa2RSYkZaeVZtdFJUa05zUmxaVWEwcG8NClRWVndRMWRx&quot; +
+        &quot;UWtkalJrNVlXa1ZLVWxacmNFZFZWRUpIVWtaR1dHUkdUbEpXTWxKRERRcFpWbFp6WW14R1ZsSnNU&quot; +
+        &quot;bE5XVlRWRFZWUkMNClIyTnNWbkpTYlRWU1ZqSlNTMVZzVmtkU2JGWnlWbXRTVWxaVk5VTlpWRVpM&quot; +
+        &quot;VVcxU2RWTnRNRTVEYlU1elZXeEtWVkpYVW05Vk1GSlANCkRRcGxSbXh5VW10S1VsWlZXa05WVjNS&quot; +
+        &quot;M1ZURmFWVlpyV21waVdGSk1WMnBLYTJKc1FsVk5SMnhSWVc1a01sbFdZM2hoUm05NVZsTjANClVW&quot; +
+        &quot;RjZiRFphUnpGcVN6QlNVbUl3TlVSYWVqQTVEUXBKYWpRNFRESnNkRmxYWkd4UWFuZDJZek5hYmxC&quot; +
+        &quot;blBUMGlQand2YVcxaFoyVSsNClBDOXpkbWMrIj48L2ltYWdlPjwvc3ZnPg==&quot;;
+
+var counter = 0;
+function loadNextFrame()
+{
+    counter++;
+    // Four first tests try to load an image with a given origin and then the same image (in cache) with a different origin.
+    if (counter == 1)
+        document.getElementById('iframe1').src = iframeURL8000 + &quot;#&quot; +
+            encodeURIComponent(JSON.stringify({node: &quot;img&quot;, url: allowAllImage1, shouldPass:true, crossOrigin: &quot;anonymous&quot;, id: 1}));
+    else if (counter == 2)
+        document.getElementById('iframe2').src = iframeURL8080 + &quot;#&quot; +
+            encodeURIComponent(JSON.stringify({node: &quot;img&quot;, url: allowAllImage1, shouldPass: true, crossOrigin: &quot;anonymous&quot;, id: 2}));
+    else
+        endTest();
+}
+
+function endTest()
+{
+    // Removing iframe2 and applying memory pressure should kick in SVG CachedImage clearing of observer
+    document.getElementById('iframe2').src = &quot;&quot;;
+    setTimeout(function() {
+        if (window.internals) {
+            internals.beginSimulatedMemoryPressure();
+            internals.endSimulatedMemoryPressure();
+        }
+        document.getElementById('console').innerHTML += &quot;PASS applying memory pressure&quot;;
+        if (window.testRunner)
+            testRunner.notifyDone();
+    });
+}
+
+loadNextFrame();
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (209913 => 209914)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-12-16 07:12:23 UTC (rev 209913)
+++ trunk/Source/WebCore/ChangeLog        2016-12-16 08:42:29 UTC (rev 209914)
</span><span class="lines">@@ -1,3 +1,36 @@
</span><ins>+2016-12-16  Youenn Fablet  &lt;youennf@gmail.com&gt;
+
+        svg/as-image/svg-image-with-data-uri-use-data-uri.svg is flaky after r207754
+        https://bugs.webkit.org/show_bug.cgi?id=163887
+        &lt;rdar://problem/29266436&gt;
+
+        Reviewed by Alex Christensen.
+
+        Test: http/tests/security/cross-origin-cached-images-with-memory-pressure.html
+
+        With the introduction of cached resource cloning, an Image may be referenced by several CachedImage.
+        This did not work well with Image observer system as it mandates a one-to-one relationship.
+
+        Introducing CachedImageObserver to restore the one-to-one relationship between Image and its observer.
+        CachedImageObserver can keep references for more than one CachedImage.
+
+        In the future, it might be better to split more clearly CachedImageObserver and its API from CachedImage.
+        Or remove the concept of CachedResource cloning and find new ways to provide CachedResource origin information to clients.
+
+        * loader/cache/CachedImage.cpp:
+        (WebCore::CachedImage::load): Moved boolean image observer fields to CachedImageObserver.
+        (WebCore::CachedImage::setBodyDataFrom): Keeping a reference of the image observer when cloning the resource.
+        (WebCore::CachedImage::createImage): Creating the observer when creating the image.
+        (WebCore::CachedImage::CachedImageObserver::CachedImageObserver):
+        (WebCore::CachedImage::CachedImageObserver::decodedSizeChanged):
+        (WebCore::CachedImage::CachedImageObserver::didDraw):
+        (WebCore::CachedImage::CachedImageObserver::animationAdvanced):
+        (WebCore::CachedImage::CachedImageObserver::changedInRect):
+        (WebCore::CachedImage::clearImage):
+        * loader/cache/CachedImage.h:
+        * loader/cache/CachedResource.cpp:
+        (WebCore::CachedResource::setBodyDataFrom): Now that each cached image receives decodedSizeChanged callback, we need to set its size correctly.
+
</ins><span class="cx"> 2016-12-15  Joonghun Park  &lt;jh718.park@samsung.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [EFL] Fix debug build break since r209873. Unreviewed.
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedImagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedImage.cpp (209913 => 209914)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedImage.cpp        2016-12-16 07:12:23 UTC (rev 209913)
+++ trunk/Source/WebCore/loader/cache/CachedImage.cpp        2016-12-16 08:42:29 UTC (rev 209914)
</span><span class="lines">@@ -89,13 +89,6 @@
</span><span class="cx">         CachedResource::load(loader);
</span><span class="cx">     else
</span><span class="cx">         setLoading(false);
</span><del>-
-    if (m_loader) {
-        m_allowSubsampling = m_loader-&gt;frameLoader()-&gt;frame().settings().imageSubsamplingEnabled();
-        m_allowLargeImageAsyncDecoding = m_loader-&gt;frameLoader()-&gt;frame().settings().largeImageAsyncDecodingEnabled();
-        m_allowAnimatedImageAsyncDecoding = m_loader-&gt;frameLoader()-&gt;frame().settings().animatedImageAsyncDecodingEnabled();
-        m_showDebugBackground = m_loader-&gt;frameLoader()-&gt;frame().settings().showDebugBorders();
-    }
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CachedImage::setBodyDataFrom(const CachedResource&amp; resource)
</span><span class="lines">@@ -106,6 +99,9 @@
</span><span class="cx">     CachedResource::setBodyDataFrom(resource);
</span><span class="cx"> 
</span><span class="cx">     m_image = image.m_image;
</span><ins>+    m_imageObserver = image.m_imageObserver;
+    if (m_imageObserver)
+        m_imageObserver-&gt;add(*this);
</ins><span class="cx"> 
</span><span class="cx">     if (m_image &amp;&amp; is&lt;SVGImage&gt;(*m_image))
</span><span class="cx">         m_svgImageCache = std::make_unique&lt;SVGImageCache&gt;(&amp;downcast&lt;SVGImage&gt;(*m_image));
</span><span class="lines">@@ -324,16 +320,18 @@
</span><span class="cx">     if (m_image)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    m_imageObserver = CachedImageObserver::create(*this);
+
+    if (m_response.mimeType() == &quot;image/svg+xml&quot;) {
+        auto svgImage = SVGImage::create(*m_imageObserver, url());
+        m_svgImageCache = std::make_unique&lt;SVGImageCache&gt;(svgImage.ptr());
+        m_image = WTFMove(svgImage);
</ins><span class="cx"> #if USE(CG) &amp;&amp; !USE(WEBKIT_IMAGE_DECODERS)
</span><del>-    else if (m_response.mimeType() == &quot;application/pdf&quot;)
-        m_image = PDFDocumentImage::create(this);
</del><ins>+    } else if (m_response.mimeType() == &quot;application/pdf&quot;) {
+        m_image = PDFDocumentImage::create(m_imageObserver.get());
</ins><span class="cx"> #endif
</span><del>-    else if (m_response.mimeType() == &quot;image/svg+xml&quot;) {
-        auto svgImage = SVGImage::create(*this, url());
-        m_svgImageCache = std::make_unique&lt;SVGImageCache&gt;(svgImage.ptr());
-        m_image = WTFMove(svgImage);
</del><span class="cx">     } else
</span><del>-        m_image = BitmapImage::create(this);
</del><ins>+        m_image = BitmapImage::create(m_imageObserver.get());
</ins><span class="cx"> 
</span><span class="cx">     if (m_image) {
</span><span class="cx">         // Send queued container size requests.
</span><span class="lines">@@ -345,12 +343,48 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+CachedImage::CachedImageObserver::CachedImageObserver(CachedImage&amp; image)
+{
+    m_cachedImages.reserveInitialCapacity(1);
+    m_cachedImages.append(&amp;image);
+    if (auto* loader = image.loader()) {
+        m_allowSubsampling = loader-&gt;frameLoader()-&gt;frame().settings().imageSubsamplingEnabled();
+        m_allowLargeImageAsyncDecoding = loader-&gt;frameLoader()-&gt;frame().settings().largeImageAsyncDecodingEnabled();
+        m_allowAnimatedImageAsyncDecoding = loader-&gt;frameLoader()-&gt;frame().settings().animatedImageAsyncDecodingEnabled();
+        m_showDebugBackground = loader-&gt;frameLoader()-&gt;frame().settings().showDebugBorders();
+    }
+}
+
+void CachedImage::CachedImageObserver::decodedSizeChanged(const Image* image, long long delta)
+{
+    for (auto cachedImage : m_cachedImages)
+        cachedImage-&gt;decodedSizeChanged(image, delta);
+}
+
+void CachedImage::CachedImageObserver::didDraw(const Image* image)
+{
+    for (auto cachedImage : m_cachedImages)
+        cachedImage-&gt;didDraw(image);
+}
+
+void CachedImage::CachedImageObserver::animationAdvanced(const Image* image)
+{
+    for (auto cachedImage : m_cachedImages)
+        cachedImage-&gt;animationAdvanced(image);
+}
+
+void CachedImage::CachedImageObserver::changedInRect(const Image* image, const IntRect* rect)
+{
+    for (auto cachedImage : m_cachedImages)
+        cachedImage-&gt;changedInRect(image, rect);
+}
+
</ins><span class="cx"> inline void CachedImage::clearImage()
</span><span class="cx"> {
</span><del>-    // If our Image has an observer, it's always us so we need to clear the back pointer
-    // before dropping our reference.
-    if (m_image)
-        m_image-&gt;setImageObserver(nullptr);
</del><ins>+    if (m_imageObserver) {
+        m_imageObserver-&gt;remove(*this);
+        m_imageObserver = nullptr;
+    }
</ins><span class="cx">     m_image = nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedImageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedImage.h (209913 => 209914)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedImage.h        2016-12-16 07:12:23 UTC (rev 209913)
+++ trunk/Source/WebCore/loader/cache/CachedImage.h        2016-12-16 08:42:29 UTC (rev 209914)
</span><span class="lines">@@ -43,7 +43,7 @@
</span><span class="cx"> 
</span><span class="cx"> struct Length;
</span><span class="cx"> 
</span><del>-class CachedImage final : public CachedResource, public ImageObserver {
</del><ins>+class CachedImage final : public CachedResource {
</ins><span class="cx">     friend class MemoryCache;
</span><span class="cx"> 
</span><span class="cx"> public:
</span><span class="lines">@@ -116,17 +116,43 @@
</span><span class="cx"> 
</span><span class="cx">     bool stillNeedsLoad() const override { return !errorOccurred() &amp;&amp; status() == Unknown &amp;&amp; !isLoading(); }
</span><span class="cx"> 
</span><del>-    // ImageObserver
-    bool allowSubsampling() const override { return m_allowSubsampling; }
-    bool allowLargeImageAsyncDecoding() const override { return m_allowLargeImageAsyncDecoding; }
-    bool allowAnimatedImageAsyncDecoding() const override { return m_allowAnimatedImageAsyncDecoding; }
-    bool showDebugBackground() const override { return m_showDebugBackground; }
-    void decodedSizeChanged(const Image*, long long delta) override;
-    void didDraw(const Image*) override;
</del><ins>+    class CachedImageObserver final : public RefCounted&lt;CachedImageObserver&gt;, public ImageObserver {
+    public:
+        static Ref&lt;CachedImageObserver&gt; create(CachedImage&amp; image) { return adoptRef(*new CachedImageObserver(image)); }
+        void add(CachedImage&amp; image) { m_cachedImages.append(&amp;image); }
+        void remove(CachedImage&amp; image) { m_cachedImages.removeFirst(&amp;image); }
</ins><span class="cx"> 
</span><del>-    void animationAdvanced(const Image*) override;
-    void changedInRect(const Image*, const IntRect* changeRect = nullptr) override;
</del><ins>+    private:
+        explicit CachedImageObserver(CachedImage&amp;);
</ins><span class="cx"> 
</span><ins>+        // ImageObserver API
+        bool allowSubsampling() const final { return m_allowSubsampling; }
+        bool allowLargeImageAsyncDecoding() const override { return m_allowLargeImageAsyncDecoding; }
+        bool allowAnimatedImageAsyncDecoding() const override { return m_allowAnimatedImageAsyncDecoding; }
+        bool showDebugBackground() const final { return m_showDebugBackground; }
+        void decodedSizeChanged(const Image*, long long delta) final;
+        void didDraw(const Image*) final;
+
+        void animationAdvanced(const Image*) final;
+        void changedInRect(const Image*, const IntRect*) final;
+
+        Vector&lt;CachedImage*&gt; m_cachedImages;
+        // The default value of m_allowSubsampling should be the same as defaultImageSubsamplingEnabled in Settings.cpp
+#if PLATFORM(IOS)
+        bool m_allowSubsampling { true };
+#else
+        bool m_allowSubsampling { false };
+#endif
+        bool m_allowLargeImageAsyncDecoding { true };
+        bool m_allowAnimatedImageAsyncDecoding { true };
+        bool m_showDebugBackground { false };
+    };
+
+    void decodedSizeChanged(const Image*, long long delta);
+    void didDraw(const Image*);
+    void animationAdvanced(const Image*);
+    void changedInRect(const Image*, const IntRect*);
+
</ins><span class="cx">     void addIncrementalDataBuffer(SharedBuffer&amp;);
</span><span class="cx"> 
</span><span class="cx">     void didReplaceSharedBufferContents() override;
</span><span class="lines">@@ -135,20 +161,11 @@
</span><span class="cx">     typedef HashMap&lt;const CachedImageClient*, SizeAndZoom&gt; ContainerSizeRequests;
</span><span class="cx">     ContainerSizeRequests m_pendingContainerSizeRequests;
</span><span class="cx"> 
</span><ins>+    RefPtr&lt;CachedImageObserver&gt; m_imageObserver;
</ins><span class="cx">     RefPtr&lt;Image&gt; m_image;
</span><span class="cx">     std::unique_ptr&lt;SVGImageCache&gt; m_svgImageCache;
</span><span class="cx">     bool m_isManuallyCached { false };
</span><span class="cx">     bool m_shouldPaintBrokenImage { true };
</span><del>-
-    // The default value of m_allowSubsampling should be the same as defaultImageSubsamplingEnabled in Settings.cpp
-#if PLATFORM(IOS)
-    bool m_allowSubsampling { true };
-#else
-    bool m_allowSubsampling { false };
-#endif
-    bool m_allowLargeImageAsyncDecoding { true };
-    bool m_allowAnimatedImageAsyncDecoding { true };
-    bool m_showDebugBackground { false };
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedResourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedResource.cpp (209913 => 209914)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedResource.cpp        2016-12-16 07:12:23 UTC (rev 209913)
+++ trunk/Source/WebCore/loader/cache/CachedResource.cpp        2016-12-16 08:42:29 UTC (rev 209914)
</span><span class="lines">@@ -297,6 +297,7 @@
</span><span class="cx"> void CachedResource::setBodyDataFrom(const CachedResource&amp; resource)
</span><span class="cx"> {
</span><span class="cx">     m_data = resource.m_data;
</span><ins>+    setDecodedSize(resource.decodedSize());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CachedResource::checkNotify()
</span></span></pre>
</div>
</div>

</body>
</html>