<!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>[175231] trunk/Source</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/175231">175231</a></dd>
<dt>Author</dt> <dd>cdumez@apple.com</dd>
<dt>Date</dt> <dd>2014-10-27 14:08:51 -0700 (Mon, 27 Oct 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Use separate HashMaps for common and uncommon headers in HTTPHeaderMap
https://bugs.webkit.org/show_bug.cgi?id=138079

Reviewed by Anders Carlsson.

Source/WebCore:

Use separate HashMaps for common and uncommon headers in HTTPHeaderMap:
- a (faster) HashMap&lt;HTTPHeaderMap, String&gt; for common HTTP headers
- a HashMap&lt;String, String, CaseFoldingHash&gt; for uncommon ones

This avoids having to construct Strings from HTTPHeaderMap values for
storing. This also means we have less isolated String copies to do when
creating cross-thread data. The common headers HashMap should also be
a bit more efficient due to faster hashing and faster key comparison in
case of collision.

Some calls sites can also benefit from having direct access to common
headers of the request in HTTPHeaderName type.

This patch adds a new HTTPHeaderMapConstIterator iterator type for
HTTPHeaderMap so that call sites that do not need / want to distinguish
common / uncommon headers still do not need to. They can keep using
modern C++ loops over HTTPHeaderMap objects and get &lt;String, String&gt;
key/value pairs.

No new tests, no behavior change.

* loader/CrossOriginAccessControl.cpp:
(WebCore::isOnAccessControlSimpleRequestHeaderWhitelist):
Have isOnAccessControlSimpleRequestHeaderWhitelist() take a
HTTPHeaderName in argument instead of a String as only common headers
are in the whitelist.

(WebCore::isSimpleCrossOriginAccessRequest):
Call isOnAccessControlSimpleRequestHeaderWhitelist() only for common
HTTP headers.

* loader/CrossOriginAccessControl.h:
Have isOnAccessControlSimpleRequestHeaderWhitelist() take a
HTTPHeaderName in argument instead of a String as only common headers
are in the whitelist.

* loader/CrossOriginPreflightResultCache.cpp:
(WebCore::CrossOriginPreflightResultCacheItem::allowsCrossOriginHeaders):
Call isOnAccessControlSimpleRequestHeaderWhitelist() only for common
HTTP headers.

* loader/DocumentLoader.cpp:
(WebCore::DocumentLoader::responseReceived):
Call httpHeaderFields().commonHeaders().find() instead of
httpHeaderFields().find() as we are looking for a common header.
HTTPHeaderMap::find(HTTPHeaderName) was removed now that we have a
HashMap dedicated to common headers.

* loader/cache/CachedRawResource.cpp:
(WebCore::shouldIgnoreHeaderForCacheReuse):
Update argument type to be a HTTPHeaderName instead of a String as
only common HTTP headers can be ignored for cache reuse. The
implementation already dealt with HTTPHeaderName type and had to
call findHTTPHeaderName(). This is no longer needed now that the
call site now has direct access to common headers in HTTPHeaderName
type.

(WebCore::CachedRawResource::canReuse):
- Only call shouldIgnoreHeaderForCacheReuse() for common HTTP headers.
- Slightly optimize the second loop (the one over oldHeaderMap) to only
  check that the key is present in newHeaderMap, without actually
  comparing the String values. If the String values were different, the
  first loop would have seen it already and we would have returned
  early.

Source/WebKit2:

Update the WK2 IPC HTTPHeaderMap serialization / deserialization code
to leverage the fact that HTTPHeaderMap now stores common HTTP headers
and uncommon one in separate HashMaps. This speeds up deserialization
as we no longer need to call findHTTPHeaderName() for every decoded
header. We already know if the header is a common one or not, and if
it is then we already have a HTTPHeaderName type instead of a String.

I see that we spend ~40% less time in HTTPHeaderMap decoding when
loading http://flickr.com/explore, while the encoding takes about
the same amount of time as before.

* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder&lt;HTTPHeaderMap&gt;::encode):
(IPC::ArgumentCoder&lt;HTTPHeaderMap&gt;::decode):

Source/WTF:

Add HashTraits for C++11 strong enum types. Using integer HashTraits for
strong enums would be inconvenient as it would require casting between
integer and strong enum types.

* wtf/HashTraits.h:
(WTF::StrongEnumHashTraits::emptyValue):
(WTF::StrongEnumHashTraits::constructDeletedValue):
(WTF::StrongEnumHashTraits::isDeletedValue):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfHashTraitsh">trunk/Source/WTF/wtf/HashTraits.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCoreexpin">trunk/Source/WebCore/WebCore.exp.in</a></li>
<li><a href="#trunkSourceWebCoreloaderCrossOriginAccessControlcpp">trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderCrossOriginAccessControlh">trunk/Source/WebCore/loader/CrossOriginAccessControl.h</a></li>
<li><a href="#trunkSourceWebCoreloaderCrossOriginPreflightResultCachecpp">trunk/Source/WebCore/loader/CrossOriginPreflightResultCache.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderDocumentLoadercpp">trunk/Source/WebCore/loader/DocumentLoader.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedRawResourcecpp">trunk/Source/WebCore/loader/cache/CachedRawResource.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkHTTPHeaderMapcpp">trunk/Source/WebCore/platform/network/HTTPHeaderMap.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkHTTPHeaderMaph">trunk/Source/WebCore/platform/network/HTTPHeaderMap.h</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2SharedWebCoreArgumentCoderscpp">trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (175230 => 175231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2014-10-27 20:42:47 UTC (rev 175230)
+++ trunk/Source/WTF/ChangeLog        2014-10-27 21:08:51 UTC (rev 175231)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2014-10-27  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        Use separate HashMaps for common and uncommon headers in HTTPHeaderMap
+        https://bugs.webkit.org/show_bug.cgi?id=138079
+
+        Reviewed by Anders Carlsson.
+
+        Add HashTraits for C++11 strong enum types. Using integer HashTraits for
+        strong enums would be inconvenient as it would require casting between
+        integer and strong enum types.
+
+        * wtf/HashTraits.h:
+        (WTF::StrongEnumHashTraits::emptyValue):
+        (WTF::StrongEnumHashTraits::constructDeletedValue):
+        (WTF::StrongEnumHashTraits::isDeletedValue):
+
</ins><span class="cx"> 2014-10-25  Brian J. Burg  &lt;burg@cs.washington.edu&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: timelines should not count time elapsed while paused in the debugger
</span></span></pre></div>
<a id="trunkSourceWTFwtfHashTraitsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/HashTraits.h (175230 => 175231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/HashTraits.h        2014-10-27 20:42:47 UTC (rev 175230)
+++ trunk/Source/WTF/wtf/HashTraits.h        2014-10-27 21:08:51 UTC (rev 175231)
</span><span class="lines">@@ -88,6 +88,15 @@
</span><span class="cx">     static bool isDeletedValue(T value) { return value == std::numeric_limits&lt;T&gt;::max() - 1; }
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+// Can be used with strong enums, allows zero as key.
+template&lt;typename T&gt; struct StrongEnumHashTraits : GenericHashTraits&lt;T&gt; {
+    using UnderlyingType = typename std::underlying_type&lt;T&gt;::type;
+    static const bool emptyValueIsZero = false;
+    static T emptyValue() { return static_cast&lt;T&gt;(std::numeric_limits&lt;UnderlyingType&gt;::max()); }
+    static void constructDeletedValue(T&amp; slot) { slot = static_cast&lt;T&gt;(std::numeric_limits&lt;UnderlyingType&gt;::max() - 1); }
+    static bool isDeletedValue(T value) { return value == static_cast&lt;T&gt;(std::numeric_limits&lt;UnderlyingType&gt;::max() - 1); }
+};
+
</ins><span class="cx"> template&lt;typename P&gt; struct HashTraits&lt;P*&gt; : GenericHashTraits&lt;P*&gt; {
</span><span class="cx">     static const bool emptyValueIsZero = true;
</span><span class="cx">     static void constructDeletedValue(P*&amp; slot) { slot = reinterpret_cast&lt;P*&gt;(-1); }
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (175230 => 175231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-10-27 20:42:47 UTC (rev 175230)
+++ trunk/Source/WebCore/ChangeLog        2014-10-27 21:08:51 UTC (rev 175231)
</span><span class="lines">@@ -1,3 +1,75 @@
</span><ins>+2014-10-27  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        Use separate HashMaps for common and uncommon headers in HTTPHeaderMap
+        https://bugs.webkit.org/show_bug.cgi?id=138079
+
+        Reviewed by Anders Carlsson.
+
+        Use separate HashMaps for common and uncommon headers in HTTPHeaderMap:
+        - a (faster) HashMap&lt;HTTPHeaderMap, String&gt; for common HTTP headers
+        - a HashMap&lt;String, String, CaseFoldingHash&gt; for uncommon ones
+
+        This avoids having to construct Strings from HTTPHeaderMap values for
+        storing. This also means we have less isolated String copies to do when
+        creating cross-thread data. The common headers HashMap should also be
+        a bit more efficient due to faster hashing and faster key comparison in
+        case of collision.
+
+        Some calls sites can also benefit from having direct access to common
+        headers of the request in HTTPHeaderName type.
+
+        This patch adds a new HTTPHeaderMapConstIterator iterator type for
+        HTTPHeaderMap so that call sites that do not need / want to distinguish
+        common / uncommon headers still do not need to. They can keep using
+        modern C++ loops over HTTPHeaderMap objects and get &lt;String, String&gt;
+        key/value pairs.
+
+        No new tests, no behavior change.
+
+        * loader/CrossOriginAccessControl.cpp:
+        (WebCore::isOnAccessControlSimpleRequestHeaderWhitelist):
+        Have isOnAccessControlSimpleRequestHeaderWhitelist() take a
+        HTTPHeaderName in argument instead of a String as only common headers
+        are in the whitelist.
+
+        (WebCore::isSimpleCrossOriginAccessRequest):
+        Call isOnAccessControlSimpleRequestHeaderWhitelist() only for common
+        HTTP headers.
+
+        * loader/CrossOriginAccessControl.h:
+        Have isOnAccessControlSimpleRequestHeaderWhitelist() take a
+        HTTPHeaderName in argument instead of a String as only common headers
+        are in the whitelist.
+
+        * loader/CrossOriginPreflightResultCache.cpp:
+        (WebCore::CrossOriginPreflightResultCacheItem::allowsCrossOriginHeaders):
+        Call isOnAccessControlSimpleRequestHeaderWhitelist() only for common
+        HTTP headers.
+
+        * loader/DocumentLoader.cpp:
+        (WebCore::DocumentLoader::responseReceived):
+        Call httpHeaderFields().commonHeaders().find() instead of
+        httpHeaderFields().find() as we are looking for a common header.
+        HTTPHeaderMap::find(HTTPHeaderName) was removed now that we have a
+        HashMap dedicated to common headers.
+
+        * loader/cache/CachedRawResource.cpp:
+        (WebCore::shouldIgnoreHeaderForCacheReuse):
+        Update argument type to be a HTTPHeaderName instead of a String as
+        only common HTTP headers can be ignored for cache reuse. The
+        implementation already dealt with HTTPHeaderName type and had to
+        call findHTTPHeaderName(). This is no longer needed now that the
+        call site now has direct access to common headers in HTTPHeaderName
+        type.
+
+        (WebCore::CachedRawResource::canReuse):
+        - Only call shouldIgnoreHeaderForCacheReuse() for common HTTP headers.
+        - Slightly optimize the second loop (the one over oldHeaderMap) to only
+          check that the key is present in newHeaderMap, without actually
+          comparing the String values. If the String values were different, the
+          first loop would have seen it already and we would have returned
+          early.
+
</ins><span class="cx"> 2014-10-27  Andreas Kling  &lt;akling@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Devirtualize RenderDeprecatedFlexibleBox::isStretchingChildren().
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCoreexpin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.exp.in (175230 => 175231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.exp.in        2014-10-27 20:42:47 UTC (rev 175230)
+++ trunk/Source/WebCore/WebCore.exp.in        2014-10-27 21:08:51 UTC (rev 175231)
</span><span class="lines">@@ -894,6 +894,7 @@
</span><span class="cx"> __ZN7WebCore20UserGestureIndicatorC1ENS_26ProcessingUserGestureStateEPNS_8DocumentE
</span><span class="cx"> __ZN7WebCore20UserGestureIndicatorD1Ev
</span><span class="cx"> __ZN7WebCore20deleteEmptyDirectoryERKN3WTF6StringE
</span><ins>+__ZN7WebCore20httpHeaderNameStringENS_14HTTPHeaderNameE
</ins><span class="cx"> __ZN7WebCore20looksLikeAbsoluteURLEP8NSString
</span><span class="cx"> __ZN7WebCore20makeRGBA32FromFloatsEffff
</span><span class="cx"> __ZN7WebCore20previousLinePositionERKNS_15VisiblePositionEiNS_12EditableTypeE
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderCrossOriginAccessControlcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp (175230 => 175231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp        2014-10-27 20:42:47 UTC (rev 175230)
+++ trunk/Source/WebCore/loader/CrossOriginAccessControl.cpp        2014-10-27 21:08:51 UTC (rev 175231)
</span><span class="lines">@@ -44,24 +44,25 @@
</span><span class="cx">     return method == &quot;GET&quot; || method == &quot;HEAD&quot; || method == &quot;POST&quot;;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool isOnAccessControlSimpleRequestHeaderWhitelist(const String&amp; name, const String&amp; value)
</del><ins>+bool isOnAccessControlSimpleRequestHeaderWhitelist(HTTPHeaderName name, const String&amp; value)
</ins><span class="cx"> {
</span><del>-    if (equalIgnoringCase(name, &quot;accept&quot;)
-        || equalIgnoringCase(name, &quot;accept-language&quot;)
-        || equalIgnoringCase(name, &quot;content-language&quot;)
-        || equalIgnoringCase(name, &quot;origin&quot;)
-        || equalIgnoringCase(name, &quot;referer&quot;))
</del><ins>+    switch (name) {
+    case HTTPHeaderName::Accept:
+    case HTTPHeaderName::AcceptLanguage:
+    case HTTPHeaderName::ContentLanguage:
+    case HTTPHeaderName::Origin:
+    case HTTPHeaderName::Referer:
</ins><span class="cx">         return true;
</span><del>-
-    // Preflight is required for MIME types that can not be sent via form submission.
-    if (equalIgnoringCase(name, &quot;content-type&quot;)) {
</del><ins>+    case HTTPHeaderName::ContentType: {
+        // Preflight is required for MIME types that can not be sent via form submission.
</ins><span class="cx">         String mimeType = extractMIMETypeFromMediaType(value);
</span><span class="cx">         return equalIgnoringCase(mimeType, &quot;application/x-www-form-urlencoded&quot;)
</span><span class="cx">             || equalIgnoringCase(mimeType, &quot;multipart/form-data&quot;)
</span><span class="cx">             || equalIgnoringCase(mimeType, &quot;text/plain&quot;);
</span><span class="cx">     }
</span><del>-
-    return false;
</del><ins>+    default:
+        return false;
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool isSimpleCrossOriginAccessRequest(const String&amp; method, const HTTPHeaderMap&amp; headerMap)
</span><span class="lines">@@ -70,7 +71,7 @@
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     for (const auto&amp; header : headerMap) {
</span><del>-        if (!isOnAccessControlSimpleRequestHeaderWhitelist(header.key, header.value))
</del><ins>+        if (!header.keyAsHTTPHeaderName || !isOnAccessControlSimpleRequestHeaderWhitelist(header.keyAsHTTPHeaderName.value(), header.value))
</ins><span class="cx">             return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderCrossOriginAccessControlh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/CrossOriginAccessControl.h (175230 => 175231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/CrossOriginAccessControl.h        2014-10-27 20:42:47 UTC (rev 175230)
+++ trunk/Source/WebCore/loader/CrossOriginAccessControl.h        2014-10-27 21:08:51 UTC (rev 175231)
</span><span class="lines">@@ -37,13 +37,14 @@
</span><span class="cx"> typedef HashSet&lt;String, CaseFoldingHash&gt; HTTPHeaderSet;
</span><span class="cx"> 
</span><span class="cx"> class HTTPHeaderMap;
</span><ins>+enum class HTTPHeaderName;
</ins><span class="cx"> class ResourceRequest;
</span><span class="cx"> class ResourceResponse;
</span><span class="cx"> class SecurityOrigin;
</span><span class="cx"> 
</span><span class="cx"> bool isSimpleCrossOriginAccessRequest(const String&amp; method, const HTTPHeaderMap&amp;);
</span><span class="cx"> bool isOnAccessControlSimpleRequestMethodWhitelist(const String&amp;);
</span><del>-bool isOnAccessControlSimpleRequestHeaderWhitelist(const String&amp; name, const String&amp; value);
</del><ins>+bool isOnAccessControlSimpleRequestHeaderWhitelist(HTTPHeaderName, const String&amp; value);
</ins><span class="cx"> bool isOnAccessControlResponseHeaderWhitelist(const String&amp;);
</span><span class="cx"> 
</span><span class="cx"> void updateRequestForAccessControl(ResourceRequest&amp;, SecurityOrigin*, StoredCredentials);
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderCrossOriginPreflightResultCachecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/CrossOriginPreflightResultCache.cpp (175230 => 175231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/CrossOriginPreflightResultCache.cpp        2014-10-27 20:42:47 UTC (rev 175230)
+++ trunk/Source/WebCore/loader/CrossOriginPreflightResultCache.cpp        2014-10-27 21:08:51 UTC (rev 175231)
</span><span class="lines">@@ -127,7 +127,9 @@
</span><span class="cx"> bool CrossOriginPreflightResultCacheItem::allowsCrossOriginHeaders(const HTTPHeaderMap&amp; requestHeaders, String&amp; errorDescription) const
</span><span class="cx"> {
</span><span class="cx">     for (const auto&amp; header : requestHeaders) {
</span><del>-        if (!m_headers.contains(header.key) &amp;&amp; !isOnAccessControlSimpleRequestHeaderWhitelist(header.key, header.value)) {
</del><ins>+        if (header.keyAsHTTPHeaderName &amp;&amp; isOnAccessControlSimpleRequestHeaderWhitelist(header.keyAsHTTPHeaderName.value(), header.value))
+            continue;
+        if (!m_headers.contains(header.key)) {
</ins><span class="cx">             errorDescription = &quot;Request header field &quot; + header.key + &quot; is not allowed by Access-Control-Allow-Headers.&quot;;
</span><span class="cx">             return false;
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderDocumentLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/DocumentLoader.cpp (175230 => 175231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/DocumentLoader.cpp        2014-10-27 20:42:47 UTC (rev 175230)
+++ trunk/Source/WebCore/loader/DocumentLoader.cpp        2014-10-27 21:08:51 UTC (rev 175231)
</span><span class="lines">@@ -605,8 +605,9 @@
</span><span class="cx">     if (willLoadFallback)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    auto it = response.httpHeaderFields().find(HTTPHeaderName::XFrameOptions);
-    if (it != response.httpHeaderFields().end()) {
</del><ins>+    const auto&amp; commonHeaders = response.httpHeaderFields().commonHeaders();
+    auto it = commonHeaders.find(HTTPHeaderName::XFrameOptions);
+    if (it != commonHeaders.end()) {
</ins><span class="cx">         String content = it-&gt;value;
</span><span class="cx">         ASSERT(m_mainResource);
</span><span class="cx">         unsigned long identifier = m_identifierForLoadWithoutResourceLoader ? m_identifierForLoadWithoutResourceLoader : m_mainResource-&gt;identifier();
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedRawResourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedRawResource.cpp (175230 => 175231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedRawResource.cpp        2014-10-27 20:42:47 UTC (rev 175230)
+++ trunk/Source/WebCore/loader/cache/CachedRawResource.cpp        2014-10-27 21:08:51 UTC (rev 175231)
</span><span class="lines">@@ -203,12 +203,8 @@
</span><span class="cx">     m_options.setDataBufferingPolicy(dataBufferingPolicy);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static bool shouldIgnoreHeaderForCacheReuse(const String&amp; headerName)
</del><ins>+static bool shouldIgnoreHeaderForCacheReuse(HTTPHeaderName name)
</ins><span class="cx"> {
</span><del>-    HTTPHeaderName name;
-    if (!findHTTPHeaderName(headerName, name))
-        return false;
-
</del><span class="cx">     switch (name) {
</span><span class="cx">     // FIXME: This list of headers that don't affect cache policy almost certainly isn't complete.
</span><span class="cx">     case HTTPHeaderName::Accept:
</span><span class="lines">@@ -246,12 +242,22 @@
</span><span class="cx">     const HTTPHeaderMap&amp; oldHeaders = m_resourceRequest.httpHeaderFields();
</span><span class="cx"> 
</span><span class="cx">     for (const auto&amp; header : newHeaders) {
</span><del>-        if (!shouldIgnoreHeaderForCacheReuse(header.key) &amp;&amp; header.value != oldHeaders.get(header.key))
</del><ins>+        if (header.keyAsHTTPHeaderName) {
+            if (!shouldIgnoreHeaderForCacheReuse(header.keyAsHTTPHeaderName.value())
+                &amp;&amp; header.value != oldHeaders.commonHeaders().get(header.keyAsHTTPHeaderName.value()))
+                return false;
+        } else if (header.value != oldHeaders.uncommonHeaders().get(header.key))
</ins><span class="cx">             return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    // For this second loop, we don't actually need to compare values, checking that the
+    // key is contained in newHeaders is sufficient due to the previous loop.
</ins><span class="cx">     for (const auto&amp; header : oldHeaders) {
</span><del>-        if (!shouldIgnoreHeaderForCacheReuse(header.key) &amp;&amp; header.value != newHeaders.get(header.key))
</del><ins>+        if (header.keyAsHTTPHeaderName) {
+            if (!shouldIgnoreHeaderForCacheReuse(header.keyAsHTTPHeaderName.value())
+                &amp;&amp; !newHeaders.commonHeaders().contains(header.keyAsHTTPHeaderName.value()))
+                return false;
+        } else if (!newHeaders.uncommonHeaders().contains(header.key))
</ins><span class="cx">             return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkHTTPHeaderMapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/HTTPHeaderMap.cpp (175230 => 175231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/HTTPHeaderMap.cpp        2014-10-27 20:42:47 UTC (rev 175230)
+++ trunk/Source/WebCore/platform/network/HTTPHeaderMap.cpp        2014-10-27 21:08:51 UTC (rev 175231)
</span><span class="lines">@@ -31,7 +31,6 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;HTTPHeaderMap.h&quot;
</span><span class="cx"> 
</span><del>-#include &quot;HTTPHeaderNames.h&quot;
</del><span class="cx"> #include &lt;utility&gt;
</span><span class="cx"> #include &lt;wtf/text/StringView.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -48,75 +47,85 @@
</span><span class="cx"> std::unique_ptr&lt;CrossThreadHTTPHeaderMapData&gt; HTTPHeaderMap::copyData() const
</span><span class="cx"> {
</span><span class="cx">     auto data = std::make_unique&lt;CrossThreadHTTPHeaderMapData&gt;();
</span><del>-    data-&gt;reserveInitialCapacity(m_headers.size());
</del><span class="cx"> 
</span><del>-    for (const auto&amp; header : *this)
-        data-&gt;uncheckedAppend(std::make_pair(header.key.isolatedCopy(), header.value.isolatedCopy()));
</del><ins>+    data-&gt;commonHeaders.reserveInitialCapacity(m_commonHeaders.size());
+    for (const auto&amp; header : m_commonHeaders)
+        data-&gt;commonHeaders.uncheckedAppend(std::make_pair(header.key, header.value.isolatedCopy()));
</ins><span class="cx"> 
</span><ins>+    data-&gt;uncommonHeaders.reserveInitialCapacity(m_uncommonHeaders.size());
+    for (const auto&amp; header : m_uncommonHeaders)
+        data-&gt;uncommonHeaders.uncheckedAppend(std::make_pair(header.key.isolatedCopy(), header.value.isolatedCopy()));
+
</ins><span class="cx">     return data;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTTPHeaderMap::adopt(std::unique_ptr&lt;CrossThreadHTTPHeaderMapData&gt; data)
</span><span class="cx"> {
</span><del>-    m_headers.clear();
</del><ins>+    m_commonHeaders.clear();
+    m_uncommonHeaders.clear();
</ins><span class="cx"> 
</span><del>-    for (auto&amp; header : *data)
-        m_headers.add(WTF::move(header.first), WTF::move(header.second));
-}
</del><ins>+    for (auto&amp; header : data-&gt;commonHeaders)
+        m_commonHeaders.add(header.first, WTF::move(header.second));
</ins><span class="cx"> 
</span><del>-static String internHTTPHeaderNameString(const String&amp; nameString)
-{
-    HTTPHeaderName headerName;
-    if (!findHTTPHeaderName(nameString, headerName))
-        return nameString;
-
-    return httpHeaderNameString(headerName).toStringWithoutCopying();
</del><ins>+    for (auto&amp; header : data-&gt;uncommonHeaders)
+        m_uncommonHeaders.add(WTF::move(header.first), WTF::move(header.second));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> String HTTPHeaderMap::get(const String&amp; name) const
</span><span class="cx"> {
</span><del>-    return m_headers.get(internHTTPHeaderNameString(name));
</del><ins>+    HTTPHeaderName headerName;
+    if (!findHTTPHeaderName(name, headerName))
+        return m_uncommonHeaders.get(name);
+    return m_commonHeaders.get(headerName);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTTPHeaderMap::set(const String&amp; name, const String&amp; value)
</span><span class="cx"> {
</span><del>-    m_headers.set(internHTTPHeaderNameString(name), value);
</del><ins>+    HTTPHeaderName headerName;
+    if (!findHTTPHeaderName(name, headerName)) {
+        m_uncommonHeaders.set(name, value);
+        return;
+    }
+    m_commonHeaders.set(headerName, value);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTTPHeaderMap::add(const String&amp; name, const String&amp; value)
</span><span class="cx"> {
</span><del>-    auto result = m_headers.add(internHTTPHeaderNameString(name), value);
-    if (!result.isNewEntry)
-        result.iterator-&gt;value = result.iterator-&gt;value + &quot;, &quot; + value;
</del><ins>+    HTTPHeaderName headerName;
+    if (!findHTTPHeaderName(name, headerName)) {
+        auto result = m_uncommonHeaders.add(name, value);
+        if (!result.isNewEntry)
+            result.iterator-&gt;value = result.iterator-&gt;value + &quot;, &quot; + value;
+        return;
+    }
+    add(headerName, value);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> String HTTPHeaderMap::get(HTTPHeaderName name) const
</span><span class="cx"> {
</span><del>-    auto it = find(name);
-    if (it == end())
-        return String();
-
-    return it-&gt;value;
</del><ins>+    return m_commonHeaders.get(name);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HTTPHeaderMap::set(HTTPHeaderName name, const String&amp; value)
</span><span class="cx"> {
</span><del>-    m_headers.set(httpHeaderNameString(name).toStringWithoutCopying(), value);
</del><ins>+    m_commonHeaders.set(name, value);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool HTTPHeaderMap::contains(HTTPHeaderName name) const
</span><span class="cx"> {
</span><del>-    return m_headers.contains(httpHeaderNameString(name).toStringWithoutCopying());
</del><ins>+    return m_commonHeaders.contains(name);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-HTTPHeaderMap::const_iterator HTTPHeaderMap::find(HTTPHeaderName name) const
</del><ins>+bool HTTPHeaderMap::remove(HTTPHeaderName name)
</ins><span class="cx"> {
</span><del>-    return m_headers.find(httpHeaderNameString(name).toStringWithoutCopying());
</del><ins>+    return m_commonHeaders.remove(name);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool HTTPHeaderMap::remove(HTTPHeaderName name)
</del><ins>+void HTTPHeaderMap::add(HTTPHeaderName name, const String&amp; value)
</ins><span class="cx"> {
</span><del>-    return m_headers.remove(httpHeaderNameString(name).toStringWithoutCopying());
</del><ins>+    auto result = m_commonHeaders.add(name, value);
+    if (!result.isNewEntry)
+        result.iterator-&gt;value = result.iterator-&gt;value + &quot;, &quot; + value;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkHTTPHeaderMaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/HTTPHeaderMap.h (175230 => 175231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/HTTPHeaderMap.h        2014-10-27 20:42:47 UTC (rev 175230)
+++ trunk/Source/WebCore/platform/network/HTTPHeaderMap.h        2014-10-27 21:08:51 UTC (rev 175231)
</span><span class="lines">@@ -27,8 +27,10 @@
</span><span class="cx"> #ifndef HTTPHeaderMap_h
</span><span class="cx"> #define HTTPHeaderMap_h
</span><span class="cx"> 
</span><ins>+#include &quot;HTTPHeaderNames.h&quot;
</ins><span class="cx"> #include &lt;utility&gt;
</span><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><ins>+#include &lt;wtf/Optional.h&gt;
</ins><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> #include &lt;wtf/text/AtomicString.h&gt;
</span><span class="cx"> #include &lt;wtf/text/AtomicStringHash.h&gt;
</span><span class="lines">@@ -36,17 +38,87 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-enum class HTTPHeaderName;
</del><ins>+struct CrossThreadHTTPHeaderMapData {
+    Vector&lt;std::pair&lt;HTTPHeaderName, String&gt;&gt; commonHeaders;
+    Vector&lt;std::pair&lt;String, String&gt;&gt; uncommonHeaders;
+};
</ins><span class="cx"> 
</span><del>-typedef Vector&lt;std::pair&lt;String, String&gt;&gt; CrossThreadHTTPHeaderMapData;
-
</del><span class="cx"> // FIXME: Not every header fits into a map. Notably, multiple Set-Cookie header fields are needed to set multiple cookies.
</span><span class="cx"> 
</span><span class="cx"> class HTTPHeaderMap {
</span><del>-    typedef HashMap&lt;String, String, CaseFoldingHash&gt; HashMapType;
</del><span class="cx"> public:
</span><del>-    typedef HashMapType::const_iterator const_iterator;
</del><ins>+    typedef HashMap&lt;HTTPHeaderName, String, WTF::IntHash&lt;HTTPHeaderName&gt;, WTF::StrongEnumHashTraits&lt;HTTPHeaderName&gt;&gt; CommonHeadersHashMap;
+    typedef HashMap&lt;String, String, CaseFoldingHash&gt; UncommonHeadersHashMap;
</ins><span class="cx"> 
</span><ins>+    class HTTPHeaderMapConstIterator {
+    public:
+        HTTPHeaderMapConstIterator(const HTTPHeaderMap&amp; table, CommonHeadersHashMap::const_iterator commonHeadersIt, UncommonHeadersHashMap::const_iterator uncommonHeadersIt)
+            : m_table(table)
+            , m_commonHeadersIt(commonHeadersIt)
+            , m_uncommonHeadersIt(uncommonHeadersIt)
+        {
+            updateKeyValue(m_commonHeadersIt);
+        }
+
+        struct KeyValue {
+            String key;
+            Optional&lt;HTTPHeaderName&gt; keyAsHTTPHeaderName;
+            String value;
+        };
+
+        const KeyValue* get() const
+        {
+            ASSERT(*this != m_table.end());
+            return &amp;m_keyValue;
+        }
+        const KeyValue&amp; operator*() const { return *get(); }
+        const KeyValue* operator-&gt;() const { return get(); }
+
+        HTTPHeaderMapConstIterator&amp; operator++()
+        {
+            if (m_commonHeadersIt != m_table.m_commonHeaders.end()) {
+                if (updateKeyValue(++m_commonHeadersIt))
+                    return *this;
+            } else
+                ++m_uncommonHeadersIt;
+
+            updateKeyValue(m_uncommonHeadersIt);
+            return *this;
+        }
+
+        bool operator!=(const HTTPHeaderMapConstIterator&amp; other) const { return !(*this == other); }
+        bool operator==(const HTTPHeaderMapConstIterator&amp; other) const
+        {
+            return m_commonHeadersIt == other.m_commonHeadersIt &amp;&amp; m_uncommonHeadersIt == other.m_uncommonHeadersIt;
+        }
+
+    private:
+        bool updateKeyValue(CommonHeadersHashMap::const_iterator it)
+        {
+            if (it == m_table.commonHeaders().end())
+                return false;
+            m_keyValue.key = httpHeaderNameString(it-&gt;key).toStringWithoutCopying();
+            m_keyValue.keyAsHTTPHeaderName = it-&gt;key;
+            m_keyValue.value = it-&gt;value;
+            return true;
+        }
+        bool updateKeyValue(UncommonHeadersHashMap::const_iterator it)
+        {
+            if (it == m_table.uncommonHeaders().end())
+                return false;
+            m_keyValue.key = it-&gt;key;
+            m_keyValue.keyAsHTTPHeaderName = Nullopt;
+            m_keyValue.value = it-&gt;value;
+            return true;
+        }
+
+        const HTTPHeaderMap&amp; m_table;
+        CommonHeadersHashMap::const_iterator m_commonHeadersIt;
+        UncommonHeadersHashMap::const_iterator m_uncommonHeadersIt;
+        KeyValue m_keyValue;
+    };
+    typedef HTTPHeaderMapConstIterator const_iterator;
+
</ins><span class="cx">     WEBCORE_EXPORT HTTPHeaderMap();
</span><span class="cx">     WEBCORE_EXPORT ~HTTPHeaderMap();
</span><span class="cx"> 
</span><span class="lines">@@ -54,10 +126,14 @@
</span><span class="cx">     std::unique_ptr&lt;CrossThreadHTTPHeaderMapData&gt; copyData() const;
</span><span class="cx">     void adopt(std::unique_ptr&lt;CrossThreadHTTPHeaderMapData&gt;);
</span><span class="cx"> 
</span><del>-    bool isEmpty() const { return m_headers.isEmpty(); }
-    int size() const { return m_headers.size(); }
</del><ins>+    bool isEmpty() const { return m_commonHeaders.isEmpty() &amp;&amp; m_uncommonHeaders.isEmpty(); }
+    int size() const { return m_commonHeaders.size() + m_uncommonHeaders.size(); }
</ins><span class="cx"> 
</span><del>-    void clear() { m_headers.clear(); }
</del><ins>+    void clear()
+    {
+        m_commonHeaders.clear();
+        m_uncommonHeaders.clear();
+    }
</ins><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT String get(const String&amp; name) const;
</span><span class="cx">     WEBCORE_EXPORT void set(const String&amp; name, const String&amp; value);
</span><span class="lines">@@ -65,23 +141,27 @@
</span><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT String get(HTTPHeaderName) const;
</span><span class="cx">     void set(HTTPHeaderName, const String&amp; value);
</span><ins>+    void add(HTTPHeaderName, const String&amp; value);
</ins><span class="cx">     bool contains(HTTPHeaderName) const;
</span><del>-    const_iterator find(HTTPHeaderName) const;
</del><span class="cx">     WEBCORE_EXPORT bool remove(HTTPHeaderName);
</span><span class="cx"> 
</span><span class="cx">     // Instead of passing a string literal to any of these functions, just use a HTTPHeaderName instead.
</span><span class="cx">     template&lt;size_t length&gt; String get(const char (&amp;)[length]) const = delete;
</span><span class="cx">     template&lt;size_t length&gt; void set(const char (&amp;)[length], const String&amp;) = delete;
</span><span class="cx">     template&lt;size_t length&gt; bool contains(const char (&amp;)[length]) = delete;
</span><del>-    template&lt;size_t length&gt; const_iterator find(const char(&amp;)[length]) = delete;
</del><span class="cx">     template&lt;size_t length&gt; bool remove(const char (&amp;)[length]) = delete;
</span><span class="cx"> 
</span><del>-    const_iterator begin() const { return m_headers.begin(); }
-    const_iterator end() const { return m_headers.end(); }
</del><ins>+    const CommonHeadersHashMap&amp; commonHeaders() const { return m_commonHeaders; }
+    const UncommonHeadersHashMap&amp; uncommonHeaders() const { return m_uncommonHeaders; }
+    CommonHeadersHashMap&amp; commonHeaders() { return m_commonHeaders; }
+    UncommonHeadersHashMap&amp; uncommonHeaders() { return m_uncommonHeaders; }
</ins><span class="cx"> 
</span><ins>+    const_iterator begin() const { return const_iterator(*this, m_commonHeaders.begin(), m_uncommonHeaders.begin()); }
+    const_iterator end() const { return const_iterator(*this, m_commonHeaders.end(), m_uncommonHeaders.end()); }
+
</ins><span class="cx">     friend bool operator==(const HTTPHeaderMap&amp; a, const HTTPHeaderMap&amp; b)
</span><span class="cx">     {
</span><del>-        return a.m_headers == b.m_headers;
</del><ins>+        return a.m_commonHeaders == b.m_commonHeaders &amp;&amp; a.m_uncommonHeaders == b.m_uncommonHeaders;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     friend bool operator!=(const HTTPHeaderMap&amp; a, const HTTPHeaderMap&amp; b)
</span><span class="lines">@@ -90,10 +170,8 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    // FIXME: Instead of having a HashMap&lt;String, String&gt;, we could have two hash maps,
-    // one HashMap&lt;HTTPHeaderName, String&gt; for common headers and another HashMap&lt;String, String&gt; for
-    // less common headers.
-    HashMapType m_headers;
</del><ins>+    CommonHeadersHashMap m_commonHeaders;
+    UncommonHeadersHashMap m_uncommonHeaders;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (175230 => 175231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-10-27 20:42:47 UTC (rev 175230)
+++ trunk/Source/WebKit2/ChangeLog        2014-10-27 21:08:51 UTC (rev 175231)
</span><span class="lines">@@ -1,3 +1,25 @@
</span><ins>+2014-10-27  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        Use separate HashMaps for common and uncommon headers in HTTPHeaderMap
+        https://bugs.webkit.org/show_bug.cgi?id=138079
+
+        Reviewed by Anders Carlsson.
+
+        Update the WK2 IPC HTTPHeaderMap serialization / deserialization code
+        to leverage the fact that HTTPHeaderMap now stores common HTTP headers
+        and uncommon one in separate HashMaps. This speeds up deserialization
+        as we no longer need to call findHTTPHeaderName() for every decoded
+        header. We already know if the header is a common one or not, and if
+        it is then we already have a HTTPHeaderName type instead of a String.
+
+        I see that we spend ~40% less time in HTTPHeaderMap decoding when
+        loading http://flickr.com/explore, while the encoding takes about
+        the same amount of time as before.
+
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::ArgumentCoder&lt;HTTPHeaderMap&gt;::encode):
+        (IPC::ArgumentCoder&lt;HTTPHeaderMap&gt;::decode):
+
</ins><span class="cx"> 2014-10-24  Benjamin Poulain  &lt;bpoulain@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix the iOS build
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedWebCoreArgumentCoderscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp (175230 => 175231)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp        2014-10-27 20:42:47 UTC (rev 175230)
+++ trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp        2014-10-27 21:08:51 UTC (rev 175231)
</span><span class="lines">@@ -467,8 +467,13 @@
</span><span class="cx"> 
</span><span class="cx"> void ArgumentCoder&lt;HTTPHeaderMap&gt;::encode(ArgumentEncoder&amp; encoder, const HTTPHeaderMap&amp; headerMap)
</span><span class="cx"> {
</span><del>-    encoder &lt;&lt; static_cast&lt;uint64_t&gt;(headerMap.size());
-    for (auto&amp; keyValuePair : headerMap) {
</del><ins>+    encoder &lt;&lt; static_cast&lt;uint64_t&gt;(headerMap.commonHeaders().size());
+    for (const auto&amp; keyValuePair : headerMap.commonHeaders()) {
+        encoder.encodeEnum(keyValuePair.key);
+        encoder &lt;&lt; keyValuePair.value;
+    }
+    encoder &lt;&lt; static_cast&lt;uint64_t&gt;(headerMap.uncommonHeaders().size());
+    for (const auto&amp; keyValuePair : headerMap.uncommonHeaders()) {
</ins><span class="cx">         encoder &lt;&lt; keyValuePair.key;
</span><span class="cx">         encoder &lt;&lt; keyValuePair.value;
</span><span class="cx">     }
</span><span class="lines">@@ -476,11 +481,27 @@
</span><span class="cx"> 
</span><span class="cx"> bool ArgumentCoder&lt;HTTPHeaderMap&gt;::decode(ArgumentDecoder&amp; decoder, HTTPHeaderMap&amp; headerMap)
</span><span class="cx"> {
</span><del>-    uint64_t size;
-    if (!decoder.decode(size))
</del><ins>+    uint64_t commonHeadersSize;
+    if (!decoder.decode(commonHeadersSize))
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    for (size_t i = 0; i &lt; size; ++i) {
</del><ins>+    for (size_t i = 0; i &lt; commonHeadersSize; ++i) {
+        HTTPHeaderName name;
+        if (!decoder.decodeEnum(name))
+            return false;
+
+        String value;
+        if (!decoder.decode(value))
+            return false;
+
+        headerMap.commonHeaders().add(name, value);
+    }
+
+    uint64_t uncommonHeadersSize;
+    if (!decoder.decode(uncommonHeadersSize))
+        return false;
+
+    for (size_t i = 0; i &lt; uncommonHeadersSize; ++i) {
</ins><span class="cx">         String name;
</span><span class="cx">         if (!decoder.decode(name))
</span><span class="cx">             return false;
</span><span class="lines">@@ -489,7 +510,7 @@
</span><span class="cx">         if (!decoder.decode(value))
</span><span class="cx">             return false;
</span><span class="cx"> 
</span><del>-        headerMap.set(name, value);
</del><ins>+        headerMap.uncommonHeaders().add(name, value);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return true;
</span></span></pre>
</div>
</div>

</body>
</html>