Changeset 241220 in webkit


Ignore:
Timestamp:
Feb 8, 2019 4:26:40 PM (5 years ago)
Author:
Chris Dumez
Message:

[Cocoa] Optimize ResourceResponse::platformLazyInit()
https://bugs.webkit.org/show_bug.cgi?id=194438

Reviewed by Alex Christensen.

Optimize ResourceResponse::platformLazyInit(). Most of the CPU time currently goes into getting the
HTTP headers from CFNetwork:
"""
Sample Count, Samples %, CPU %, Symbol
46, 0.0%, 0.0%, WebCore::initializeHTTPHeaders(WebCore::OnlyCommonHeaders, NSHTTPURLResponse*, WebCore::HTTPHeaderMap&) (in WebCore)
34, 0.0%, 0.0%, HTTPHeaderDict::copyAsOrdinaryDict(CFAllocator const*) const (in CFNetwork)
11, 0.0%, 0.0%, CFDictionaryApplyFunction (in CoreFoundation)
"""

We currently have 2 levels of initialization: CommonFieldsOnly & AllFields. With WebKit2, most ResourceResponses get sent over IPC
and thus end up getting initialized twice, once with CommonFieldsOnly and then with AllFields.
This would cause us to call the expensive HTTPHeaderDict::copyAsOrdinaryDict() twice instead of once, simply to initialize the common
HTTP headers first and then the uncommon ones later.

This patch updates ResourceResponse::platformLazyInit() to initialize all HTTP headers at once, as soon as CommonFieldsOnly
initialization is requested, so that we no longer copy all HTTP headers twice.

  • platform/network/cocoa/ResourceResponseCocoa.mm:

(WebCore::initializeHTTPHeaders):
(WebCore::ResourceResponse::platformLazyInit):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r241207 r241220  
     12019-02-08  Chris Dumez  <cdumez@apple.com>
     2
     3        [Cocoa] Optimize ResourceResponse::platformLazyInit()
     4        https://bugs.webkit.org/show_bug.cgi?id=194438
     5
     6        Reviewed by Alex Christensen.
     7
     8        Optimize ResourceResponse::platformLazyInit(). Most of the CPU time currently goes into getting the
     9        HTTP headers from CFNetwork:
     10        """
     11        Sample Count, Samples %, CPU %, Symbol
     12        46, 0.0%, 0.0%, WebCore::initializeHTTPHeaders(WebCore::OnlyCommonHeaders, NSHTTPURLResponse*, WebCore::HTTPHeaderMap&) (in WebCore)
     13        34, 0.0%, 0.0%,     HTTPHeaderDict::copyAsOrdinaryDict(__CFAllocator const*) const (in CFNetwork)
     14        11, 0.0%, 0.0%,     CFDictionaryApplyFunction (in CoreFoundation)
     15        """
     16
     17        We currently have 2 levels of initialization: CommonFieldsOnly & AllFields. With WebKit2, most ResourceResponses get sent over IPC
     18        and thus end up getting initialized twice, once with CommonFieldsOnly and then with AllFields.
     19        This would cause us to call the expensive HTTPHeaderDict::copyAsOrdinaryDict() twice instead of once, simply to initialize the common
     20        HTTP headers first and then the uncommon ones later.
     21
     22        This patch updates ResourceResponse::platformLazyInit() to initialize all HTTP headers at once, as soon as CommonFieldsOnly
     23        initialization is requested, so that we no longer copy all HTTP headers twice.
     24
     25        * platform/network/cocoa/ResourceResponseCocoa.mm:
     26        (WebCore::initializeHTTPHeaders):
     27        (WebCore::ResourceResponse::platformLazyInit):
     28
    1292019-02-08  Justin Fan  <justin_fan@apple.com>
    230
  • trunk/Source/WebCore/platform/network/cocoa/ResourceResponseCocoa.mm

    r239255 r241220  
    138138}
    139139
    140 enum class OnlyCommonHeaders { No, Yes };
    141 static inline void initializeHTTPHeaders(OnlyCommonHeaders onlyCommonHeaders, NSHTTPURLResponse *httpResponse, HTTPHeaderMap& headersMap)
    142 {
    143     headersMap.clear();
    144     auto messageRef = CFURLResponseGetHTTPResponse([httpResponse _CFURLResponse]);
    145 
     140static inline HTTPHeaderMap initializeHTTPHeaders(CFHTTPMessageRef messageRef)
     141{
    146142    // Avoid calling [NSURLResponse allHeaderFields] to minimize copying (<rdar://problem/26778863>).
    147143    auto headers = adoptCF(CFHTTPMessageCopyAllHeaderFields(messageRef));
    148     if (onlyCommonHeaders == OnlyCommonHeaders::Yes) {
    149         for (auto& commonHeader : commonHeaderFields) {
    150             const void* value;
    151             if (CFDictionaryGetValueIfPresent(headers.get(), commonHeader, &value))
    152                 headersMap.set(commonHeader, (CFStringRef) value);
    153         }
    154         return;
    155     }
     144
     145    HTTPHeaderMap headersMap;
    156146    CFDictionaryApplyFunction(headers.get(), addToHTTPHeaderMap, &headersMap);
     147    return headersMap;
    157148}
    158149
     
    178169    @autoreleasepool {
    179170
    180         NSHTTPURLResponse *httpResponse = [m_nsResponse.get() isKindOfClass:[NSHTTPURLResponse class]] ? (NSHTTPURLResponse *)m_nsResponse.get() : nullptr;
     171        auto messageRef = [m_nsResponse.get() isKindOfClass:[NSHTTPURLResponse class]] ? CFURLResponseGetHTTPResponse([ (NSHTTPURLResponse *)m_nsResponse.get() _CFURLResponse]) : nullptr;
    181172
    182173        if (m_initLevel < CommonFieldsOnly) {
     
    186177            // Stripping double quotes as a workaround for <rdar://problem/8757088>, can be removed once that is fixed.
    187178            m_textEncodingName = stripLeadingAndTrailingDoubleQuote([m_nsResponse.get() textEncodingName]);
    188             m_httpStatusCode = httpResponse ? [httpResponse statusCode] : 0;
     179            m_httpStatusCode = messageRef ? CFHTTPMessageGetResponseStatusCode(messageRef) : 0;
     180            if (messageRef)
     181                m_httpHeaderFields = initializeHTTPHeaders(messageRef);
    189182        }
    190         if (httpResponse) {
    191             if (initLevel == AllFields) {
    192                 auto messageRef = CFURLResponseGetHTTPResponse([httpResponse _CFURLResponse]);
    193                 m_httpStatusText = extractHTTPStatusText(messageRef);
    194                 m_httpVersion = String(adoptCF(CFHTTPMessageCopyVersion(messageRef)).get()).convertToASCIIUppercase();
    195                 initializeHTTPHeaders(OnlyCommonHeaders::No, httpResponse, m_httpHeaderFields);
    196             } else
    197                 initializeHTTPHeaders(OnlyCommonHeaders::Yes, httpResponse, m_httpHeaderFields);
     183        if (messageRef && initLevel == AllFields) {
     184            m_httpStatusText = extractHTTPStatusText(messageRef);
     185            m_httpVersion = String(adoptCF(CFHTTPMessageCopyVersion(messageRef)).get()).convertToASCIIUppercase();
    198186        }
    199 
    200187    }
    201188
Note: See TracChangeset for help on using the changeset viewer.