Changeset 220808 in webkit


Ignore:
Timestamp:
Aug 16, 2017 1:49:47 PM (7 years ago)
Author:
timothy_horton@apple.com
Message:

2-3% of main thread time under UTTypeCreatePreferredIdentifierForTag on wunderground map
https://bugs.webkit.org/show_bug.cgi?id=175618

Reviewed by Simon Fraser.

No new tests, just a perf win.

UTTypeCreatePreferredIdentifierForTag is fairly expensive, and is called
under every toDataURL, which the Wunderground wundermap does a /lot/.

Keep a 16-item LRU cache of MIMEType->UTI mappings.

Also, make other callers of UTTypeCreatePreferredIdentifierForTag use
the UTIUtilities version so they can share in the caching.

Also, as a drive-by, add and make other callers use mimeTypeFromUTI too,
and make the UTIUtilities operate on Strings for a slightly more WebCore-y feel.

  • editing/ios/EditorIOS.mm:

(WebCore::Editor::WebContentReader::readImage):

  • platform/MIMETypeRegistry.cpp:

(WebCore::initializeSupportedImageMIMETypes):
(WebCore::initializeSupportedImageMIMETypesForEncoding):

  • platform/graphics/mac/MediaPlayerPrivateQTKit.mm:

(WebCore::createFileTypesSet):

  • platform/graphics/cg/ImageSourceCGMac.mm:

(WebCore::MIMETypeForImageSourceType):
Adopt newly-added MIMETypeFromUTI().

  • platform/graphics/cg/ImageBufferCG.cpp:

(WebCore::utiFromImageBufferMIMEType):
(WebCore::ImageBuffer::toCFData const):
(WebCore::cfData):
(WebCore::utiFromMIMEType): Deleted.
Adopt UTIFromMIMEType, and rename the local helper that does something
different (a small static map) on iOS and Windows to not have an overlapping name.

  • platform/ios/PasteboardIOS.mm:

(WebCore::Pasteboard::resourceMIMEType):
(WebCore::utiTypeFromCocoaType):
Adopt UTIFromMIMEType().

  • platform/ios/PlatformPasteboardIOS.mm:

(WebCore::PlatformPasteboard::writeObjectRepresentations):

  • platform/mac/PasteboardMac.mm:

(WebCore::cocoaTypeFromHTMLClipboardType):
Adopt isDeclaredUTI and UTIFromMIMEType().

  • platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm:

(WebCore::WebCoreAVFResourceLoader::responseReceived):

  • platform/network/ios/WebCoreURLResponseIOS.mm:

(WebCore::adjustMIMETypeIfNecessary):

  • platform/network/mac/WebCoreURLResponse.mm:

(WebCore::adjustMIMETypeIfNecessary):

  • rendering/RenderThemeIOS.mm:

(WebCore::iconForAttachment):

  • rendering/RenderThemeMac.mm:

(WebCore::iconForAttachment):
Deal with the fact that UTI utilities deal in Strings now.

  • platform/network/mac/UTIUtilities.h:
  • platform/network/mac/UTIUtilities.mm:

(WebCore::MIMETypeFromUTI):
Added. This doesn't crawl up the UTI tree if the first conversion fails,
which is what most of the existing code does. It's possible we want to
use MIMETypeFromUTITree's logic everywhere, but I didn't want to change
that in this patch.

(WebCore::MIMETypeFromUTITree):
(WebCore::isDeclaredUTI):
Take and return strings.

(WebCore::UTIFromMIMETypeCachePolicy::createValueForKey):
(WebCore::UTIFromMIMEType):
Add the aforementioned cache.

Location:
trunk/Source/WebCore
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r220806 r220808  
     12017-08-16  Tim Horton  <timothy_horton@apple.com>
     2
     3        2-3% of main thread time under UTTypeCreatePreferredIdentifierForTag on wunderground map
     4        https://bugs.webkit.org/show_bug.cgi?id=175618
     5
     6        Reviewed by Simon Fraser.
     7
     8        No new tests, just a perf win.
     9
     10        UTTypeCreatePreferredIdentifierForTag is fairly expensive, and is called
     11        under every toDataURL, which the Wunderground wundermap does a /lot/.
     12
     13        Keep a 16-item LRU cache of MIMEType->UTI mappings.
     14
     15        Also, make other callers of UTTypeCreatePreferredIdentifierForTag use
     16        the UTIUtilities version so they can share in the caching.
     17
     18        Also, as a drive-by, add and make other callers use mimeTypeFromUTI too,
     19        and make the UTIUtilities operate on Strings for a slightly more WebCore-y feel.
     20
     21        * editing/ios/EditorIOS.mm:
     22        (WebCore::Editor::WebContentReader::readImage):
     23        * platform/MIMETypeRegistry.cpp:
     24        (WebCore::initializeSupportedImageMIMETypes):
     25        (WebCore::initializeSupportedImageMIMETypesForEncoding):
     26        * platform/graphics/mac/MediaPlayerPrivateQTKit.mm:
     27        (WebCore::createFileTypesSet):
     28        * platform/graphics/cg/ImageSourceCGMac.mm:
     29        (WebCore::MIMETypeForImageSourceType):
     30        Adopt newly-added MIMETypeFromUTI().
     31
     32        * platform/graphics/cg/ImageBufferCG.cpp:
     33        (WebCore::utiFromImageBufferMIMEType):
     34        (WebCore::ImageBuffer::toCFData const):
     35        (WebCore::cfData):
     36        (WebCore::utiFromMIMEType): Deleted.
     37        Adopt UTIFromMIMEType, and rename the local helper that does something
     38        different (a small static map) on iOS and Windows to not have an overlapping name.
     39
     40        * platform/ios/PasteboardIOS.mm:
     41        (WebCore::Pasteboard::resourceMIMEType):
     42        (WebCore::utiTypeFromCocoaType):
     43        Adopt UTIFromMIMEType().
     44
     45        * platform/ios/PlatformPasteboardIOS.mm:
     46        (WebCore::PlatformPasteboard::writeObjectRepresentations):
     47        * platform/mac/PasteboardMac.mm:
     48        (WebCore::cocoaTypeFromHTMLClipboardType):
     49        Adopt isDeclaredUTI and UTIFromMIMEType().
     50
     51        * platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm:
     52        (WebCore::WebCoreAVFResourceLoader::responseReceived):
     53        * platform/network/ios/WebCoreURLResponseIOS.mm:
     54        (WebCore::adjustMIMETypeIfNecessary):
     55        * platform/network/mac/WebCoreURLResponse.mm:
     56        (WebCore::adjustMIMETypeIfNecessary):
     57        * rendering/RenderThemeIOS.mm:
     58        (WebCore::iconForAttachment):
     59        * rendering/RenderThemeMac.mm:
     60        (WebCore::iconForAttachment):
     61        Deal with the fact that UTI utilities deal in Strings now.
     62
     63        * platform/network/mac/UTIUtilities.h:
     64        * platform/network/mac/UTIUtilities.mm:
     65        (WebCore::MIMETypeFromUTI):
     66        Added. This doesn't crawl up the UTI tree if the first conversion fails,
     67        which is what most of the existing code does. It's possible we want to
     68        use MIMETypeFromUTITree's logic everywhere, but I didn't want to change
     69        that in this patch.
     70
     71        (WebCore::MIMETypeFromUTITree):
     72        (WebCore::isDeclaredUTI):
     73        Take and return strings.
     74
     75        (WebCore::UTIFromMIMETypeCachePolicy::createValueForKey):
     76        (WebCore::UTIFromMIMEType):
     77        Add the aforementioned cache.
     78
    1792017-08-16  Simon Fraser  <simon.fraser@apple.com>
    280
  • trunk/Source/WebCore/editing/ios/EditorIOS.mm

    r220506 r220808  
    5959#import "Text.h"
    6060#import "TypingCommand.h"
     61#import "UTIUtilities.h"
    6162#import "WAKAppKitStubs.h"
    6263#import "markup.h"
     
    333334    RetainPtr<NSString> filenameExtension = adoptNS((NSString *)UTTypeCopyPreferredTagWithClass(stringType.get(), kUTTagClassFilenameExtension));
    334335    NSString *relativeURLPart = [@"image" stringByAppendingString:filenameExtension.get()];
    335     RetainPtr<NSString> mimeType = adoptNS((NSString *)UTTypeCopyPreferredTagWithClass(stringType.get(), kUTTagClassMIMEType));
    336 
    337     addFragment(frame.editor().createFragmentForImageResourceAndAddResource(ArchiveResource::create(WTFMove(buffer), URL::fakeURLWithRelativePart(relativeURLPart), mimeType.get(), emptyString(), emptyString())));
     336    String mimeType = MIMETypeFromUTI(type);
     337
     338    addFragment(frame.editor().createFragmentForImageResourceAndAddResource(ArchiveResource::create(WTFMove(buffer), URL::fakeURLWithRelativePart(relativeURLPart), mimeType, emptyString(), emptyString())));
    338339    return fragment;
    339340}
  • trunk/Source/WebCore/platform/Pasteboard.h

    r219585 r220808  
    212212
    213213    static NSArray *supportedWebContentPasteboardTypes();
    214     static String resourceMIMEType(const NSString *mimeType);
     214    static String resourceMIMEType(NSString *mimeType);
    215215#endif
    216216
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm

    r220760 r220808  
    120120
    121121    if (AVAssetResourceLoadingContentInformationRequest* contentInfo = [m_avRequest.get() contentInformationRequest]) {
    122         String uti = UTIFromMIMEType(response.mimeType().createCFString().get()).get();
     122        String uti = UTIFromMIMEType(response.mimeType());
    123123
    124124        [contentInfo setContentType:uti];
  • trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp

    r220506 r220808  
    4848
    4949#if PLATFORM(COCOA)
     50#include "UTIUtilities.h"
    5051#include "WebCoreSystemInterface.h"
    5152#endif
     
    448449}
    449450   
    450 static RetainPtr<CFStringRef> utiFromMIMEType(const String& mimeType)
    451 {
     451static RetainPtr<CFStringRef> utiFromImageBufferMIMEType(const String& mimeType)
     452{
     453    // FIXME: Why doesn't iOS use the CoreServices version?
    452454#if PLATFORM(MAC)
    453     return adoptCF(UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType.createCFString().get(), 0));
     455    return UTIFromMIMEType(mimeType).createCFString();
    454456#else
    455457    ASSERT(isMainThread()); // It is unclear if CFSTR is threadsafe.
     
    533535        flushContext();
    534536
    535     auto uti = utiFromMIMEType(mimeType);
     537    auto uti = utiFromImageBufferMIMEType(mimeType);
    536538    ASSERT(uti);
    537539
     
    575577    ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
    576578
    577     auto uti = utiFromMIMEType(mimeType);
     579    auto uti = utiFromImageBufferMIMEType(mimeType);
    578580    ASSERT(uti);
    579581
  • trunk/Source/WebCore/platform/graphics/cg/ImageSourceCGMac.mm

    r205516 r220808  
    2727#import "ImageSourceCG.h"
    2828
     29#import "UTIUtilities.h"
    2930#import <wtf/RetainPtr.h>
    3031#import <wtf/text/WTFString.h>
     
    3839String MIMETypeForImageSourceType(const String& uti)
    3940{
    40     return adoptCF(UTTypeCopyPreferredTagWithClass(uti.createCFString().get(), kUTTagClassMIMEType)).get();
     41    return MIMETypeFromUTI(uti);
    4142}
    4243
  • trunk/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm

    r219595 r220808  
    4040#import "SecurityOrigin.h"
    4141#import "URL.h"
     42#import "UTIUtilities.h"
    4243#import "WebCoreSystemInterface.h"
    4344#import <objc/runtime.h>
     
    12441245        if (!uti)
    12451246            continue;
    1246         auto mime = adoptCF(UTTypeCopyPreferredTagWithClass(uti.get(), kUTTagClassMIMEType));
    1247         if (shouldRejectMIMEType(mime.get()))
     1247        auto mime = MIMETypeFromUTI(uti.get());
     1248        if (shouldRejectMIMEType(mime))
    12481249            continue;
    1249         if (mime)
    1250             set.add(mime.get());
     1250        if (!mime.isEmpty())
     1251            set.add(mime);
    12511252
    12521253        // -movieFileTypes: returns both file extensions and OSTypes. The later are surrounded by single
  • trunk/Source/WebCore/platform/ios/PasteboardIOS.mm

    r218508 r220808  
    4949#import "Text.h"
    5050#import "URL.h"
     51#import "UTIUtilities.h"
    5152#import "WebNSAttributedStringExtras.h"
    5253#import "markup.h"
     
    143144}
    144145
    145 String Pasteboard::resourceMIMEType(const NSString *mimeType)
    146 {
    147     return String(adoptCF(UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (CFStringRef)mimeType, NULL)).get());
     146String Pasteboard::resourceMIMEType(NSString *mimeType)
     147{
     148    return UTIFromMIMEType(mimeType);
    148149}
    149150
  • trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm

    r220124 r220808  
    294294
    295295    if (pasteboardImage.resourceData && !pasteboardImage.resourceMIMEType.isEmpty()) {
    296         auto utiOrMIMEType = pasteboardImage.resourceMIMEType.createCFString();
    297         if (!UTTypeIsDeclared(utiOrMIMEType.get()))
    298             utiOrMIMEType = adoptCF(UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, utiOrMIMEType.get(), nil));
     296        auto utiOrMIMEType = pasteboardImage.resourceMIMEType;
     297        if (!isDeclaredUTI(utiOrMIMEType))
     298            utiOrMIMEType = UTIFromMIMEType(utiOrMIMEType);
    299299
    300300        auto imageData = pasteboardImage.resourceData->createNSData();
    301         [itemsToRegister addData:imageData.get() forType:(NSString *)utiOrMIMEType.get()];
     301        [itemsToRegister addData:imageData.get() forType:(NSString *)utiOrMIMEType];
    302302        [itemsToRegister setEstimatedDisplayedSize:pasteboardImage.imageSize];
    303303        [itemsToRegister setSuggestedName:pasteboardImage.suggestedName];
  • trunk/Source/WebCore/platform/mac/PasteboardMac.mm

    r218508 r220808  
    4848#import "Text.h"
    4949#import "URL.h"
     50#import "UTIUtilities.h"
    5051#import "WebCoreNSStringExtras.h"
    5152#import "WebCoreSystemInterface.h"
     
    483484        return String();
    484485
    485     if (auto utiType = adoptCF(UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, lowercasedType.createCFString().get(), NULL))) {
    486         if (auto pbType = adoptCF(UTTypeCopyPreferredTagWithClass(utiType.get(), kUTTagClassNSPboardType)))
     486    auto utiType = UTIFromMIMEType(lowercasedType);
     487    if (!utiType.isEmpty()) {
     488        if (auto pbType = adoptCF(UTTypeCopyPreferredTagWithClass(utiType.createCFString().get(), kUTTagClassNSPboardType)))
    487489            return pbType.get();
    488490    }
  • trunk/Source/WebCore/platform/network/ios/WebCoreURLResponseIOS.mm

    r205516 r220808  
    5858                if (extension) {
    5959                    RetainPtr<CFStringRef> uti = adoptCF(UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, extension.get(), nullptr));
    60                     quickLookMIMEType = mimeTypeFromUTITree(uti.get());
     60                    String MIMEType = MIMETypeFromUTITree(uti.get());
     61                    if (!MIMEType.isEmpty())
     62                        quickLookMIMEType = MIMEType.createCFString();
    6163                }
    6264            }
  • trunk/Source/WebCore/platform/network/mac/UTIUtilities.h

    r200530 r220808  
    2727#define UTIUtilities_h
    2828
     29#import <wtf/Forward.h>
    2930#import <wtf/RetainPtr.h>
    3031
    3132namespace WebCore {
    32 RetainPtr<CFStringRef> mimeTypeFromUTITree(CFStringRef uti);
    33 RetainPtr<CFStringRef> UTIFromMIMEType(CFStringRef mime);
    34 bool isDeclaredUTI(CFStringRef UTI);
     33String MIMETypeFromUTI(const String&);
     34String MIMETypeFromUTITree(const String&);
     35String UTIFromMIMEType(const String&);
     36bool isDeclaredUTI(const String&);
    3537}
    3638
  • trunk/Source/WebCore/platform/network/mac/UTIUtilities.mm

    r205516 r220808  
    2626#import "config.h"
    2727#import "UTIUtilities.h"
     28#import <wtf/MainThread.h>
     29#import <wtf/TinyLRUCache.h>
     30#import <wtf/text/WTFString.h>
    2831
    2932#if PLATFORM(IOS)
     
    3336namespace WebCore {
    3437
    35 RetainPtr<CFStringRef> mimeTypeFromUTITree(CFStringRef uti)
     38String MIMETypeFromUTI(const String& uti)
    3639{
     40    return adoptCF(UTTypeCopyPreferredTagWithClass(uti.createCFString().get(), kUTTagClassMIMEType)).get();
     41}
     42
     43String MIMETypeFromUTITree(const String& uti)
     44{
     45    auto utiCF = uti.createCFString();
     46
    3747    // Check if this UTI has a MIME type.
    38     RetainPtr<CFStringRef> mimeType = adoptCF(UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType));
     48    RetainPtr<CFStringRef> mimeType = adoptCF(UTTypeCopyPreferredTagWithClass(utiCF.get(), kUTTagClassMIMEType));
    3949    if (mimeType)
    4050        return mimeType.get();
    4151
    4252    // If not, walk the ancestory of this UTI via its "ConformsTo" tags and return the first MIME type we find.
    43     RetainPtr<CFDictionaryRef> decl = adoptCF(UTTypeCopyDeclaration(uti));
     53    RetainPtr<CFDictionaryRef> decl = adoptCF(UTTypeCopyDeclaration(utiCF.get()));
    4454    if (!decl)
    45         return nil;
     55        return String();
    4656    CFTypeRef value = CFDictionaryGetValue(decl.get(), kUTTypeConformsToKey);
    4757    if (!value)
    48         return nil;
     58        return String();
    4959    CFTypeID typeID = CFGetTypeID(value);
    5060
    5161    if (typeID == CFStringGetTypeID())
    52         return mimeTypeFromUTITree((CFStringRef)value);
     62        return MIMETypeFromUTITree((CFStringRef)value);
    5363
    5464    if (typeID == CFArrayGetTypeID()) {
     
    5666        CFIndex count = CFArrayGetCount(newTypes);
    5767        for (CFIndex i = 0; i < count; ++i) {
    58         CFTypeRef object = CFArrayGetValueAtIndex(newTypes, i);
    59         if (CFGetTypeID(object) != CFStringGetTypeID())
    60             continue;
     68            CFTypeRef object = CFArrayGetValueAtIndex(newTypes, i);
     69            if (CFGetTypeID(object) != CFStringGetTypeID())
     70                continue;
    6171
    62         if (RetainPtr<CFStringRef> mimeType = mimeTypeFromUTITree((CFStringRef)object))
    63             return mimeType;
     72            String mimeType = MIMETypeFromUTITree((CFStringRef)object);
     73            if (!mimeType.isEmpty())
     74                return mimeType;
    6475        }
    6576    }
    6677
    67     return nil;
     78    return String();
    6879}
    6980
    70 RetainPtr<CFStringRef> UTIFromMIMEType(CFStringRef mime)
     81struct UTIFromMIMETypeCachePolicy : TinyLRUCachePolicy<String, String> {
     82public:
     83    static String createValueForKey(const String& key)
     84    {
     85        return String(adoptCF(UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, key.createCFString().get(), 0)).get());
     86    }
     87};
     88
     89String UTIFromMIMEType(const String& mimeType)
    7190{
    72     RetainPtr<CFStringRef> uti = adoptCF(UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mime, 0));
    73     return uti;
     91    ASSERT(isMainThread());
     92    static NeverDestroyed<TinyLRUCache<String, String, 16, UTIFromMIMETypeCachePolicy>> cache;
     93    return cache.get().get(mimeType);
    7494}
    7595
    76 bool isDeclaredUTI(CFStringRef UTI)
     96bool isDeclaredUTI(const String& UTI)
    7797{
    78     return UTTypeIsDeclared(UTI);
     98    return UTTypeIsDeclared(UTI.createCFString().get());
    7999}
    80100
  • trunk/Source/WebCore/platform/network/mac/WebCoreURLResponse.mm

    r207585 r220808  
    304304                CFStringLowercase(mutableExtension, NULL);
    305305                extension = adoptCF(mutableExtension);
    306                 result = (CFStringRef) CFDictionaryGetValue(extensionMap, extension.get());
     306                result = (CFStringRef)CFDictionaryGetValue(extensionMap, extension.get());
    307307               
    308308                if (!result) {
     
    310310                    // looking up the file extension in the UTI maps.
    311311                    RetainPtr<CFStringRef> uti = adoptCF(UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, extension.get(), 0));
    312                     result = mimeTypeFromUTITree(uti.get());
     312                    String MIMEType = MIMETypeFromUTITree(uti.get());
     313                    if (!MIMEType.isEmpty())
     314                        result = MIMEType.createCFString();
    313315                }
    314316            }
  • trunk/Source/WebCore/rendering/RenderThemeIOS.mm

    r220506 r220808  
    16171617    String attachmentType = attachment.attachmentElement().attachmentType();
    16181618    if (!attachmentType.isEmpty()) {
    1619         auto attachmentTypeCF = attachmentType.createCFString();
    1620         RetainPtr<CFStringRef> UTI;
    1621         if (isDeclaredUTI(attachmentTypeCF.get()))
    1622             UTI = attachmentTypeCF;
     1619        String UTI;
     1620        if (isDeclaredUTI(attachmentType))
     1621            UTI = attachmentType;
    16231622        else
    1624             UTI = UTIFromMIMEType(attachmentTypeCF.get());
    1625 
    1626         [documentInteractionController setUTI:static_cast<NSString *>(UTI.get())];
     1623            UTI = UTIFromMIMEType(attachmentType);
     1624
     1625        [documentInteractionController setUTI:static_cast<NSString *>(UTI)];
    16271626    }
    16281627
  • trunk/Source/WebCore/rendering/RenderThemeMac.mm

    r220506 r220808  
    24212421                return icon;
    24222422        } else {
    2423             auto attachmentTypeCF = attachmentType.createCFString();
    2424             RetainPtr<CFStringRef> UTI;
    2425             if (isDeclaredUTI(attachmentTypeCF.get()))
    2426                 UTI = attachmentTypeCF;
     2423            String UTI;
     2424            if (isDeclaredUTI(attachmentType))
     2425                UTI = attachmentType;
    24272426            else
    2428                 UTI = UTIFromMIMEType(attachmentTypeCF.get());
    2429 
    2430             if (auto icon = Icon::createIconForUTI(UTI.get()))
     2427                UTI = UTIFromMIMEType(attachmentType);
     2428
     2429            if (auto icon = Icon::createIconForUTI(UTI))
    24312430                return icon;
    24322431        }
Note: See TracChangeset for help on using the changeset viewer.