Use separate HashMaps for common and uncommon headers in HTTPHeaderMap
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Oct 2014 21:08:51 +0000 (21:08 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Oct 2014 21:08:51 +0000 (21:08 +0000)
commit9b041f17f55a98528129116d8a81c495b359b654
tree3ae72718c7a6f4eb35bb7729932abf3e31e8e854
parentc3d34db7c6035903d0a1414bdfbd7d444fb38cce
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<HTTPHeaderMap, String> for common HTTP headers
- a HashMap<String, String, CaseFoldingHash> 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 <String, String>
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<HTTPHeaderMap>::encode):
(IPC::ArgumentCoder<HTTPHeaderMap>::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):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@175231 268f45cc-cd09-0410-ab3c-d52691b4dbfc
13 files changed:
Source/WTF/ChangeLog
Source/WTF/wtf/HashTraits.h
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/loader/CrossOriginAccessControl.cpp
Source/WebCore/loader/CrossOriginAccessControl.h
Source/WebCore/loader/CrossOriginPreflightResultCache.cpp
Source/WebCore/loader/DocumentLoader.cpp
Source/WebCore/loader/cache/CachedRawResource.cpp
Source/WebCore/platform/network/HTTPHeaderMap.cpp
Source/WebCore/platform/network/HTTPHeaderMap.h
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/WebCoreArgumentCoders.cpp