<!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>[174454] releases/WebKitGTK/webkit-2.6</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/174454">174454</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2014-10-08 08:16:23 -0700 (Wed, 08 Oct 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/174190">r174190</a> - Add basic caching for Document.cookie API
https://bugs.webkit.org/show_bug.cgi?id=137225

Reviewed by Alexey Proskuryakov.

Source/WebCore:

While profiling the load of nytimes.com, I noticed that the site is
accessing ~250 times document.cookie, just during page load. Accessing
document.cookie is currently slow because we:
- Call WebPlatformStrategies::cookiesForDOM() virtual function
- Send a sync IPC message to the Network process to retrieve the
  cookies
    - The Network process gets the list of cookies from CFNetwork then
      serializes the result to send it back to the WebProcess
- We unserialize the cookies into an NSList of cookies
- We filter-out the cookies that are 'httpOnly' and construct a new
  NSList of cookies
- We create a WTF String out of the cookies NSList

In the case of nytimes.com, it turns out that up to 100 calls to
document.cookie() are made in the same event loop iteration. This patch
thus caches / freezes the cookies until we return to the event
loop so that consecutive calls to document.cookie() are extremely fast.
Doing so seems to be sufficient to achieve a ~87% cache hit for
nytimes.com page load.

The cookies cache is invalidated whenever:
- document.cookie is set
- we return to the event loop
- a network resource is loaded synchronously as it may cause cookies to
  be set before we return to the event loop

Test: http/tests/cookies/sync-xhr-set-cookie-invalidates-cache.html

* dom/Document.cpp:
(WebCore::Document::Document):
(WebCore::Document::open):
(WebCore::Document::cookie):
(WebCore::Document::setCookie):
(WebCore::Document::setCookieURL):
(WebCore::Document::initSecurityContext):
(WebCore::Document::setDOMCookieCache):
(WebCore::Document::invalidateDOMCookieCache):
(WebCore::Document::domCookieCacheExpiryTimerFired):
(WebCore::Document::didLoadResourceSynchronously):
* dom/Document.h:
(WebCore::Document::domCookieCache):
(WebCore::Document::isDOMCookieCacheValid):
(WebCore::Document::setCookieURL): Deleted.
* dom/ScriptExecutionContext.cpp:
(WebCore::ScriptExecutionContext::didLoadResourceSynchronously):
* dom/ScriptExecutionContext.h:
* loader/ThreadableLoader.cpp:
(WebCore::ThreadableLoader::loadResourceSynchronously):

LayoutTests:

Add a layout test to make sure that document.cookie returns updated
results after cookies are set via a sync XHR.

* http/tests/cookies/sync-xhr-set-cookie-invalidates-cache-expected.txt: Added.
* http/tests/cookies/sync-xhr-set-cookie-invalidates-cache.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit26LayoutTestsChangeLog">releases/WebKitGTK/webkit-2.6/LayoutTests/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit26LayoutTestshttptestscookiesresourcescookiestestprejs">releases/WebKitGTK/webkit-2.6/LayoutTests/http/tests/cookies/resources/cookies-test-pre.js</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCoreChangeLog">releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCoredomDocumentcpp">releases/WebKitGTK/webkit-2.6/Source/WebCore/dom/Document.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCoredomDocumenth">releases/WebKitGTK/webkit-2.6/Source/WebCore/dom/Document.h</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCoredomScriptExecutionContextcpp">releases/WebKitGTK/webkit-2.6/Source/WebCore/dom/ScriptExecutionContext.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCoredomScriptExecutionContexth">releases/WebKitGTK/webkit-2.6/Source/WebCore/dom/ScriptExecutionContext.h</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCoreloaderThreadableLoadercpp">releases/WebKitGTK/webkit-2.6/Source/WebCore/loader/ThreadableLoader.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit26LayoutTestshttptestscookiessyncxhrsetcookieinvalidatescacheexpectedtxt">releases/WebKitGTK/webkit-2.6/LayoutTests/http/tests/cookies/sync-xhr-set-cookie-invalidates-cache-expected.txt</a></li>
<li><a href="#releasesWebKitGTKwebkit26LayoutTestshttptestscookiessyncxhrsetcookieinvalidatescachehtml">releases/WebKitGTK/webkit-2.6/LayoutTests/http/tests/cookies/sync-xhr-set-cookie-invalidates-cache.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit26LayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/LayoutTests/ChangeLog (174453 => 174454)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/LayoutTests/ChangeLog        2014-10-08 14:44:56 UTC (rev 174453)
+++ releases/WebKitGTK/webkit-2.6/LayoutTests/ChangeLog        2014-10-08 15:16:23 UTC (rev 174454)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2014-10-01  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        Add basic caching for Document.cookie API
+        https://bugs.webkit.org/show_bug.cgi?id=137225
+
+        Reviewed by Alexey Proskuryakov.
+
+        Add a layout test to make sure that document.cookie returns updated
+        results after cookies are set via a sync XHR.
+
+        * http/tests/cookies/sync-xhr-set-cookie-invalidates-cache-expected.txt: Added.
+        * http/tests/cookies/sync-xhr-set-cookie-invalidates-cache.html: Added.
+
</ins><span class="cx"> 2014-09-30  Said Abou-Hallawa  &lt;sabouhallawa@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Stack overflow with enormous SVG filter.
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26LayoutTestshttptestscookiesresourcescookiestestprejs"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/LayoutTests/http/tests/cookies/resources/cookies-test-pre.js (174453 => 174454)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/LayoutTests/http/tests/cookies/resources/cookies-test-pre.js        2014-10-08 14:44:56 UTC (rev 174453)
+++ releases/WebKitGTK/webkit-2.6/LayoutTests/http/tests/cookies/resources/cookies-test-pre.js        2014-10-08 15:16:23 UTC (rev 174454)
</span><span class="lines">@@ -23,6 +23,11 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+function registerCookieForCleanup(cookie)
+{
+    cookies.push(cookie);
+}
+
</ins><span class="cx"> // Normalize a cookie string
</span><span class="cx"> function normalizeCookie(cookie)
</span><span class="cx"> {
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26LayoutTestshttptestscookiessyncxhrsetcookieinvalidatescacheexpectedtxt"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.6/LayoutTests/http/tests/cookies/sync-xhr-set-cookie-invalidates-cache-expected.txt (0 => 174454)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/LayoutTests/http/tests/cookies/sync-xhr-set-cookie-invalidates-cache-expected.txt                                (rev 0)
+++ releases/WebKitGTK/webkit-2.6/LayoutTests/http/tests/cookies/sync-xhr-set-cookie-invalidates-cache-expected.txt        2014-10-08 15:16:23 UTC (rev 174454)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+Tests that document.cookie returns the right value after a sync XHR
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS normalizeCookie(document.cookie) is &quot;testKey=testValue&quot;
+PASS xhr.status is 200
+PASS normalizeCookie(document.cookie) is &quot;testKey=testValue; xhrKey=xhrValue&quot;
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit26LayoutTestshttptestscookiessyncxhrsetcookieinvalidatescachehtml"></a>
<div class="addfile"><h4>Added: releases/WebKitGTK/webkit-2.6/LayoutTests/http/tests/cookies/sync-xhr-set-cookie-invalidates-cache.html (0 => 174454)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/LayoutTests/http/tests/cookies/sync-xhr-set-cookie-invalidates-cache.html                                (rev 0)
+++ releases/WebKitGTK/webkit-2.6/LayoutTests/http/tests/cookies/sync-xhr-set-cookie-invalidates-cache.html        2014-10-08 15:16:23 UTC (rev 174454)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;script src='resources/cookies-test-pre.js'&gt;&lt;/script&gt;
+
+&lt;script&gt;
+description('Tests that document.cookie returns the right value after a sync XHR');
+
+document.cookie = &quot;testKey=testValue&quot;;
+shouldBeEqualToString('normalizeCookie(document.cookie)', 'testKey=testValue');
+var xhr = new XMLHttpRequest();
+xhr.open('GET', 'resources/setCookies.cgi', false);
+var cookie = 'xhrKey=xhrValue; path=/';
+xhr.setRequestHeader('SET-COOKIE', cookie);
+xhr.send();
+
+// This is so the cookie gets removed at the end of the test.
+registerCookieForCleanup(cookie);
+
+shouldBe('xhr.status', '200');
+shouldBeEqualToString('normalizeCookie(document.cookie)', 'testKey=testValue; xhrKey=xhrValue');
+
+&lt;/script&gt;
+&lt;script src='resources/cookies-test-post.js'&gt;&lt;/script&gt;
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog (174453 => 174454)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog        2014-10-08 14:44:56 UTC (rev 174453)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog        2014-10-08 15:16:23 UTC (rev 174454)
</span><span class="lines">@@ -1,3 +1,59 @@
</span><ins>+2014-10-01  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        Add basic caching for Document.cookie API
+        https://bugs.webkit.org/show_bug.cgi?id=137225
+
+        Reviewed by Alexey Proskuryakov.
+
+        While profiling the load of nytimes.com, I noticed that the site is
+        accessing ~250 times document.cookie, just during page load. Accessing
+        document.cookie is currently slow because we:
+        - Call WebPlatformStrategies::cookiesForDOM() virtual function
+        - Send a sync IPC message to the Network process to retrieve the
+          cookies
+            - The Network process gets the list of cookies from CFNetwork then
+              serializes the result to send it back to the WebProcess
+        - We unserialize the cookies into an NSList of cookies
+        - We filter-out the cookies that are 'httpOnly' and construct a new
+          NSList of cookies
+        - We create a WTF String out of the cookies NSList
+
+        In the case of nytimes.com, it turns out that up to 100 calls to
+        document.cookie() are made in the same event loop iteration. This patch
+        thus caches / freezes the cookies until we return to the event
+        loop so that consecutive calls to document.cookie() are extremely fast.
+        Doing so seems to be sufficient to achieve a ~87% cache hit for
+        nytimes.com page load.
+
+        The cookies cache is invalidated whenever:
+        - document.cookie is set
+        - we return to the event loop
+        - a network resource is loaded synchronously as it may cause cookies to
+          be set before we return to the event loop
+
+        Test: http/tests/cookies/sync-xhr-set-cookie-invalidates-cache.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::Document):
+        (WebCore::Document::open):
+        (WebCore::Document::cookie):
+        (WebCore::Document::setCookie):
+        (WebCore::Document::setCookieURL):
+        (WebCore::Document::initSecurityContext):
+        (WebCore::Document::setDOMCookieCache):
+        (WebCore::Document::invalidateDOMCookieCache):
+        (WebCore::Document::domCookieCacheExpiryTimerFired):
+        (WebCore::Document::didLoadResourceSynchronously):
+        * dom/Document.h:
+        (WebCore::Document::domCookieCache):
+        (WebCore::Document::isDOMCookieCacheValid):
+        (WebCore::Document::setCookieURL): Deleted.
+        * dom/ScriptExecutionContext.cpp:
+        (WebCore::ScriptExecutionContext::didLoadResourceSynchronously):
+        * dom/ScriptExecutionContext.h:
+        * loader/ThreadableLoader.cpp:
+        (WebCore::ThreadableLoader::loadResourceSynchronously):
+
</ins><span class="cx"> 2014-09-30  Said Abou-Hallawa  &lt;sabouhallawa@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Stack overflow with enormous SVG filter
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCoredomDocumentcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/dom/Document.cpp (174453 => 174454)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/dom/Document.cpp        2014-10-08 14:44:56 UTC (rev 174453)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/dom/Document.cpp        2014-10-08 15:16:23 UTC (rev 174454)
</span><span class="lines">@@ -513,6 +513,7 @@
</span><span class="cx">     , m_inputCursor(EmptyInputCursor::create())
</span><span class="cx"> #endif
</span><span class="cx">     , m_didAssociateFormControlsTimer(this, &amp;Document::didAssociateFormControlsTimerFired)
</span><ins>+    , m_cookieCacheExpiryTimer(this, &amp;Document::domCookieCacheExpiryTimerFired)
</ins><span class="cx">     , m_disabledFieldsetElementsCount(0)
</span><span class="cx">     , m_hasInjectedPlugInsScript(false)
</span><span class="cx">     , m_renderTreeBeingDestroyed(false)
</span><span class="lines">@@ -2212,7 +2213,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (ownerDocument) {
</span><span class="cx">         setURL(ownerDocument-&gt;url());
</span><del>-        m_cookieURL = ownerDocument-&gt;cookieURL();
</del><ins>+        setCookieURL(ownerDocument-&gt;cookieURL());
</ins><span class="cx">         setSecurityOrigin(ownerDocument-&gt;securityOrigin());
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -3791,7 +3792,7 @@
</span><span class="cx">     return frame()-&gt;ownerElement();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-String Document::cookie(ExceptionCode&amp; ec) const
</del><ins>+String Document::cookie(ExceptionCode&amp; ec)
</ins><span class="cx"> {
</span><span class="cx">     if (page() &amp;&amp; !page()-&gt;settings().cookieEnabled())
</span><span class="cx">         return String();
</span><span class="lines">@@ -3809,7 +3810,10 @@
</span><span class="cx">     if (cookieURL.isEmpty())
</span><span class="cx">         return String();
</span><span class="cx"> 
</span><del>-    return cookies(this, cookieURL);
</del><ins>+    if (!isDOMCookieCacheValid())
+        setCachedDOMCookies(cookies(this, cookieURL));
+
+    return cachedDOMCookies();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Document::setCookie(const String&amp; value, ExceptionCode&amp; ec)
</span><span class="lines">@@ -3830,6 +3834,7 @@
</span><span class="cx">     if (cookieURL.isEmpty())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    invalidateDOMCookieCache();
</ins><span class="cx">     setCookies(this, cookieURL, value);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -3933,6 +3938,14 @@
</span><span class="cx">     return String::format(&quot;%02d/%02d/%04d %02d:%02d:%02d&quot;, date.month() + 1, date.monthDay(), date.fullYear(), date.hour(), date.minute(), date.second());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Document::setCookieURL(const URL&amp; url)
+{
+    if (m_cookieURL == url)
+        return;
+    m_cookieURL = url;
+    invalidateDOMCookieCache();
+}
+
</ins><span class="cx"> static bool isValidNameNonASCII(const LChar* characters, unsigned length)
</span><span class="cx"> {
</span><span class="cx">     if (!isValidNameStart(characters[0]))
</span><span class="lines">@@ -4645,7 +4658,7 @@
</span><span class="cx">     if (!m_frame) {
</span><span class="cx">         // No source for a security context.
</span><span class="cx">         // This can occur via document.implementation.createDocument().
</span><del>-        m_cookieURL = URL(ParsedURLString, emptyString());
</del><ins>+        setCookieURL(URL(ParsedURLString, emptyString()));
</ins><span class="cx">         setSecurityOrigin(SecurityOrigin::createUnique());
</span><span class="cx">         setContentSecurityPolicy(std::make_unique&lt;ContentSecurityPolicy&gt;(this));
</span><span class="cx">         return;
</span><span class="lines">@@ -4653,7 +4666,7 @@
</span><span class="cx"> 
</span><span class="cx">     // In the common case, create the security context from the currently
</span><span class="cx">     // loading URL with a fresh content security policy.
</span><del>-    m_cookieURL = m_url;
</del><ins>+    setCookieURL(m_url);
</ins><span class="cx">     enforceSandboxFlags(m_frame-&gt;loader().effectiveSandboxFlags());
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="lines">@@ -4719,7 +4732,7 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_cookieURL = ownerFrame-&gt;document()-&gt;cookieURL();
</del><ins>+    setCookieURL(ownerFrame-&gt;document()-&gt;cookieURL());
</ins><span class="cx">     // We alias the SecurityOrigins to match Firefox, see Bug 15313
</span><span class="cx">     // https://bugs.webkit.org/show_bug.cgi?id=15313
</span><span class="cx">     setSecurityOrigin(ownerFrame-&gt;document()-&gt;securityOrigin());
</span><span class="lines">@@ -6137,6 +6150,32 @@
</span><span class="cx">     m_associatedFormControls.clear();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Document::setCachedDOMCookies(const String&amp; cookies)
+{
+    ASSERT(!isDOMCookieCacheValid());
+    m_cachedDOMCookies = cookies;
+    // The cookie cache is valid at most until we go back to the event loop.
+    m_cookieCacheExpiryTimer.startOneShot(0);
+}
+
+void Document::invalidateDOMCookieCache()
+{
+    m_cookieCacheExpiryTimer.stop();
+    m_cachedDOMCookies = String();
+}
+
+void Document::domCookieCacheExpiryTimerFired(Timer&lt;Document&gt;&amp;)
+{
+    invalidateDOMCookieCache();
+}
+
+void Document::didLoadResourceSynchronously(const ResourceRequest&amp;)
+{
+    // Synchronous resources loading can set cookies so we invalidate the cookies cache
+    // in this case, to be safe.
+    invalidateDOMCookieCache();
+}
+
</ins><span class="cx"> void Document::ensurePlugInsInjectedScript(DOMWrapperWorld&amp; world)
</span><span class="cx"> {
</span><span class="cx">     if (m_hasInjectedPlugInsScript)
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCoredomDocumenth"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/dom/Document.h (174453 => 174454)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/dom/Document.h        2014-10-08 14:44:56 UTC (rev 174453)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/dom/Document.h        2014-10-08 15:16:23 UTC (rev 174454)
</span><span class="lines">@@ -881,7 +881,7 @@
</span><span class="cx">     void setTitleElement(const StringWithDirection&amp;, Element* titleElement);
</span><span class="cx">     void removeTitle(Element* titleElement);
</span><span class="cx"> 
</span><del>-    String cookie(ExceptionCode&amp;) const;
</del><ins>+    String cookie(ExceptionCode&amp;);
</ins><span class="cx">     void setCookie(const String&amp;, ExceptionCode&amp;);
</span><span class="cx"> 
</span><span class="cx">     String referrer() const;
</span><span class="lines">@@ -904,7 +904,7 @@
</span><span class="cx">     //    inherits its cookieURL but not its URL.
</span><span class="cx">     //
</span><span class="cx">     const URL&amp; cookieURL() const { return m_cookieURL; }
</span><del>-    void setCookieURL(const URL&amp; url) { m_cookieURL = url; }
</del><ins>+    void setCookieURL(const URL&amp;);
</ins><span class="cx"> 
</span><span class="cx">     // The firstPartyForCookies is used to compute whether this document
</span><span class="cx">     // appears in a &quot;third-party&quot; context for the purpose of third-party
</span><span class="lines">@@ -1362,6 +1362,14 @@
</span><span class="cx"> 
</span><span class="cx">     void didAssociateFormControlsTimerFired(Timer&lt;Document&gt;&amp;);
</span><span class="cx"> 
</span><ins>+    // DOM Cookies caching.
+    const String&amp; cachedDOMCookies() const { return m_cachedDOMCookies; }
+    void setCachedDOMCookies(const String&amp;);
+    bool isDOMCookieCacheValid() const { return m_cookieCacheExpiryTimer.isActive(); }
+    void invalidateDOMCookieCache();
+    void domCookieCacheExpiryTimerFired(Timer&lt;Document&gt;&amp;);
+    void didLoadResourceSynchronously(const ResourceRequest&amp;) override final;
+
</ins><span class="cx">     unsigned m_referencingNodeCount;
</span><span class="cx"> 
</span><span class="cx">     std::unique_ptr&lt;StyleResolver&gt; m_styleResolver;
</span><span class="lines">@@ -1694,6 +1702,8 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     Timer&lt;Document&gt; m_didAssociateFormControlsTimer;
</span><ins>+    Timer&lt;Document&gt; m_cookieCacheExpiryTimer;
+    String m_cachedDOMCookies;
</ins><span class="cx">     HashSet&lt;RefPtr&lt;Element&gt;&gt; m_associatedFormControls;
</span><span class="cx">     unsigned m_disabledFieldsetElementsCount;
</span><span class="cx"> 
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCoredomScriptExecutionContextcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/dom/ScriptExecutionContext.cpp (174453 => 174454)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/dom/ScriptExecutionContext.cpp        2014-10-08 14:44:56 UTC (rev 174453)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/dom/ScriptExecutionContext.cpp        2014-10-08 15:16:23 UTC (rev 174454)
</span><span class="lines">@@ -172,6 +172,10 @@
</span><span class="cx">     m_messagePorts.remove(&amp;messagePort);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ScriptExecutionContext::didLoadResourceSynchronously(const ResourceRequest&amp;)
+{
+}
+
</ins><span class="cx"> bool ScriptExecutionContext::canSuspendActiveDOMObjects()
</span><span class="cx"> {
</span><span class="cx">     checkConsistency();
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCoredomScriptExecutionContexth"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/dom/ScriptExecutionContext.h (174453 => 174454)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/dom/ScriptExecutionContext.h        2014-10-08 14:44:56 UTC (rev 174453)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/dom/ScriptExecutionContext.h        2014-10-08 15:16:23 UTC (rev 174454)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ActiveDOMObject.h&quot;
</span><span class="cx"> #include &quot;DOMTimer.h&quot;
</span><ins>+#include &quot;ResourceRequest.h&quot;
</ins><span class="cx"> #include &quot;ScheduledAction.h&quot;
</span><span class="cx"> #include &quot;SecurityContext.h&quot;
</span><span class="cx"> #include &quot;Supplementable.h&quot;
</span><span class="lines">@@ -110,6 +111,8 @@
</span><span class="cx">     void createdMessagePort(MessagePort&amp;);
</span><span class="cx">     void destroyedMessagePort(MessagePort&amp;);
</span><span class="cx"> 
</span><ins>+    virtual void didLoadResourceSynchronously(const ResourceRequest&amp;);
+
</ins><span class="cx">     void ref() { refScriptExecutionContext(); }
</span><span class="cx">     void deref() { derefScriptExecutionContext(); }
</span><span class="cx"> 
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCoreloaderThreadableLoadercpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/loader/ThreadableLoader.cpp (174453 => 174454)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/loader/ThreadableLoader.cpp        2014-10-08 14:44:56 UTC (rev 174453)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/loader/ThreadableLoader.cpp        2014-10-08 15:16:23 UTC (rev 174454)
</span><span class="lines">@@ -66,12 +66,11 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(context);
</span><span class="cx"> 
</span><del>-    if (context-&gt;isWorkerGlobalScope()) {
</del><ins>+    if (context-&gt;isWorkerGlobalScope())
</ins><span class="cx">         WorkerThreadableLoader::loadResourceSynchronously(toWorkerGlobalScope(context), request, client, options);
</span><del>-        return;
-    }
-
-    DocumentThreadableLoader::loadResourceSynchronously(*toDocument(context), request, client, options);
</del><ins>+    else
+        DocumentThreadableLoader::loadResourceSynchronously(*toDocument(context), request, client, options);
+    context-&gt;didLoadResourceSynchronously(request);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre>
</div>
</div>

</body>
</html>