Changeset 215686 in webkit


Ignore:
Timestamp:
Apr 24, 2017, 10:31:05 AM (8 years ago)
Author:
achristensen@apple.com
Message:

Reduce copies and allocations in SharedBuffer::append
https://bugs.webkit.org/show_bug.cgi?id=170956

Reviewed by Andreas Kling.

Source/JavaScriptCore:

  • runtime/ArrayBuffer.h:

Source/WebCore:

SharedBuffer was a mess of different data structures added over the years.
SharedBuffer::append would allocate large Vector<char>s and call memcpy, and that
is inefficient and causes crashes when large allocations fail, and the allocations
and copies aren't even necessary. There were also const correctness problems in
ResourceLoader::addDataOrBuffer, and iterating a SharedBuffer was strange because
sometimes we don't want to add unnecessary copies.

These problems are solved by making SharedBuffer a Vector of read-only data segments,
which can be contained in various ways but we don't care because all we want to do is
read them. Appending SharedBuffers is now const correct because we just add to a
Vector<Ref<DataSegment>> and neither SharedBuffer can write to the data. Sometimes,
though, we want all the data to be in continuous memory, and if there are multiple
segments then the data needs to be copied once to a new segment. We should audit the
call sites of SharedBuffer::data and see if this is really necessary.

No change in functional behavior. Fewer copies of the data are made when buffering
data in the NetworkProcess. No extra memory is allocated for bytes we think we might
need to append in the future. Data is now only copied into one buffer lazily as needed,
which could slightly change when small delays from memcpy happen, but it's an overall
improvement. We could have a performance hit if we were to call append() then data()
then append() then data() etc. but that doesn't happen in WebKit because we call append
repeatedly when buffering the data then call data() once when reading the data.

  • editing/cocoa/EditorCocoa.mm:

(WebCore::archivedDataForAttributedString):
(WebCore::Editor::selectionInWebArchiveFormat):
(WebCore::Editor::dataInRTFDFormat):
(WebCore::Editor::dataInRTFFormat):

  • editing/ios/EditorIOS.mm:

(WebCore::Editor::WebContentReader::readURL):

  • editing/mac/EditorMac.mm:

(WebCore::Editor::imageInWebArchiveFormat):

  • loader/TextTrackLoader.cpp:

(WebCore::TextTrackLoader::processNewCueData):

  • loader/archive/cf/LegacyWebArchive.cpp:

(WebCore::LegacyWebArchive::createResource):

  • loader/cache/CachedResource.cpp:

(WebCore::CachedResource::tryReplaceEncodedData):

  • loader/cocoa/DiskCacheMonitorCocoa.mm:

(WebCore::DiskCacheMonitor::tryGetFileBackedSharedBufferFromCFURLCachedResponse):

  • platform/SharedBuffer.cpp:

(WebCore::SharedBuffer::SharedBuffer):
(WebCore::SharedBuffer::create):
(WebCore::SharedBuffer::combineToOneSegment):
(WebCore::SharedBuffer::data):
(WebCore::SharedBuffer::createArrayBuffer):
(WebCore::SharedBuffer::append):
(WebCore::SharedBuffer::clear):
(WebCore::SharedBuffer::copy):
(WebCore::SharedBuffer::DataSegment::data):
(WebCore::SharedBuffer::DataSegment::size):
(WebCore::segmentIndex): Deleted.
(WebCore::offsetInSegment): Deleted.
(WebCore::allocateSegment): Deleted.
(WebCore::freeSegment): Deleted.
(WebCore::SharedBuffer::~SharedBuffer): Deleted.
(WebCore::SharedBuffer::size): Deleted.
(WebCore::SharedBuffer::duplicateDataBufferIfNecessary): Deleted.
(WebCore::SharedBuffer::appendToDataBuffer): Deleted.
(WebCore::SharedBuffer::clearDataBuffer): Deleted.
(WebCore::SharedBuffer::copyBufferAndClear): Deleted.
(WebCore::SharedBuffer::buffer): Deleted.
(WebCore::SharedBuffer::getSomeData): Deleted.
(WebCore::SharedBuffer::maybeTransferMappedFileData): Deleted.
(WebCore::SharedBuffer::clearPlatformData): Deleted.
(WebCore::SharedBuffer::maybeTransferPlatformData): Deleted.
(WebCore::SharedBuffer::hasPlatformData): Deleted.
(WebCore::SharedBuffer::platformData): Deleted.
(WebCore::SharedBuffer::maybeAppendPlatformData): Deleted.

  • platform/SharedBuffer.h:

(WebCore::SharedBuffer::create): Deleted.
(WebCore::SharedBuffer::isEmpty): Deleted.

  • platform/SharedBufferChunkReader.cpp:

(WebCore::SharedBufferChunkReader::nextChunk):
(WebCore::SharedBufferChunkReader::peek):

  • platform/SharedBufferChunkReader.h:
  • platform/URLParser.cpp:

(WebCore::URLParser::URLParser):

  • platform/cf/KeyedEncoderCF.cpp:

(WebCore::KeyedEncoderCF::finishEncoding):

  • platform/cf/SharedBufferCF.cpp:

(WebCore::SharedBuffer::SharedBuffer):
(WebCore::SharedBuffer::createCFData):
(WebCore::SharedBuffer::create):
(WebCore::SharedBuffer::hintMemoryNotNeededSoon):
(WebCore::SharedBuffer::append):
(WebCore::SharedBuffer::wrapCFData): Deleted.
(WebCore::SharedBuffer::hasPlatformData): Deleted.
(WebCore::SharedBuffer::platformData): Deleted.
(WebCore::SharedBuffer::platformDataSize): Deleted.
(WebCore::SharedBuffer::maybeTransferPlatformData): Deleted.
(WebCore::SharedBuffer::clearPlatformData): Deleted.
(WebCore::SharedBuffer::tryReplaceContentsWithPlatformBuffer): Deleted.
(WebCore::SharedBuffer::maybeAppendPlatformData): Deleted.
(WebCore::SharedBuffer::copyBufferAndClear): Deleted.
(WebCore::SharedBuffer::copySomeDataFromDataArray): Deleted.
(WebCore::SharedBuffer::singleDataArrayBuffer): Deleted.
(WebCore::SharedBuffer::maybeAppendDataArray): Deleted.

  • platform/cocoa/NetworkExtensionContentFilter.mm:

(WebCore::NetworkExtensionContentFilter::replacementData):

  • platform/cocoa/ParentalControlsContentFilter.mm:

(WebCore::ParentalControlsContentFilter::replacementData):

  • platform/cocoa/SharedBufferCocoa.mm:

(-[WebCoreSharedBufferData initWithSharedBufferDataSegment:]):
(-[WebCoreSharedBufferData length]):
(-[WebCoreSharedBufferData bytes]):
(WebCore::SharedBuffer::create):
(WebCore::SharedBuffer::createCFData):
(WebCore::SharedBuffer::createFromReadingFile):
(WebCore::SharedBuffer::createNSDataArray):
(-[WebCoreSharedBufferData initWithSharedBufferDataBuffer:]): Deleted.
(WebCore::SharedBuffer::wrapNSData): Deleted.
(WebCore::SharedBuffer::existingCFData): Deleted.

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

(WebCore::WebCoreAVFResourceLoader::fulfillRequestWithResource):

  • platform/graphics/cocoa/FontPlatformDataCocoa.mm:

(WebCore::FontPlatformData::openTypeTable):

  • platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:

(ResourceHandleStreamingClient::didReceiveBuffer):

  • platform/graphics/mac/ImageMac.mm:

(WebCore::Image::loadPlatformResource):

  • platform/image-decoders/ImageDecoder.cpp:

(WebCore::ImageDecoder::create):

  • platform/image-decoders/png/PNGImageDecoder.cpp:

(WebCore::PNGImageReader::decode):

  • platform/ios/PlatformPasteboardIOS.mm:

(WebCore::PlatformPasteboard::readBuffer):

  • platform/mac/PasteboardMac.mm:

(WebCore::writeFileWrapperAsRTFDAttachment):
(WebCore::Pasteboard::write):

  • platform/mac/PlatformPasteboardMac.mm:

(WebCore::PlatformPasteboard::bufferForType):

  • platform/network/BlobResourceHandle.cpp:

(WebCore::BlobResourceHandle::notifyReceiveData):

  • platform/network/MIMEHeader.cpp:
  • platform/network/MIMEHeader.h:
  • platform/network/cf/ResourceHandleCFURLConnectionDelegateWithOperationQueue.cpp:

(WebCore::ResourceHandleCFURLConnectionDelegateWithOperationQueue::didReceiveData):

  • platform/network/cf/SynchronousResourceHandleCFURLConnectionDelegate.cpp:

(WebCore::SynchronousResourceHandleCFURLConnectionDelegate::didReceiveData):

  • platform/network/mac/WebCoreResourceHandleAsDelegate.mm:

(-[WebCoreResourceHandleAsDelegate connection:didReceiveData:lengthReceived:]):

  • platform/network/mac/WebCoreResourceHandleAsOperationQueueDelegate.mm:

(-[WebCoreResourceHandleAsOperationQueueDelegate connection:didReceiveData:lengthReceived:]):

  • platform/soup/SharedBufferSoup.cpp:

(WebCore::SharedBuffer::SharedBuffer):
(WebCore::SharedBuffer::createSoupBuffer):
(WebCore::SharedBuffer::clearPlatformData): Deleted.
(WebCore::SharedBuffer::maybeTransferPlatformData): Deleted.
(WebCore::SharedBuffer::hasPlatformData): Deleted.
(WebCore::SharedBuffer::platformData): Deleted.
(WebCore::SharedBuffer::platformDataSize): Deleted.
(WebCore::SharedBuffer::maybeAppendPlatformData): Deleted.
(WebCore::SharedBuffer::tryReplaceContentsWithPlatformBuffer): Deleted.

Source/WebKit/mac:

  • WebView/WebArchive.mm:

(-[WebArchive initWithData:]):

  • WebView/WebFrame.mm:

(-[WebFrame _loadData:MIMEType:textEncodingName:baseURL:unreachableURL:]):

  • WebView/WebResource.mm:

(-[WebResource initWithCoder:]):
(-[WebResource _initWithData:URL:MIMEType:textEncodingName:frameName:response:copyData:]):

Source/WebKit2:

  • NetworkProcess/cocoa/NetworkSessionCocoa.mm:

(-[WKNetworkSessionDelegate URLSession:dataTask:didReceiveData:]):

  • Platform/IPC/DataReference.cpp:

(IPC::SharedBufferDataReference::encode):

  • Shared/ShareableResource.cpp:

(WebKit::ShareableResource::wrapInSharedBuffer):

  • UIProcess/API/Cocoa/WKURLSchemeHandlerTask.mm:

(-[WKURLSchemeHandlerTaskImpl didReceiveData:]):

  • WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm:

(-[WKWebProcessPlugInBrowserContextController _setEditingDelegate:]):

  • WebProcess/Plugins/PDF/PDFPlugin.mm:

(WebKit::PDFPlugin::addArchiveResource):
(WebKit::PDFPlugin::liveResourceData):
(WebKit::PDFPlugin::writeItemsToPasteboard):

  • WebProcess/Plugins/PluginView.cpp:

(WebKit::PluginView::redeliverManualStream):

  • WebProcess/WebCoreSupport/mac/WebDragClientMac.mm:

(WebKit::WebDragClient::declareAndWriteDragImage):

  • WebProcess/WebPage/mac/WebPageMac.mm:

(WebKit::WebPage::cachedResponseDataForURL):

Tools:

  • TestWebKitAPI/Tests/WebCore/cocoa/SharedBuffer.mm:

(TestWebKitAPI::TEST_F):

Location:
trunk
Files:
58 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/Source/JavaScriptCore/ChangeLog

    r215683 r215686  
     12017-04-24  Alex Christensen  <achristensen@webkit.org>
     2
     3        Reduce copies and allocations in SharedBuffer::append
     4        https://bugs.webkit.org/show_bug.cgi?id=170956
     5
     6        Reviewed by Andreas Kling.
     7
     8        * runtime/ArrayBuffer.h:
     9
    1102017-04-24  Carlos Garcia Campos  <cgarcia@igalia.com>
    211
  • TabularUnified trunk/Source/JavaScriptCore/runtime/ArrayBuffer.h

    r212035 r215686  
    111111    JS_EXPORT_PRIVATE static RefPtr<ArrayBuffer> tryCreate(const void* source, unsigned byteLength);
    112112
    113     // Only for use by Uint8ClampedArray::createUninitialized and SharedBuffer::createArrayBuffer.
     113    // Only for use by Uint8ClampedArray::createUninitialized and SharedBuffer::tryCreateArrayBuffer.
    114114    JS_EXPORT_PRIVATE static Ref<ArrayBuffer> createUninitialized(unsigned numElements, unsigned elementByteSize);
    115115    JS_EXPORT_PRIVATE static RefPtr<ArrayBuffer> tryCreateUninitialized(unsigned numElements, unsigned elementByteSize);
  • TabularUnified trunk/Source/WebCore/ChangeLog

    r215685 r215686  
     12017-04-24  Alex Christensen  <achristensen@webkit.org>
     2
     3        Reduce copies and allocations in SharedBuffer::append
     4        https://bugs.webkit.org/show_bug.cgi?id=170956
     5
     6        Reviewed by Andreas Kling.
     7
     8        SharedBuffer was a mess of different data structures added over the years.
     9        SharedBuffer::append would allocate large Vector<char>s and call memcpy, and that
     10        is inefficient and causes crashes when large allocations fail, and the allocations
     11        and copies aren't even necessary.  There were also const correctness problems in
     12        ResourceLoader::addDataOrBuffer, and iterating a SharedBuffer was strange because
     13        sometimes we don't want to add unnecessary copies.
     14
     15        These problems are solved by making SharedBuffer a Vector of read-only data segments,
     16        which can be contained in various ways but we don't care because all we want to do is
     17        read them.  Appending SharedBuffers is now const correct because we just add to a
     18        Vector<Ref<DataSegment>> and neither SharedBuffer can write to the data.  Sometimes,
     19        though, we want all the data to be in continuous memory, and if there are multiple
     20        segments then the data needs to be copied once to a new segment.  We should audit the
     21        call sites of SharedBuffer::data and see if this is really necessary.
     22
     23        No change in functional behavior.  Fewer copies of the data are made when buffering
     24        data in the NetworkProcess.  No extra memory is allocated for bytes we think we might
     25        need to append in the future.  Data is now only copied into one buffer lazily as needed,
     26        which could slightly change when small delays from memcpy happen, but it's an overall
     27        improvement.  We could have a performance hit if we were to call append() then data()
     28        then append() then data() etc. but that doesn't happen in WebKit because we call append
     29        repeatedly when buffering the data then call data() once when reading the data.
     30
     31        * editing/cocoa/EditorCocoa.mm:
     32        (WebCore::archivedDataForAttributedString):
     33        (WebCore::Editor::selectionInWebArchiveFormat):
     34        (WebCore::Editor::dataInRTFDFormat):
     35        (WebCore::Editor::dataInRTFFormat):
     36        * editing/ios/EditorIOS.mm:
     37        (WebCore::Editor::WebContentReader::readURL):
     38        * editing/mac/EditorMac.mm:
     39        (WebCore::Editor::imageInWebArchiveFormat):
     40        * loader/TextTrackLoader.cpp:
     41        (WebCore::TextTrackLoader::processNewCueData):
     42        * loader/archive/cf/LegacyWebArchive.cpp:
     43        (WebCore::LegacyWebArchive::createResource):
     44        * loader/cache/CachedResource.cpp:
     45        (WebCore::CachedResource::tryReplaceEncodedData):
     46        * loader/cocoa/DiskCacheMonitorCocoa.mm:
     47        (WebCore::DiskCacheMonitor::tryGetFileBackedSharedBufferFromCFURLCachedResponse):
     48        * platform/SharedBuffer.cpp:
     49        (WebCore::SharedBuffer::SharedBuffer):
     50        (WebCore::SharedBuffer::create):
     51        (WebCore::SharedBuffer::combineToOneSegment):
     52        (WebCore::SharedBuffer::data):
     53        (WebCore::SharedBuffer::createArrayBuffer):
     54        (WebCore::SharedBuffer::append):
     55        (WebCore::SharedBuffer::clear):
     56        (WebCore::SharedBuffer::copy):
     57        (WebCore::SharedBuffer::DataSegment::data):
     58        (WebCore::SharedBuffer::DataSegment::size):
     59        (WebCore::segmentIndex): Deleted.
     60        (WebCore::offsetInSegment): Deleted.
     61        (WebCore::allocateSegment): Deleted.
     62        (WebCore::freeSegment): Deleted.
     63        (WebCore::SharedBuffer::~SharedBuffer): Deleted.
     64        (WebCore::SharedBuffer::size): Deleted.
     65        (WebCore::SharedBuffer::duplicateDataBufferIfNecessary): Deleted.
     66        (WebCore::SharedBuffer::appendToDataBuffer): Deleted.
     67        (WebCore::SharedBuffer::clearDataBuffer): Deleted.
     68        (WebCore::SharedBuffer::copyBufferAndClear): Deleted.
     69        (WebCore::SharedBuffer::buffer): Deleted.
     70        (WebCore::SharedBuffer::getSomeData): Deleted.
     71        (WebCore::SharedBuffer::maybeTransferMappedFileData): Deleted.
     72        (WebCore::SharedBuffer::clearPlatformData): Deleted.
     73        (WebCore::SharedBuffer::maybeTransferPlatformData): Deleted.
     74        (WebCore::SharedBuffer::hasPlatformData): Deleted.
     75        (WebCore::SharedBuffer::platformData): Deleted.
     76        (WebCore::SharedBuffer::maybeAppendPlatformData): Deleted.
     77        * platform/SharedBuffer.h:
     78        (WebCore::SharedBuffer::create): Deleted.
     79        (WebCore::SharedBuffer::isEmpty): Deleted.
     80        * platform/SharedBufferChunkReader.cpp:
     81        (WebCore::SharedBufferChunkReader::nextChunk):
     82        (WebCore::SharedBufferChunkReader::peek):
     83        * platform/SharedBufferChunkReader.h:
     84        * platform/URLParser.cpp:
     85        (WebCore::URLParser::URLParser):
     86        * platform/cf/KeyedEncoderCF.cpp:
     87        (WebCore::KeyedEncoderCF::finishEncoding):
     88        * platform/cf/SharedBufferCF.cpp:
     89        (WebCore::SharedBuffer::SharedBuffer):
     90        (WebCore::SharedBuffer::createCFData):
     91        (WebCore::SharedBuffer::create):
     92        (WebCore::SharedBuffer::hintMemoryNotNeededSoon):
     93        (WebCore::SharedBuffer::append):
     94        (WebCore::SharedBuffer::wrapCFData): Deleted.
     95        (WebCore::SharedBuffer::hasPlatformData): Deleted.
     96        (WebCore::SharedBuffer::platformData): Deleted.
     97        (WebCore::SharedBuffer::platformDataSize): Deleted.
     98        (WebCore::SharedBuffer::maybeTransferPlatformData): Deleted.
     99        (WebCore::SharedBuffer::clearPlatformData): Deleted.
     100        (WebCore::SharedBuffer::tryReplaceContentsWithPlatformBuffer): Deleted.
     101        (WebCore::SharedBuffer::maybeAppendPlatformData): Deleted.
     102        (WebCore::SharedBuffer::copyBufferAndClear): Deleted.
     103        (WebCore::SharedBuffer::copySomeDataFromDataArray): Deleted.
     104        (WebCore::SharedBuffer::singleDataArrayBuffer): Deleted.
     105        (WebCore::SharedBuffer::maybeAppendDataArray): Deleted.
     106        * platform/cocoa/NetworkExtensionContentFilter.mm:
     107        (WebCore::NetworkExtensionContentFilter::replacementData):
     108        * platform/cocoa/ParentalControlsContentFilter.mm:
     109        (WebCore::ParentalControlsContentFilter::replacementData):
     110        * platform/cocoa/SharedBufferCocoa.mm:
     111        (-[WebCoreSharedBufferData initWithSharedBufferDataSegment:]):
     112        (-[WebCoreSharedBufferData length]):
     113        (-[WebCoreSharedBufferData bytes]):
     114        (WebCore::SharedBuffer::create):
     115        (WebCore::SharedBuffer::createCFData):
     116        (WebCore::SharedBuffer::createFromReadingFile):
     117        (WebCore::SharedBuffer::createNSDataArray):
     118        (-[WebCoreSharedBufferData initWithSharedBufferDataBuffer:]): Deleted.
     119        (WebCore::SharedBuffer::wrapNSData): Deleted.
     120        (WebCore::SharedBuffer::existingCFData): Deleted.
     121        * platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm:
     122        (WebCore::WebCoreAVFResourceLoader::fulfillRequestWithResource):
     123        * platform/graphics/cocoa/FontPlatformDataCocoa.mm:
     124        (WebCore::FontPlatformData::openTypeTable):
     125        * platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:
     126        (ResourceHandleStreamingClient::didReceiveBuffer):
     127        * platform/graphics/mac/ImageMac.mm:
     128        (WebCore::Image::loadPlatformResource):
     129        * platform/image-decoders/ImageDecoder.cpp:
     130        (WebCore::ImageDecoder::create):
     131        * platform/image-decoders/png/PNGImageDecoder.cpp:
     132        (WebCore::PNGImageReader::decode):
     133        * platform/ios/PlatformPasteboardIOS.mm:
     134        (WebCore::PlatformPasteboard::readBuffer):
     135        * platform/mac/PasteboardMac.mm:
     136        (WebCore::writeFileWrapperAsRTFDAttachment):
     137        (WebCore::Pasteboard::write):
     138        * platform/mac/PlatformPasteboardMac.mm:
     139        (WebCore::PlatformPasteboard::bufferForType):
     140        * platform/network/BlobResourceHandle.cpp:
     141        (WebCore::BlobResourceHandle::notifyReceiveData):
     142        * platform/network/MIMEHeader.cpp:
     143        * platform/network/MIMEHeader.h:
     144        * platform/network/cf/ResourceHandleCFURLConnectionDelegateWithOperationQueue.cpp:
     145        (WebCore::ResourceHandleCFURLConnectionDelegateWithOperationQueue::didReceiveData):
     146        * platform/network/cf/SynchronousResourceHandleCFURLConnectionDelegate.cpp:
     147        (WebCore::SynchronousResourceHandleCFURLConnectionDelegate::didReceiveData):
     148        * platform/network/mac/WebCoreResourceHandleAsDelegate.mm:
     149        (-[WebCoreResourceHandleAsDelegate connection:didReceiveData:lengthReceived:]):
     150        * platform/network/mac/WebCoreResourceHandleAsOperationQueueDelegate.mm:
     151        (-[WebCoreResourceHandleAsOperationQueueDelegate connection:didReceiveData:lengthReceived:]):
     152        * platform/soup/SharedBufferSoup.cpp:
     153        (WebCore::SharedBuffer::SharedBuffer):
     154        (WebCore::SharedBuffer::createSoupBuffer):
     155        (WebCore::SharedBuffer::clearPlatformData): Deleted.
     156        (WebCore::SharedBuffer::maybeTransferPlatformData): Deleted.
     157        (WebCore::SharedBuffer::hasPlatformData): Deleted.
     158        (WebCore::SharedBuffer::platformData): Deleted.
     159        (WebCore::SharedBuffer::platformDataSize): Deleted.
     160        (WebCore::SharedBuffer::maybeAppendPlatformData): Deleted.
     161        (WebCore::SharedBuffer::tryReplaceContentsWithPlatformBuffer): Deleted.
     162
    11632017-04-24  Dan Bernstein  <mitz@apple.com>
    2164
  • TabularUnified trunk/Source/WebCore/Modules/encryptedmedia/MediaKeySession.cpp

    r212110 r215686  
    600600    //    interface with its type attribute set to message and its isTrusted attribute initialized to true, and dispatch it at the
    601601    //    session.
    602     auto messageEvent = MediaKeyMessageEvent::create(eventNames().messageEvent, {messageType, message.createArrayBuffer()}, Event::IsTrusted::Yes);
     602    auto messageEvent = MediaKeyMessageEvent::create(eventNames().messageEvent, {messageType, message.tryCreateArrayBuffer()}, Event::IsTrusted::Yes);
    603603    m_eventQueue.enqueueEvent(WTFMove(messageEvent));
    604604}
  • TabularUnified trunk/Source/WebCore/Modules/fetch/FetchBodyConsumer.cpp

    r209390 r215686  
    126126        return ArrayBuffer::tryCreate(nullptr, 0);
    127127
    128     auto arrayBuffer = m_buffer->createArrayBuffer();
     128    auto arrayBuffer = m_buffer->tryCreateArrayBuffer();
    129129    m_buffer = nullptr;
    130130    return arrayBuffer;
  • TabularUnified trunk/Source/WebCore/Modules/fetch/FetchResponse.cpp

    r215429 r215686  
    279279    RefPtr<SharedBuffer> data = m_bodyLoader->startStreaming();
    280280    if (data) {
    281         if (!m_readableStreamSource->enqueue(data->createArrayBuffer())) {
     281        if (!m_readableStreamSource->enqueue(data->tryCreateArrayBuffer())) {
    282282            stop();
    283283            return;
  • TabularUnified trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r215672 r215686  
    16201620                37C238221098C84200EF9F72 /* ComplexTextControllerCoreText.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37C238201098C84200EF9F72 /* ComplexTextControllerCoreText.mm */; };
    16211621                37D456FD1A9A50D8003330A1 /* LocalizableStrings.pm in Copy Scripts */ = {isa = PBXBuildFile; fileRef = 37D456FB1A9A50B6003330A1 /* LocalizableStrings.pm */; };
    1622                 37DDCD9413844FD50008B793 /* MIMEHeader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37DDCD9213844FD50008B793 /* MIMEHeader.cpp */; };
    1623                 37DDCD9513844FD50008B793 /* MIMEHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 37DDCD9313844FD50008B793 /* MIMEHeader.h */; };
    16241622                37DDCD9E13844FFA0008B793 /* Archive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37DDCD9D13844FFA0008B793 /* Archive.cpp */; };
    1625                 37DDCDA51384501C0008B793 /* MHTMLArchive.h in Headers */ = {isa = PBXBuildFile; fileRef = 37DDCDA11384501C0008B793 /* MHTMLArchive.h */; };
    1626                 37DDCDA71384501C0008B793 /* MHTMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 37DDCDA31384501C0008B793 /* MHTMLParser.h */; };
    16271623                37E3524B12450C5200BAF5D9 /* InputType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37E3524A12450C5200BAF5D9 /* InputType.cpp */; };
    16281624                37E3524D12450C6600BAF5D9 /* InputType.h in Headers */ = {isa = PBXBuildFile; fileRef = 37E3524C12450C6600BAF5D9 /* InputType.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    40524048                97AABD2C14FA09D5007457AE /* WorkerThreadableWebSocketChannel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97AABD1114FA09D5007457AE /* WorkerThreadableWebSocketChannel.cpp */; };
    40534049                97AABD2D14FA09D5007457AE /* WorkerThreadableWebSocketChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 97AABD1214FA09D5007457AE /* WorkerThreadableWebSocketChannel.h */; settings = {ATTRIBUTES = (Private, ); }; };
    4054                 97B1F02E13B025CA00F5103F /* SharedBufferChunkReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37569E0013AF172C00CDBA8E /* SharedBufferChunkReader.cpp */; };
    4055                 97B1F02F13B025D200F5103F /* SharedBufferChunkReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 37569E0213AF172C00CDBA8E /* SharedBufferChunkReader.h */; };
    40564050                97B38E27151C4271004622E9 /* DOMWindowNotifications.h in Headers */ = {isa = PBXBuildFile; fileRef = 97B38E24151C4264004622E9 /* DOMWindowNotifications.h */; };
    40574051                97B38E28151C4273004622E9 /* DOMWindowNotifications.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97B38E23151C4264004622E9 /* DOMWindowNotifications.cpp */; };
     
    92219215                372C00C3129611F1005C9575 /* TextBoundaries.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextBoundaries.cpp; sourceTree = "<group>"; };
    92229216                372C00D8129619F8005C9575 /* FindOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FindOptions.h; sourceTree = "<group>"; };
    9223                 37569E0013AF172C00CDBA8E /* SharedBufferChunkReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SharedBufferChunkReader.cpp; sourceTree = "<group>"; };
    9224                 37569E0213AF172C00CDBA8E /* SharedBufferChunkReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharedBufferChunkReader.h; sourceTree = "<group>"; };
    92259217                375CD231119D43C800A2A859 /* Hyphenation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Hyphenation.h; sourceTree = "<group>"; };
    92269218                376DCCE013B4F966002EBEFC /* TextRun.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextRun.cpp; sourceTree = "<group>"; };
     
    92479239                37C238201098C84200EF9F72 /* ComplexTextControllerCoreText.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ComplexTextControllerCoreText.mm; sourceTree = "<group>"; };
    92489240                37D456FB1A9A50B6003330A1 /* LocalizableStrings.pm */ = {isa = PBXFileReference; lastKnownFileType = text.script.perl; path = LocalizableStrings.pm; sourceTree = "<group>"; };
    9249                 37DDCD9213844FD50008B793 /* MIMEHeader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MIMEHeader.cpp; sourceTree = "<group>"; };
    9250                 37DDCD9313844FD50008B793 /* MIMEHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIMEHeader.h; sourceTree = "<group>"; };
    92519241                37DDCD9D13844FFA0008B793 /* Archive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Archive.cpp; sourceTree = "<group>"; };
    9252                 37DDCDA11384501C0008B793 /* MHTMLArchive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHTMLArchive.h; sourceTree = "<group>"; };
    9253                 37DDCDA31384501C0008B793 /* MHTMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHTMLParser.h; sourceTree = "<group>"; };
    92549242                37E3524A12450C5200BAF5D9 /* InputType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InputType.cpp; sourceTree = "<group>"; };
    92559243                37E3524C12450C6600BAF5D9 /* InputType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputType.h; sourceTree = "<group>"; };
     
    1754617534                        sourceTree = "<group>";
    1754717535                };
    17548                 37DDCD9F1384501C0008B793 /* mhtml */ = {
    17549                         isa = PBXGroup;
    17550                         children = (
    17551                                 37DDCDA11384501C0008B793 /* MHTMLArchive.h */,
    17552                                 37DDCDA31384501C0008B793 /* MHTMLParser.h */,
    17553                         );
    17554                         path = mhtml;
    17555                         sourceTree = "<group>";
    17556                 };
    1755717536                4150F9ED12B6E0990008C860 /* shadow */ = {
    1755817537                        isa = PBXGroup;
     
    1838218361                        children = (
    1838318362                                512DD8E90D91E6AF000F89EE /* cf */,
    18384                                 37DDCD9F1384501C0008B793 /* mhtml */,
    1838518363                                37DDCD9D13844FFA0008B793 /* Archive.cpp */,
    1838618364                                512DD8EC0D91E6AF000F89EE /* Archive.h */,
     
    1889318871                                514C765D0CE923A1007EF3CD /* HTTPParsers.cpp */,
    1889418872                                514C765E0CE923A1007EF3CD /* HTTPParsers.h */,
    18895                                 37DDCD9213844FD50008B793 /* MIMEHeader.cpp */,
    18896                                 37DDCD9313844FD50008B793 /* MIMEHeader.h */,
    1889718873                                628D214B12131ED10055DCFC /* NetworkingContext.h */,
    1889818874                                8A81BF8411DCFD9000DA2B98 /* NetworkLoadMetrics.h */,
     
    2404324019                                1A4A954B0B4EDCCB002D8C3C /* SharedBuffer.cpp */,
    2404424020                                1A4A954C0B4EDCCB002D8C3C /* SharedBuffer.h */,
    24045                                 37569E0013AF172C00CDBA8E /* SharedBufferChunkReader.cpp */,
    24046                                 37569E0213AF172C00CDBA8E /* SharedBufferChunkReader.h */,
    2404724021                                93309EA0099EB78C0056E581 /* SharedTimer.h */,
    2404824022                                4B3043C60AE0370300A82647 /* Sound.h */,
     
    2854128515                                E1ADECBF0E76ACF1004A1A5E /* MessagePort.h in Headers */,
    2854228516                                41BF700C0FE86F49005E8DEC /* MessagePortChannel.h in Headers */,
    28543                                 37DDCDA51384501C0008B793 /* MHTMLArchive.h in Headers */,
    28544                                 37DDCDA71384501C0008B793 /* MHTMLParser.h in Headers */,
    2854528517                                53B895AF19DC7ED9009CAA93 /* Microtasks.h in Headers */,
    28546                                 37DDCD9513844FD50008B793 /* MIMEHeader.h in Headers */,
    2854728518                                BC772C4F0C4EB3040083285F /* MIMETypeRegistry.h in Headers */,
    2854828519                                52F10866162B6DA8009AC81E /* MixedContentChecker.h in Headers */,
     
    2923529206                                FD1AF1501656F15100C6D4F7 /* ShapeValue.h in Headers */,
    2923629207                                1A4A954E0B4EDCCB002D8C3C /* SharedBuffer.h in Headers */,
    29237                                 97B1F02F13B025D200F5103F /* SharedBufferChunkReader.h in Headers */,
    2923829208                                93309EA3099EB78C0056E581 /* SharedTimer.h in Headers */,
    2923929209                                E48944A3180B57D800F165D8 /* SimpleLineLayout.h in Headers */,
     
    3254632516                                E1ADECC00E76ACF1004A1A5E /* MessagePort.cpp in Sources */,
    3254732517                                CB8CF0181A9358D4000D510B /* Microtasks.cpp in Sources */,
    32548                                 37DDCD9413844FD50008B793 /* MIMEHeader.cpp in Sources */,
    3254932518                                BC772C4E0C4EB3040083285F /* MIMETypeRegistry.cpp in Sources */,
    3255032519                                C53D39341C978A45007F3AE9 /* MIMETypeRegistryCocoa.mm in Sources */,
     
    3307933048                                1A4A954D0B4EDCCB002D8C3C /* SharedBuffer.cpp in Sources */,
    3308033049                                512DD8E30D91E2B4000F89EE /* SharedBufferCF.cpp in Sources */,
    33081                                 97B1F02E13B025CA00F5103F /* SharedBufferChunkReader.cpp in Sources */,
    3308233050                                1A4A95520B4EDCFF002D8C3C /* SharedBufferCocoa.mm in Sources */,
    3308333051                                163E88F7118A39D200ED9231 /* SimpleFontDataCoreText.cpp in Sources */,
  • TabularUnified trunk/Source/WebCore/editing/cocoa/EditorCocoa.mm

    r215661 r215686  
    158158        return nullptr;
    159159
    160     return SharedBuffer::wrapNSData([NSKeyedArchiver archivedDataWithRootObject:attributedString]);
     160    return SharedBuffer::create([NSKeyedArchiver archivedDataWithRootObject:attributedString]);
    161161}
    162162
     
    206206    if (!archive)
    207207        return nullptr;
    208     return SharedBuffer::wrapCFData(archive->rawDataRepresentation().get());
     208    return SharedBuffer::create(archive->rawDataRepresentation().get());
    209209}
    210210
     
    277277
    278278    BEGIN_BLOCK_OBJC_EXCEPTIONS;
    279     return SharedBuffer::wrapNSData([string RTFDFromRange:NSMakeRange(0, length) documentAttributes:@{ }]);
     279    return SharedBuffer::create([string RTFDFromRange:NSMakeRange(0, length) documentAttributes:@{ }]);
    280280    END_BLOCK_OBJC_EXCEPTIONS;
    281281
     
    290290
    291291    BEGIN_BLOCK_OBJC_EXCEPTIONS;
    292     return SharedBuffer::wrapNSData([string RTFFromRange:NSMakeRange(0, length) documentAttributes:@{ }]);
     292    return SharedBuffer::create([string RTFFromRange:NSMakeRange(0, length) documentAttributes:@{ }]);
    293293    END_BLOCK_OBJC_EXCEPTIONS;
    294294
  • TabularUnified trunk/Source/WebCore/editing/ios/EditorIOS.mm

    r215661 r215686  
    340340        NSData *data = [NSData dataWithContentsOfFile:localPath];
    341341        if (UTTypeConformsTo((CFStringRef)fileType.get(), kUTTypePNG)) {
    342             addFragment(frame.editor().createFragmentForImageResourceAndAddResource(ArchiveResource::create(SharedBuffer::wrapNSData([[data copy] autorelease]), URL::fakeURLWithRelativePart("image.png"), @"image/png", emptyString(), emptyString())));
     342            addFragment(frame.editor().createFragmentForImageResourceAndAddResource(ArchiveResource::create(SharedBuffer::create([[data copy] autorelease]), URL::fakeURLWithRelativePart("image.png"), @"image/png", emptyString(), emptyString())));
    343343            return fragment;
    344344        } else if (UTTypeConformsTo((CFStringRef)fileType.get(), kUTTypeJPEG)) {
    345             addFragment(frame.editor().createFragmentForImageResourceAndAddResource(ArchiveResource::create(SharedBuffer::wrapNSData([[data copy] autorelease]), URL::fakeURLWithRelativePart("image.jpg"), @"image/jpg", emptyString(), emptyString())));
     345            addFragment(frame.editor().createFragmentForImageResourceAndAddResource(ArchiveResource::create(SharedBuffer::create([[data copy] autorelease]), URL::fakeURLWithRelativePart("image.jpg"), @"image/jpg", emptyString(), emptyString())));
    346346            return fragment;
    347347        }
  • TabularUnified trunk/Source/WebCore/editing/mac/EditorMac.mm

    r215661 r215686  
    205205    if (!archive)
    206206        return nullptr;
    207     return SharedBuffer::wrapCFData(archive->rawDataRepresentation().get());
     207    return SharedBuffer::create(archive->rawDataRepresentation().get());
    208208}
    209209
  • TabularUnified trunk/Source/WebCore/loader/TextTrackLoader.cpp

    r215661 r215686  
    9292        m_cueParser = std::make_unique<WebVTTParser>(static_cast<WebVTTParserClient*>(this), m_scriptExecutionContext);
    9393
    94     const char* data;
    95     unsigned length;
    96 
    97     while ((length = buffer->getSomeData(data, m_parseOffset))) {
    98         m_cueParser->parseBytes(data, length);
    99         m_parseOffset += length;
     94    auto bytesToSkip = m_parseOffset;
     95    for (const auto& segment : *buffer) {
     96        if (bytesToSkip > segment->size()) {
     97            bytesToSkip -= segment->size();
     98            continue;
     99        }
     100        m_cueParser->parseBytes(segment->data() + bytesToSkip, segment->size() - bytesToSkip);
     101        bytesToSkip = 0;
     102        m_parseOffset += segment->size();
    100103    }
    101104}
  • TabularUnified trunk/Source/WebCore/loader/archive/cf/LegacyWebArchive.cpp

    r215661 r215686  
    222222    }
    223223
    224     return ArchiveResource::create(SharedBuffer::wrapCFData(resourceData), URL(URL(), url), mimeType, textEncoding, frameName, response);
     224    return ArchiveResource::create(SharedBuffer::create(resourceData), URL(URL(), url), mimeType, textEncoding, frameName, response);
    225225}
    226226
  • TabularUnified trunk/Source/WebCore/loader/cache/CachedResource.cpp

    r215661 r215686  
    851851        return;
    852852
    853     if (m_data->tryReplaceContentsWithPlatformBuffer(newBuffer))
    854         didReplaceSharedBufferContents();
    855 }
    856 
    857 #endif
    858 
    859 }
     853    m_data->clear();
     854    m_data->append(newBuffer);
     855    didReplaceSharedBufferContents();
     856}
     857
     858#endif
     859
     860}
  • TabularUnified trunk/Source/WebCore/loader/cocoa/DiskCacheMonitorCocoa.mm

    r215661 r215686  
    4949        return nullptr;
    5050
    51     return SharedBuffer::wrapCFData(data);
     51    return SharedBuffer::create(data);
    5252}
    5353
  • TabularUnified trunk/Source/WebCore/platform/SharedBuffer.cpp

    r215661 r215686  
    3232#include <wtf/unicode/UTF8.h>
    3333
     34#if USE(SOUP)
     35#include "GUniquePtrSoup.h"
     36#endif
     37
    3438namespace WebCore {
    3539
    36 #if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
    37 
    38 static const unsigned segmentSize = 0x1000;
    39 static const unsigned segmentPositionMask = 0x0FFF;
    40 
    41 static inline unsigned segmentIndex(unsigned position)
    42 {
    43     return position / segmentSize;
    44 }
    45 
    46 static inline unsigned offsetInSegment(unsigned position)
    47 {
    48     return position & segmentPositionMask;
    49 }
    50 
    51 static inline char* allocateSegment() WARN_UNUSED_RETURN;
    52 static inline char* allocateSegment()
    53 {
    54     return static_cast<char*>(fastMalloc(segmentSize));
    55 }
    56 
    57 static inline void freeSegment(char* p)
    58 {
    59     fastFree(p);
    60 }
    61 
    62 #endif
    63 
    64 SharedBuffer::SharedBuffer()
    65     : m_buffer(adoptRef(*new DataBuffer))
    66 {
    67 }
    68 
    69 SharedBuffer::SharedBuffer(const char* data, unsigned size)
    70     : m_buffer(adoptRef(*new DataBuffer))
     40SharedBuffer::SharedBuffer(const char* data, size_t size)
    7141{
    7242    append(data, size);
    7343}
    7444
    75 SharedBuffer::SharedBuffer(const unsigned char* data, unsigned size)
    76     : m_buffer(adoptRef(*new DataBuffer))
     45SharedBuffer::SharedBuffer(const unsigned char* data, size_t size)
    7746{
    7847    append(reinterpret_cast<const char*>(data), size);
     
    8049
    8150SharedBuffer::SharedBuffer(MappedFileData&& fileData)
    82     : m_buffer(adoptRef(*new DataBuffer))
    83     , m_fileData(WTFMove(fileData))
    84 {
    85 }
    86 
    87 SharedBuffer::~SharedBuffer()
    88 {
    89     clear();
     51    : m_size(fileData.size())
     52{
     53    m_segments.append(DataSegment::create(WTFMove(fileData)));
     54}
     55
     56SharedBuffer::SharedBuffer(Vector<char>&& data)
     57{
     58    append(WTFMove(data));
    9059}
    9160
     
    10372Ref<SharedBuffer> SharedBuffer::create(Vector<char>&& vector)
    10473{
    105     auto buffer = create();
    106     buffer->m_buffer->data = WTFMove(vector);
    107     buffer->m_size = buffer->m_buffer->data.size();
    108     return buffer;
    109 }
    110 
    111 unsigned SharedBuffer::size() const
    112 {
    113     if (hasPlatformData())
    114         return platformDataSize();
    115    
    116     if (m_fileData)
    117         return m_fileData.size();
    118 
    119     return m_size;
     74    return adoptRef(*new SharedBuffer(WTFMove(vector)));
     75}
     76
     77void SharedBuffer::combineIntoOneSegment() const
     78{
     79    if (m_segments.size() <= 1)
     80        return;
     81
     82    Vector<char> combinedData;
     83    combinedData.reserveInitialCapacity(m_size);
     84    for (const auto& segment : m_segments)
     85        combinedData.append(segment->data(), segment->size());
     86    ASSERT(combinedData.size() == m_size);
     87    m_segments.clear();
     88    m_segments.append(DataSegment::create(WTFMove(combinedData)));
     89    ASSERT(m_segments.size() == 1);
    12090}
    12191
    12292const char* SharedBuffer::data() const
    12393{
    124     if (hasPlatformData())
    125         return platformData();
    126 
    127     if (m_fileData)
    128         return static_cast<const char*>(m_fileData.data());
    129 
    130 #if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
    131     if (const char* buffer = singleDataArrayBuffer())
    132         return buffer;
    133 #endif
    134 
    135     return this->buffer().data();
    136 }
    137 
    138 RefPtr<ArrayBuffer> SharedBuffer::createArrayBuffer() const
     94    if (!m_segments.size())
     95        return nullptr;
     96    combineIntoOneSegment();
     97    return m_segments[0]->data();
     98}
     99
     100RefPtr<ArrayBuffer> SharedBuffer::tryCreateArrayBuffer() const
    139101{
    140102    RefPtr<ArrayBuffer> arrayBuffer = ArrayBuffer::createUninitialized(static_cast<unsigned>(size()), sizeof(char));
    141103    if (!arrayBuffer) {
    142         WTFLogAlways("SharedBuffer::createArrayBuffer Unable to create buffer. Requested size was %d x %lu\n", size(), sizeof(char));
     104        WTFLogAlways("SharedBuffer::tryCreateArrayBuffer Unable to create buffer. Requested size was %d x %lu\n", size(), sizeof(char));
    143105        return nullptr;
    144106    }
    145107
    146     const char* segment = 0;
    147     unsigned position = 0;
    148     while (unsigned segmentSize = getSomeData(segment, position)) {
    149         memcpy(static_cast<char*>(arrayBuffer->data()) + position, segment, segmentSize);
    150         position += segmentSize;
     108    size_t position = 0;
     109    for (const auto& segment : m_segments) {
     110        memcpy(static_cast<char*>(arrayBuffer->data()) + position, segment->data(), segment->size());
     111        position += segment->size();
    151112    }
    152113
    153     if (position != arrayBuffer->byteLength()) {
    154         ASSERT_NOT_REACHED();
    155         // Don't return the incomplete ArrayBuffer.
    156         return nullptr;
    157     }
    158 
     114    ASSERT(position == m_size);
    159115    return arrayBuffer;
    160116}
    161117
    162 void SharedBuffer::append(SharedBuffer& data)
    163 {
    164     if (maybeAppendPlatformData(data))
    165         return;
    166 #if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
    167     if (maybeAppendDataArray(data))
    168         return;
    169 #endif
    170 
    171     const char* segment;
    172     size_t position = 0;
    173     while (size_t length = data.getSomeData(segment, position)) {
    174         append(segment, length);
    175         position += length;
    176     }
    177 }
    178 
    179 void SharedBuffer::append(const char* data, unsigned length)
    180 {
    181     if (!length)
    182         return;
    183 
    184     maybeTransferMappedFileData();
    185     maybeTransferPlatformData();
    186 
    187 #if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
    188     unsigned positionInSegment = offsetInSegment(m_size - m_buffer->data.size());
     118void SharedBuffer::append(const SharedBuffer& data)
     119{
     120    m_size += data.m_size;
     121    m_segments.reserveCapacity(m_segments.size() + data.m_segments.size());
     122    for (const auto& segment : data.m_segments)
     123        m_segments.uncheckedAppend(segment.copyRef());
     124}
     125
     126void SharedBuffer::append(const char* data, size_t length)
     127{
    189128    m_size += length;
    190 
    191     if (m_size <= segmentSize) {
    192         // No need to use segments for small resource data
    193         if (m_buffer->data.isEmpty())
    194             m_buffer->data.reserveInitialCapacity(length);
    195         appendToDataBuffer(data, length);
    196         return;
    197     }
    198 
    199     char* segment;
    200     if (!positionInSegment) {
    201         segment = allocateSegment();
    202         m_segments.append(segment);
    203     } else
    204         segment = m_segments.last() + positionInSegment;
    205 
    206     unsigned segmentFreeSpace = segmentSize - positionInSegment;
    207     unsigned bytesToCopy = std::min(length, segmentFreeSpace);
    208 
    209     for (;;) {
    210         memcpy(segment, data, bytesToCopy);
    211         if (static_cast<unsigned>(length) == bytesToCopy)
    212             break;
    213 
    214         length -= bytesToCopy;
    215         data += bytesToCopy;
    216         segment = allocateSegment();
    217         m_segments.append(segment);
    218         bytesToCopy = std::min(length, segmentSize);
    219     }
    220 #else
    221     m_size += length;
    222     if (m_buffer->data.isEmpty())
    223         m_buffer->data.reserveInitialCapacity(length);
    224     appendToDataBuffer(data, length);
    225 #endif
     129    Vector<char> vector;
     130    vector.append(data, length);
     131    m_segments.append(DataSegment::create(WTFMove(vector)));
    226132}
    227133
    228134void SharedBuffer::append(Vector<char>&& data)
    229135{
    230     // This takes its argument as a rvalue reference because we intend to have a future
    231     // version take ownership of the vector rather than copying.
    232     append(data.data(), data.size());
     136    m_size += data.size();
     137    m_segments.append(DataSegment::create(WTFMove(data)));
    233138}
    234139
    235140void SharedBuffer::clear()
    236141{
    237     m_fileData = { };
    238 
    239     clearPlatformData();
    240    
    241 #if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
    242     for (char* segment : m_segments)
    243         freeSegment(segment);
     142    m_size = 0;
    244143    m_segments.clear();
    245 #else
    246     m_dataArray.clear();
    247 #endif
    248 
    249     m_size = 0;
    250     clearDataBuffer();
    251144}
    252145
    253146Ref<SharedBuffer> SharedBuffer::copy() const
    254147{
    255     Ref<SharedBuffer> clone { adoptRef(*new SharedBuffer) };
    256 
    257     if (hasPlatformData() || m_fileData) {
    258         clone->append(data(), size());
    259         return clone;
    260     }
    261 
     148    Ref<SharedBuffer> clone = adoptRef(*new SharedBuffer);
    262149    clone->m_size = m_size;
    263     clone->m_buffer->data.reserveCapacity(m_size);
    264     clone->m_buffer->data.append(m_buffer->data.data(), m_buffer->data.size());
    265 
    266 #if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
    267     if (!m_segments.isEmpty()) {
    268         unsigned lastIndex = m_segments.size() - 1;
    269         for (unsigned i = 0; i < lastIndex; ++i)
    270             clone->m_buffer->data.append(m_segments[i], segmentSize);
    271 
    272         unsigned sizeOfLastSegment = m_size - m_buffer->data.size() - lastIndex * segmentSize;
    273         clone->m_buffer->data.append(m_segments.last(), sizeOfLastSegment);
    274     }
    275 #else
    276     for (auto& data : m_dataArray)
    277         clone->m_dataArray.append(data.get());
    278 #endif
    279     ASSERT(clone->size() == size());
    280 
     150    clone->m_segments.reserveInitialCapacity(m_segments.size());
     151    for (const auto& segment : m_segments)
     152        clone->m_segments.uncheckedAppend(segment.copyRef());
    281153    return clone;
    282154}
    283155
    284 void SharedBuffer::duplicateDataBufferIfNecessary() const
    285 {
    286     size_t currentCapacity = m_buffer->data.capacity();
    287     if (m_buffer->hasOneRef() || m_size <= currentCapacity)
    288         return;
    289 
    290     size_t newCapacity = std::max(static_cast<size_t>(m_size), currentCapacity * 2);
    291     auto newBuffer = adoptRef(*new DataBuffer);
    292     newBuffer->data.reserveInitialCapacity(newCapacity);
    293     newBuffer->data = m_buffer->data;
    294     m_buffer = WTFMove(newBuffer);
    295 }
    296 
    297 void SharedBuffer::appendToDataBuffer(const char *data, unsigned length) const
    298 {
    299     duplicateDataBufferIfNecessary();
    300     m_buffer->data.append(data, length);
    301 }
    302 
    303 void SharedBuffer::clearDataBuffer()
    304 {
    305     if (!m_buffer->hasOneRef())
    306         m_buffer = adoptRef(*new DataBuffer);
    307     else
    308         m_buffer->data.clear();
     156const char* SharedBuffer::DataSegment::data() const
     157{
     158    auto visitor = WTF::makeVisitor(
     159        [](const Vector<char>& data) { return data.data(); },
     160#if USE(CF)
     161        [](const RetainPtr<CFDataRef>& data) { return reinterpret_cast<const char*>(CFDataGetBytePtr(data.get())); },
     162#endif
     163#if USE(SOUP)
     164        [](const GUniquePtr<SoupBuffer>& data) { return data->data; },
     165#endif
     166        [](const MappedFileData& data) { return reinterpret_cast<const char*>(data.data()); }
     167    );
     168    return WTF::visit(visitor, m_immutableData);
    309169}
    310170
     
    315175#endif
    316176
    317 #if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
    318 
    319 void SharedBuffer::copyBufferAndClear(char* destination, unsigned bytesToCopy) const
    320 {
    321     for (char* segment : m_segments) {
    322         unsigned effectiveBytesToCopy = std::min(bytesToCopy, segmentSize);
    323         memcpy(destination, segment, effectiveBytesToCopy);
    324         destination += effectiveBytesToCopy;
    325         bytesToCopy -= effectiveBytesToCopy;
    326         freeSegment(segment);
    327     }
    328     m_segments.clear();
    329 }
    330 
    331 #endif
    332 
    333 const Vector<char>& SharedBuffer::buffer() const
    334 {
    335     unsigned bufferSize = m_buffer->data.size();
    336     if (m_size > bufferSize) {
    337         duplicateDataBufferIfNecessary();
    338         m_buffer->data.resize(m_size);
    339         copyBufferAndClear(m_buffer->data.data() + bufferSize, m_size - bufferSize);
    340     }
    341     return m_buffer->data;
    342 }
    343 
    344 unsigned SharedBuffer::getSomeData(const char*& someData, unsigned position) const
    345 {
    346     unsigned totalSize = size();
    347     if (position >= totalSize) {
    348         someData = 0;
    349         return 0;
    350     }
    351 
    352     if (hasPlatformData() || m_fileData) {
    353         ASSERT_WITH_SECURITY_IMPLICATION(position < size());
    354         someData = data() + position;
    355         return totalSize - position;
    356     }
    357 
    358     ASSERT_WITH_SECURITY_IMPLICATION(position < m_size);
    359     unsigned consecutiveSize = m_buffer->data.size();
    360     if (position < consecutiveSize) {
    361         someData = m_buffer->data.data() + position;
    362         return consecutiveSize - position;
    363     }
    364  
    365     position -= consecutiveSize;
    366 #if !USE(NETWORK_CFDATA_ARRAY_CALLBACK)
    367     unsigned segments = m_segments.size();
    368     unsigned maxSegmentedSize = segments * segmentSize;
    369     unsigned segment = segmentIndex(position);
    370     if (segment < segments) {
    371         unsigned bytesLeft = totalSize - consecutiveSize;
    372         unsigned segmentedSize = std::min(maxSegmentedSize, bytesLeft);
    373 
    374         unsigned positionInSegment = offsetInSegment(position);
    375         someData = m_segments[segment] + positionInSegment;
    376         return segment == segments - 1 ? segmentedSize - position : segmentSize - positionInSegment;
    377     }
    378     ASSERT_NOT_REACHED();
    379     return 0;
    380 #else
    381     return copySomeDataFromDataArray(someData, position);
    382 #endif
    383 }
    384 
    385 void SharedBuffer::maybeTransferMappedFileData()
    386 {
    387     if (m_fileData) {
    388         auto fileData = WTFMove(m_fileData);
    389         append(static_cast<const char*>(fileData.data()), fileData.size());
    390     }
    391 }
    392 
    393 #if !USE(CF) && !USE(SOUP)
    394 
    395 inline void SharedBuffer::clearPlatformData()
    396 {
    397 }
    398 
    399 inline void SharedBuffer::maybeTransferPlatformData()
    400 {
    401 }
    402 
    403 inline bool SharedBuffer::hasPlatformData() const
    404 {
    405     return false;
    406 }
    407 
    408 inline const char* SharedBuffer::platformData() const
    409 {
    410     ASSERT_NOT_REACHED();
    411 
    412     return nullptr;
    413 }
    414 
    415 inline bool SharedBuffer::maybeAppendPlatformData(SharedBuffer&)
    416 {
    417     return false;
    418 }
    419 
    420 #endif
     177size_t SharedBuffer::DataSegment::size() const
     178{
     179    auto visitor = WTF::makeVisitor(
     180        [](const Vector<char>& data) { return data.size(); },
     181#if USE(CF)
     182        [](const RetainPtr<CFDataRef>& data) { return CFDataGetLength(data.get()); },
     183#endif
     184#if USE(SOUP)
     185        [](const GUniquePtr<SoupBuffer>& data) { return static_cast<size_t>(data->length); },
     186#endif
     187        [](const MappedFileData& data) { return data.size(); }
     188    );
     189    return WTF::visit(visitor, m_immutableData);
     190}
    421191
    422192RefPtr<SharedBuffer> utf8Buffer(const String& string)
  • TabularUnified trunk/Source/WebCore/platform/SharedBuffer.h

    r215661 r215686  
    3232#include <wtf/RefCounted.h>
    3333#include <wtf/ThreadSafeRefCounted.h>
     34#include <wtf/Variant.h>
    3435#include <wtf/Vector.h>
    3536#include <wtf/text/WTFString.h>
     
    5051namespace WebCore {
    5152   
    52 class SharedBuffer : public RefCounted<SharedBuffer> {
     53class WEBCORE_EXPORT SharedBuffer : public RefCounted<SharedBuffer> {
    5354public:
    5455    static Ref<SharedBuffer> create() { return adoptRef(*new SharedBuffer); }
    55     static Ref<SharedBuffer> create(const char* c, unsigned i) { return adoptRef(*new SharedBuffer(c, i)); }
    56     static Ref<SharedBuffer> create(const unsigned char* data, unsigned size) { return adoptRef(*new SharedBuffer(data, size)); }
     56    static Ref<SharedBuffer> create(const char* data, size_t size) { return adoptRef(*new SharedBuffer(data, size)); }
     57    static Ref<SharedBuffer> create(const unsigned char* data, size_t size) { return adoptRef(*new SharedBuffer(data, size)); }
     58    static RefPtr<SharedBuffer> createWithContentsOfFile(const String& filePath);
    5759
    58     WEBCORE_EXPORT static RefPtr<SharedBuffer> createWithContentsOfFile(const String& filePath);
    59 
    60     WEBCORE_EXPORT static Ref<SharedBuffer> create(Vector<char>&&);
    61    
    62     WEBCORE_EXPORT ~SharedBuffer();
     60    static Ref<SharedBuffer> create(Vector<char>&&);
    6361   
    6462#if USE(FOUNDATION)
    65     WEBCORE_EXPORT RetainPtr<NSData> createNSData();
    66     WEBCORE_EXPORT RetainPtr<NSArray> createNSDataArray() const;
    67     WEBCORE_EXPORT static Ref<SharedBuffer> wrapNSData(NSData *);
     63    RetainPtr<NSData> createNSData();
     64    RetainPtr<NSArray> createNSDataArray() const;
     65    static Ref<SharedBuffer> create(NSData *);
    6866#endif
    6967#if USE(CF)
    70     WEBCORE_EXPORT RetainPtr<CFDataRef> createCFData();
    71     WEBCORE_EXPORT static Ref<SharedBuffer> wrapCFData(CFDataRef);
    72     WEBCORE_EXPORT void append(CFDataRef);
     68    RetainPtr<CFDataRef> createCFData();
     69    static Ref<SharedBuffer> create(CFDataRef);
     70    void append(CFDataRef);
    7371#endif
    7472
     
    7876#endif
    7977
    80     // Calling this function will force internal segmented buffers
    81     // to be merged into a flat buffer. Use getSomeData() whenever possible
    82     // for better performance.
    83     WEBCORE_EXPORT const char* data() const;
     78    // Calling data() causes all the data segments to be copied into one segment if they are not already.
     79    // Iterate the segments using begin() and end() instead.
     80    // FIXME: Audit the call sites of this function and replace them with iteration if possible.
     81    const char* data() const;
     82
    8483    // Creates an ArrayBuffer and copies this SharedBuffer's contents to that
    8584    // ArrayBuffer without merging segmented buffers into a flat buffer.
    86     WEBCORE_EXPORT RefPtr<ArrayBuffer> createArrayBuffer() const;
     85    RefPtr<ArrayBuffer> tryCreateArrayBuffer() const;
    8786
    88     WEBCORE_EXPORT unsigned size() const;
     87    // FIXME: This should return a size_t.
     88    unsigned size() const { return m_size; }
    8989
    9090    bool isEmpty() const { return !size(); }
    9191
    92     WEBCORE_EXPORT void append(SharedBuffer&);
    93     WEBCORE_EXPORT void append(const char*, unsigned);
    94     WEBCORE_EXPORT void append(Vector<char>&&);
     92    void append(const SharedBuffer&);
     93    void append(const char*, size_t);
     94    void append(Vector<char>&&);
    9595
    96     WEBCORE_EXPORT void clear();
     96    void clear();
    9797
    98     WEBCORE_EXPORT Ref<SharedBuffer> copy() const;
    99    
    100     // Return the number of consecutive bytes after "position". "data"
    101     // points to the first byte.
    102     // Return 0 when no more data left.
    103     // When extracting all data with getSomeData(), the caller should
    104     // repeat calling it until it returns 0.
    105     // Usage:
    106     //      const char* segment;
    107     //      unsigned pos = 0;
    108     //      while (unsigned length = sharedBuffer->getSomeData(segment, pos)) {
    109     //          // Use the data. for example: decoder->decode(segment, length);
    110     //          pos += length;
    111     //      }
    112     WEBCORE_EXPORT unsigned getSomeData(const char*& data, unsigned position = 0) const;
     98    Ref<SharedBuffer> copy() const;
    11399
    114     bool tryReplaceContentsWithPlatformBuffer(SharedBuffer&);
    115     WEBCORE_EXPORT bool hasPlatformData() const;
     100    // Data wrapped by a DataSegment should be immutable because it can be referenced by other objects.
     101    // To modify or combine the data, allocate a new DataSegment.
     102    class DataSegment : public ThreadSafeRefCounted<DataSegment> {
     103    public:
     104        const char* data() const;
     105        size_t size() const;
    116106
    117     struct DataBuffer : public ThreadSafeRefCounted<DataBuffer> {
    118         Vector<char> data;
     107        static Ref<DataSegment> create(Vector<char>&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
     108#if USE(CF)
     109        static Ref<DataSegment> create(RetainPtr<CFDataRef>&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
     110#endif
     111#if USE(SOUP)
     112        static Ref<DataSegment> create(GUniquePtr<SoupBuffer>&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
     113#endif
     114        static Ref<DataSegment> create(MappedFileData&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
     115
     116    private:
     117        DataSegment(Vector<char>&& data)
     118            : m_immutableData(WTFMove(data)) { }
     119#if USE(CF)
     120        DataSegment(RetainPtr<CFDataRef>&& data)
     121            : m_immutableData(WTFMove(data)) { }
     122#endif
     123#if USE(SOUP)
     124        DataSegment(GUniquePtr<SoupBuffer>&& data)
     125            : m_immutableData(WTFMove(data)) { }
     126#endif
     127        DataSegment(MappedFileData&& data)
     128            : m_immutableData(WTFMove(data)) { }
     129
     130        Variant<Vector<char>,
     131#if USE(CF)
     132            RetainPtr<CFDataRef>,
     133#endif
     134#if USE(SOUP)
     135            GUniquePtr<SoupBuffer>,
     136#endif
     137            MappedFileData> m_immutableData;
     138        friend class SharedBuffer;
    119139    };
     140
     141    using DataSegmentVector = Vector<Ref<DataSegment>, 1>;
     142    DataSegmentVector::const_iterator begin() const { return m_segments.begin(); }
     143    DataSegmentVector::const_iterator end() const { return m_segments.end(); }
    120144
    121145    void hintMemoryNotNeededSoon();
    122146
    123147private:
    124     WEBCORE_EXPORT SharedBuffer();
    125     WEBCORE_EXPORT SharedBuffer(const char*, unsigned);
    126     WEBCORE_EXPORT SharedBuffer(const unsigned char*, unsigned);
     148    explicit SharedBuffer() = default;
     149    explicit SharedBuffer(const char*, size_t);
     150    explicit SharedBuffer(const unsigned char*, size_t);
     151    explicit SharedBuffer(Vector<char>&&);
    127152    explicit SharedBuffer(MappedFileData&&);
     153#if USE(CF)
     154    explicit SharedBuffer(CFDataRef);
     155#endif
     156#if USE(SOUP)
     157    explicit SharedBuffer(SoupBuffer*);
     158#endif
    128159
     160    void combineIntoOneSegment() const;
     161   
    129162    static RefPtr<SharedBuffer> createFromReadingFile(const String& filePath);
    130163
    131     // Calling this function will force internal segmented buffers
    132     // to be merged into a flat buffer. Use getSomeData() whenever possible
    133     // for better performance.
    134     const Vector<char>& buffer() const;
    135 
    136     void clearPlatformData();
    137     void maybeTransferPlatformData();
    138     bool maybeAppendPlatformData(SharedBuffer&);
    139 
    140     void maybeTransferMappedFileData();
    141 
    142     void copyBufferAndClear(char* destination, unsigned bytesToCopy) const;
    143 
    144     void appendToDataBuffer(const char *, unsigned) const;
    145     void duplicateDataBufferIfNecessary() const;
    146     void clearDataBuffer();
    147 
    148     unsigned m_size { 0 };
    149     mutable Ref<DataBuffer> m_buffer;
    150 
    151 #if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
    152     mutable Vector<RetainPtr<CFDataRef>> m_dataArray;
    153     unsigned copySomeDataFromDataArray(const char*& someData, unsigned position) const;
    154     const char *singleDataArrayBuffer() const;
    155     bool maybeAppendDataArray(SharedBuffer&);
    156 #else
    157     mutable Vector<char*> m_segments;
    158 #endif
    159 
    160     unsigned platformDataSize() const;
    161     const char* platformData() const;
    162 
    163 #if USE(CF)
    164     explicit SharedBuffer(CFDataRef);
    165     RetainPtr<CFDataRef> m_cfData;
    166     CFDataRef existingCFData();
    167 #endif
    168 
    169 #if USE(SOUP)
    170     explicit SharedBuffer(SoupBuffer*);
    171     GUniquePtr<SoupBuffer> m_soupBuffer;
    172 #endif
    173 
    174     MappedFileData m_fileData;
     164    size_t m_size { 0 };
     165    mutable DataSegmentVector m_segments;
    175166};
    176167
  • TabularUnified trunk/Source/WebCore/platform/SharedBufferChunkReader.cpp

    r215661 r215686  
    3131#include "config.h"
    3232#include "SharedBufferChunkReader.h"
     33
     34#if ENABLE(MHTML)
     35
     36// FIXME: This class is overkill. Remove this class and just iterate the segments of a SharedBuffer
     37// using the cool new SharedBuffer::begin() and SharedBuffer::end() instead of using this class.
    3338
    3439#include "SharedBuffer.h"
     
    101106        m_segmentIndex = 0;
    102107        m_bufferPosition += m_segmentLength;
    103         m_segmentLength = m_buffer->getSomeData(m_segment, m_bufferPosition);
     108        // Let's pretend all the data is in one block.
     109        // FIXME: This class should be removed in favor of just iterating the segments of the SharedBuffer.
     110        m_segment = m_buffer->data() + m_bufferPosition;
     111        m_segmentLength = m_buffer->size() - m_bufferPosition;
    104112        if (!m_segmentLength) {
    105113            m_reachedEndOfFile = true;
     
    135143    size_t bufferPosition = m_bufferPosition + m_segmentLength;
    136144    const char* segment = 0;
    137     while (size_t segmentLength = m_buffer->getSomeData(segment, bufferPosition)) {
    138         if (requestedSize <= readBytesCount + segmentLength) {
    139             data.append(segment, requestedSize - readBytesCount);
    140             readBytesCount += (requestedSize - readBytesCount);
    141             break;
    142         }
     145
     146    // Let's pretend all the data is in one block.
     147    // FIXME: This class should be removed in favor of just iterating the segments of the SharedBuffer.
     148    if (bufferPosition != m_buffer->size()) {
     149        segment = m_buffer->data() + bufferPosition;
     150        size_t segmentLength = m_buffer->size() - bufferPosition;
     151        if (segmentLength > requestedSize)
     152            segmentLength = requestedSize;
    143153        data.append(segment, segmentLength);
    144154        readBytesCount += segmentLength;
     
    149159
    150160}
     161
     162#endif
  • TabularUnified trunk/Source/WebCore/platform/SharedBufferChunkReader.h

    r215661 r215686  
    2929 */
    3030
    31 #ifndef SharedBufferChunkReader_h
    32 #define SharedBufferChunkReader_h
     31#pragma once
     32
     33#if ENABLE(MHTML)
    3334
    3435#include <wtf/Vector.h>
  • TabularUnified trunk/Source/WebCore/platform/cf/KeyedEncoderCF.cpp

    r215661 r215686  
    146146    if (!data)
    147147        return nullptr;
    148     return SharedBuffer::wrapCFData(data.get());
     148    return SharedBuffer::create(data.get());
    149149}
    150150
  • TabularUnified trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp

    r215661 r215686  
    3434namespace WebCore {
    3535
    36 SharedBuffer::SharedBuffer(CFDataRef cfData)
    37     : m_buffer(adoptRef(*new DataBuffer))
    38     , m_cfData(cfData)
     36SharedBuffer::SharedBuffer(CFDataRef data)
    3937{
     38    append(data);
    4039}
    4140
     
    4544RetainPtr<CFDataRef> SharedBuffer::createCFData()
    4645{
    47     if (m_cfData)
    48         return m_cfData;
    49 
    50     // Internal data in SharedBuffer can be segmented. We need to get the contiguous buffer.
    51     const Vector<char>& contiguousBuffer = buffer();
    52     return adoptCF(CFDataCreate(0, reinterpret_cast<const UInt8*>(contiguousBuffer.data()), contiguousBuffer.size()));
     46    if (m_segments.size() == 1) {
     47        if (auto data = WTF::get_if<RetainPtr<CFDataRef>>(m_segments[0]->m_immutableData))
     48            return *data;
     49    }
     50    return adoptCF(CFDataCreate(nullptr, reinterpret_cast<const UInt8*>(data()), size()));
    5351}
    5452#endif
    5553
    56 Ref<SharedBuffer> SharedBuffer::wrapCFData(CFDataRef data)
     54Ref<SharedBuffer> SharedBuffer::create(CFDataRef data)
    5755{
    5856    return adoptRef(*new SharedBuffer(data));
    5957}
    6058
    61 bool SharedBuffer::hasPlatformData() const
     59void SharedBuffer::hintMemoryNotNeededSoon()
    6260{
    63     return m_cfData;
     61    for (const auto& segment : m_segments) {
     62        if (segment->hasOneRef()) {
     63            if (auto data = WTF::get_if<RetainPtr<CFDataRef>>(segment->m_immutableData))
     64                OSAllocator::hintMemoryNotNeededSoon(const_cast<UInt8*>(CFDataGetBytePtr(data->get())), CFDataGetLength(data->get()));
     65        }
     66    }
    6467}
    6568
    66 const char* SharedBuffer::platformData() const
    67 {
    68     return reinterpret_cast<const char*>(CFDataGetBytePtr(m_cfData.get()));
    69 }
    70 
    71 unsigned SharedBuffer::platformDataSize() const
    72 {
    73     return CFDataGetLength(m_cfData.get());
    74 }
    75 
    76 void SharedBuffer::hintMemoryNotNeededSoon()
    77 {
    78     if (!hasPlatformData())
    79         return;
    80     OSAllocator::hintMemoryNotNeededSoon(const_cast<char*>(platformData()), platformDataSize());
    81 }
    82 
    83 void SharedBuffer::maybeTransferPlatformData()
    84 {
    85     if (!m_cfData)
    86         return;
    87    
    88     ASSERT(!m_size);
    89    
    90     // Hang on to the m_cfData pointer in a local pointer as append() will re-enter maybeTransferPlatformData()
    91     // and we need to make sure to early return when it does.
    92     RetainPtr<CFDataRef> cfData = adoptCF(m_cfData.leakRef());
    93 
    94     append(reinterpret_cast<const char*>(CFDataGetBytePtr(cfData.get())), CFDataGetLength(cfData.get()));
    95 }
    96 
    97 void SharedBuffer::clearPlatformData()
    98 {
    99     m_cfData = 0;
    100 }
    101 
    102 bool SharedBuffer::tryReplaceContentsWithPlatformBuffer(SharedBuffer& newContents)
    103 {
    104     if (!newContents.m_cfData)
    105         return false;
    106 
    107     clear();
    108     m_cfData = newContents.m_cfData;
    109     return true;
    110 }
    111 
    112 bool SharedBuffer::maybeAppendPlatformData(SharedBuffer& newContents)
    113 {
    114     if (size() || !newContents.m_cfData)
    115         return false;
    116     m_cfData = newContents.m_cfData;
    117     return true;
    118 }
    119 
    120 #if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
    12169void SharedBuffer::append(CFDataRef data)
    12270{
    12371    ASSERT(data);
    124     m_dataArray.append(data);
    12572    m_size += CFDataGetLength(data);
     73    m_segments.append(DataSegment::create(data));
    12674}
    12775
    128 void SharedBuffer::copyBufferAndClear(char* destination, unsigned bytesToCopy) const
    129 {
    130     if (m_dataArray.isEmpty())
    131         return;
    132 
    133     CFIndex bytesLeft = bytesToCopy;
    134     for (auto& cfData : m_dataArray) {
    135         CFIndex dataLen = CFDataGetLength(cfData.get());
    136         ASSERT(bytesLeft >= dataLen);
    137         memcpy(destination, CFDataGetBytePtr(cfData.get()), dataLen);
    138         destination += dataLen;
    139         bytesLeft -= dataLen;
    140     }
    141     m_dataArray.clear();
    14276}
    143 
    144 unsigned SharedBuffer::copySomeDataFromDataArray(const char*& someData, unsigned position) const
    145 {
    146     unsigned totalOffset = 0;
    147     for (auto& cfData : m_dataArray) {
    148         unsigned dataLen = static_cast<unsigned>(CFDataGetLength(cfData.get()));
    149         ASSERT(totalOffset <= position);
    150         unsigned localOffset = position - totalOffset;
    151         if (localOffset < dataLen) {
    152             someData = reinterpret_cast<const char *>(CFDataGetBytePtr(cfData.get())) + localOffset;
    153             return dataLen - localOffset;
    154         }
    155         totalOffset += dataLen;
    156     }
    157     return 0;
    158 }
    159 
    160 const char *SharedBuffer::singleDataArrayBuffer() const
    161 {
    162     // If we had previously copied data into m_buffer in copyDataArrayAndClear() or some other
    163     // function, then we can't return a pointer to the CFDataRef buffer.
    164     if (m_buffer->data.size())
    165         return 0;
    166 
    167     if (m_dataArray.size() != 1)
    168         return 0;
    169 
    170     return reinterpret_cast<const char*>(CFDataGetBytePtr(m_dataArray.at(0).get()));
    171 }
    172 
    173 bool SharedBuffer::maybeAppendDataArray(SharedBuffer& data)
    174 {
    175     if (m_buffer->data.size() || m_cfData || !data.m_dataArray.size())
    176         return false;
    177 #if !ASSERT_DISABLED
    178     unsigned originalSize = size();
    179 #endif
    180     for (auto& cfData : data.m_dataArray)
    181         append(cfData.get());
    182     ASSERT(size() == originalSize + data.size());
    183     return true;
    184 }
    185 #endif
    186 
    187 }
  • TabularUnified trunk/Source/WebCore/platform/cocoa/NetworkExtensionContentFilter.mm

    r215661 r215686  
    198198{
    199199    ASSERT(didBlockData());
    200     return SharedBuffer::wrapNSData(m_replacementData.get());
     200    return SharedBuffer::create(m_replacementData.get());
    201201}
    202202
  • TabularUnified trunk/Source/WebCore/platform/cocoa/ParentalControlsContentFilter.mm

    r215661 r215686  
    9494{
    9595    ASSERT(didBlockData());
    96     return SharedBuffer::wrapNSData(m_replacementData.get());
     96    return SharedBuffer::create(m_replacementData.get());
    9797}
    9898
  • TabularUnified trunk/Source/WebCore/platform/cocoa/SharedBufferCocoa.mm

    r215661 r215686  
    3636@interface WebCoreSharedBufferData : NSData
    3737{
    38     RefPtr<SharedBuffer::DataBuffer> sharedBufferDataBuffer;
     38    RefPtr<const SharedBuffer::DataSegment> sharedBufferDataSegment;
    3939}
    4040
    41 - (id)initWithSharedBufferDataBuffer:(SharedBuffer::DataBuffer*)dataBuffer;
     41- (id)initWithSharedBufferDataSegment:(const SharedBuffer::DataSegment&)dataSegment;
    4242@end
    4343
     
    6060}
    6161
    62 - (id)initWithSharedBufferDataBuffer:(SharedBuffer::DataBuffer*)dataBuffer
     62- (id)initWithSharedBufferDataSegment:(const SharedBuffer::DataSegment&)dataSegment
    6363{
    6464    self = [super init];
    6565   
    6666    if (self)
    67         sharedBufferDataBuffer = dataBuffer;
     67        sharedBufferDataSegment = &dataSegment;
    6868
    6969    return self;
     
    7272- (NSUInteger)length
    7373{
    74     return sharedBufferDataBuffer->data.size();
     74    return sharedBufferDataSegment->size();
    7575}
    7676
    7777- (const void *)bytes
    7878{
    79     return sharedBufferDataBuffer->data.data();
     79    return sharedBufferDataSegment->data();
    8080}
    8181
     
    8484namespace WebCore {
    8585
    86 Ref<SharedBuffer> SharedBuffer::wrapNSData(NSData *nsData)
     86Ref<SharedBuffer> SharedBuffer::create(NSData *nsData)
    8787{
    8888    return adoptRef(*new SharedBuffer((CFDataRef)nsData));
     
    9494}
    9595
    96 CFDataRef SharedBuffer::existingCFData()
    97 {
    98     if (m_cfData)
    99         return m_cfData.get();
    100 
    101 #if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
    102     if (m_dataArray.size() == 1)
    103         return m_dataArray.at(0).get();
    104 #endif
    105 
    106     return nullptr;
    107 }
    108 
    10996RetainPtr<CFDataRef> SharedBuffer::createCFData()
    11097{
    111     if (CFDataRef cfData = existingCFData())
    112         return cfData;
    113 
    114     data(); // Force data into m_buffer from segments or data array.
    115     return adoptCF((CFDataRef)adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataBuffer:m_buffer.ptr()]).leakRef());
     98    combineIntoOneSegment();
     99    if (!m_segments.size())
     100        return adoptCF(CFDataCreate(nullptr, nullptr, 0));
     101    ASSERT(m_segments.size() == 1);
     102    return adoptCF((CFDataRef)adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataSegment:m_segments[0]]).leakRef());
    116103}
    117104
     
    120107    NSData *resourceData = [NSData dataWithContentsOfFile:filePath];
    121108    if (resourceData)
    122         return SharedBuffer::wrapNSData(resourceData);
     109        return SharedBuffer::create(resourceData);
    123110    return nullptr;
    124111}
     
    126113RetainPtr<NSArray> SharedBuffer::createNSDataArray() const
    127114{
    128     if (auto platformData = (NSData *)m_cfData.get())
    129         return @[ platformData ];
    130 
    131     if (m_fileData)
    132         return @[ [NSData dataWithBytes:m_fileData.data() length:m_fileData.size()] ];
    133 
    134     auto dataArray = adoptNS([[NSMutableArray alloc] init]);
    135     if (m_buffer->data.size())
    136         [dataArray addObject:adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataBuffer:m_buffer.ptr()]).get()];
    137 
    138 #if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
    139     for (auto& data : m_dataArray)
    140         [dataArray addObject:(NSData *)data.get()];
    141 #else
    142     // Cocoa platforms all currently USE(NETWORK_CFDATA_ARRAY_CALLBACK), so implementing a code path for copying segments would be dead code.
    143     // If this ever changes, the following static_assert will detect it.
    144     static_assert(false, "FIXME: Copy the segments into an array of NSData objects.");
    145 #endif
    146 
     115    auto dataArray = adoptNS([[NSMutableArray alloc] initWithCapacity:m_segments.size()]);
     116    for (const auto& segment : m_segments)
     117        [dataArray addObject:adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataSegment:segment]).get()];
    147118    return WTFMove(dataArray);
    148119}
  • TabularUnified trunk/Source/WebCore/platform/graphics/avfoundation/objc/WebCoreAVFResourceLoader.mm

    r215661 r215686  
    174174
    175175    // Check for possible unsigned overflow.
    176     ASSERT([dataRequest currentOffset] >= [dataRequest requestedOffset]);
    177     ASSERT([dataRequest requestedLength] >= ([dataRequest currentOffset] - [dataRequest requestedOffset]));
    178 
    179     NSUInteger remainingLength = [dataRequest requestedLength] - static_cast<NSUInteger>([dataRequest currentOffset] - [dataRequest requestedOffset]);
    180     do {
    181         // Check to see if there is any data available in the buffer to fulfill the data request.
    182         if (data->size() <= [dataRequest currentOffset] - responseOffset)
    183             return;
    184 
    185         const char* someData;
    186         NSUInteger receivedLength = data->getSomeData(someData, static_cast<unsigned>([dataRequest currentOffset] - responseOffset));
    187 
    188         // Create an NSData with only as much of the received data as necessary to fulfill the request.
    189         NSUInteger length = MIN(receivedLength, remainingLength);
    190         RetainPtr<NSData> nsData = adoptNS([[NSData alloc] initWithBytes:someData length:length]);
    191 
    192         [dataRequest respondWithData:nsData.get()];
    193         remainingLength -= length;
    194     } while (remainingLength);
    195 
    196     if ([dataRequest currentOffset] + [dataRequest requestedLength] >= [dataRequest requestedOffset]) {
     176    ASSERT(dataRequest.currentOffset >= dataRequest.requestedOffset);
     177    ASSERT(dataRequest.requestedLength >= (dataRequest.currentOffset - dataRequest.requestedOffset));
     178
     179    NSUInteger remainingLength = dataRequest.requestedLength - static_cast<NSUInteger>(dataRequest.currentOffset - dataRequest.requestedOffset);
     180
     181    auto bytesToSkip = dataRequest.currentOffset - responseOffset;
     182    RetainPtr<NSArray> array = data->createNSDataArray();
     183    for (NSData *segment in array.get()) {
     184        if (bytesToSkip) {
     185            if (bytesToSkip > segment.length) {
     186                bytesToSkip -= segment.length;
     187                continue;
     188            }
     189            auto bytesToUse = segment.length - bytesToSkip;
     190            [dataRequest respondWithData:[segment subdataWithRange:NSMakeRange(static_cast<NSUInteger>(bytesToSkip), static_cast<NSUInteger>(segment.length - bytesToSkip))]];
     191            bytesToSkip = 0;
     192            remainingLength -= bytesToUse;
     193            continue;
     194        }
     195        if (segment.length <= remainingLength) {
     196            [dataRequest respondWithData:segment];
     197            remainingLength -= segment.length;
     198            continue;
     199        }
     200        [dataRequest respondWithData:[segment subdataWithRange:NSMakeRange(0, remainingLength)]];
     201        remainingLength = 0;
     202        if (!remainingLength)
     203            break;
     204    }
     205
     206    if (dataRequest.currentOffset + dataRequest.requestedLength >= dataRequest.requestedOffset) {
    197207        [m_avRequest.get() finishLoading];
    198208        stopLoading();
  • TabularUnified trunk/Source/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm

    r215661 r215686  
    202202{
    203203    if (RetainPtr<CFDataRef> data = adoptCF(CTFontCopyTable(font(), table, kCTFontTableOptionNoOptions)))
    204         return SharedBuffer::wrapCFData(data.get());
     204        return SharedBuffer::create(data.get());
    205205   
    206206    return nullptr;
  • TabularUnified trunk/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp

    r215661 r215686  
    11641164void ResourceHandleStreamingClient::didReceiveBuffer(ResourceHandle*, Ref<SharedBuffer>&& buffer, int /* encodedLength */)
    11651165{
    1166     // This pattern is suggested by SharedBuffer.h.
    1167     const char* segment;
    1168     unsigned position = 0;
    1169     while (unsigned length = buffer->getSomeData(segment, position)) {
    1170         handleDataReceived(segment, length);
    1171         position += length;
    1172     }
     1166    for (const auto& segment : buffer.get())
     1167        handleDataReceived(segment->data(), segment->size());
    11731168}
    11741169
  • TabularUnified trunk/Source/WebCore/platform/graphics/mac/ImageMac.mm

    r215661 r215686  
    6464    if (namedImageData) {
    6565        auto image = BitmapImage::create();
    66         image->setData(SharedBuffer::wrapNSData(namedImageData), true);
     66        image->setData(SharedBuffer::create(namedImageData), true);
    6767        return WTFMove(image);
    6868    }
  • TabularUnified trunk/Source/WebCore/platform/image-decoders/ImageDecoder.cpp

    r215661 r215686  
    4343namespace {
    4444
    45 unsigned copyFromSharedBuffer(char* buffer, unsigned bufferLength, const SharedBuffer& sharedBuffer, unsigned offset)
     45static unsigned copyFromSharedBuffer(char* buffer, unsigned bufferLength, const SharedBuffer& sharedBuffer)
    4646{
    4747    unsigned bytesExtracted = 0;
    48     const char* moreData;
    49     while (unsigned moreDataLength = sharedBuffer.getSomeData(moreData, offset)) {
    50         unsigned bytesToCopy = min(bufferLength - bytesExtracted, moreDataLength);
    51         memcpy(buffer + bytesExtracted, moreData, bytesToCopy);
    52         bytesExtracted += bytesToCopy;
    53         if (bytesExtracted == bufferLength)
     48    for (const auto& segment : sharedBuffer) {
     49        if (bytesExtracted + segment->size() <= bufferLength) {
     50            memcpy(buffer + bytesExtracted, segment->data(), segment->size());
     51            bytesExtracted += segment->size();
     52        } else {
     53            ASSERT(bufferLength - bytesExtracted < segment->size());
     54            memcpy(buffer + bytesExtracted, segment->data(), bufferLength - bytesExtracted);
     55            bytesExtracted = bufferLength;
    5456            break;
    55         offset += bytesToCopy;
     57        }
    5658    }
    5759    return bytesExtracted;
     
    101103    static const unsigned lengthOfLongestSignature = 14; // To wit: "RIFF????WEBPVP"
    102104    char contents[lengthOfLongestSignature];
    103     unsigned length = copyFromSharedBuffer(contents, lengthOfLongestSignature, data, 0);
     105    unsigned length = copyFromSharedBuffer(contents, lengthOfLongestSignature, data);
    104106    if (length < lengthOfLongestSignature)
    105107        return nullptr;
  • TabularUnified trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp

    r215661 r215686  
    158158            return decoder->setFailed();
    159159
    160         const char* segment;
    161         while (unsigned segmentLength = data.getSomeData(segment, m_readOffset)) {
    162             m_readOffset += segmentLength;
     160        auto bytesToSkip = m_readOffset;
     161        for (const auto& segment : data) {
     162            if (bytesToSkip > segment->size()) {
     163                bytesToSkip -= segment->size();
     164                continue;
     165            }
     166            m_readOffset += segment->size();
    163167            m_currentBufferSize = m_readOffset;
    164             png_process_data(m_png, m_info, reinterpret_cast<png_bytep>(const_cast<char*>(segment)), segmentLength);
     168            png_process_data(m_png, m_info, reinterpret_cast<png_bytep>(const_cast<char*>(segment->data() + bytesToSkip)), segment->size() - bytesToSkip);
     169            bytesToSkip = 0;
    165170            // We explicitly specify the superclass encodedDataStatus() because we
    166171            // merely want to check if we've managed to set the size, not
  • TabularUnified trunk/Source/WebCore/platform/ios/PlatformPasteboardIOS.mm

    r215663 r215686  
    330330    if (![pasteboardItem count])
    331331        return nullptr;
    332     return SharedBuffer::wrapNSData([pasteboardItem.get() objectAtIndex:0]);
     332    return SharedBuffer::create([pasteboardItem.get() objectAtIndex:0]);
    333333}
    334334
  • TabularUnified trunk/Source/WebCore/platform/mac/PasteboardMac.mm

    r215661 r215686  
    262262        return;
    263263
    264     newChangeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(SharedBuffer::wrapNSData(RTFDData).ptr(), NSRTFDPboardType, pasteboardName);
     264    newChangeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(SharedBuffer::create(RTFDData).ptr(), NSRTFDPboardType, pasteboardName);
    265265}
    266266
     
    279279
    280280    m_changeCount = writeURLForTypes(types, m_pasteboardName, pasteboardImage.url);
    281     m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(SharedBuffer::wrapCFData(imageData).ptr(), NSTIFFPboardType, m_pasteboardName);
     281    m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(SharedBuffer::create(imageData).ptr(), NSTIFFPboardType, m_pasteboardName);
    282282    if (pasteboardImage.dataInWebArchiveFormat)
    283283        m_changeCount = platformStrategies()->pasteboardStrategy()->setBufferForType(pasteboardImage.dataInWebArchiveFormat.get(), WebArchivePboardType, m_pasteboardName);
  • TabularUnified trunk/Source/WebCore/platform/mac/PlatformPasteboardMac.mm

    r215661 r215686  
    5151    if (!data)
    5252        return nullptr;
    53     return SharedBuffer::wrapNSData([[data copy] autorelease]);
     53    return SharedBuffer::create([[data copy] autorelease]);
    5454}
    5555
  • TabularUnified trunk/Source/WebCore/platform/network/BlobResourceHandle.cpp

    r215661 r215686  
    605605{
    606606    if (client())
    607         client()->didReceiveBuffer(this, SharedBuffer::create(data, bytesRead), bytesRead);
     607        client()->didReceiveBuffer(this, SharedBuffer::create(reinterpret_cast<const uint8_t*>(data), bytesRead), bytesRead);
    608608}
    609609
  • TabularUnified trunk/Source/WebCore/platform/network/MIMEHeader.cpp

    r215661 r215686  
    3131#include "config.h"
    3232#include "MIMEHeader.h"
     33
     34#if ENABLE(MHTML)
    3335
    3436#include "ParsedContentType.h"
     
    134136
    135137}
     138
     139#endif
  • TabularUnified trunk/Source/WebCore/platform/network/MIMEHeader.h

    r215661 r215686  
    2929 */
    3030
    31 #ifndef MIMEHeader_h
    32 #define MIMEHeader_h
     31#pragma once
     32
     33#if ENABLE(MHTML)
    3334
    3435#include <wtf/RefCounted.h>
  • TabularUnified trunk/Source/WebCore/platform/network/cf/ResourceHandleCFURLConnectionDelegateWithOperationQueue.cpp

    r215661 r215686  
    178178            LOG(Network, "CFNet - ResourceHandleCFURLConnectionDelegateWithOperationQueue::didReceiveData(handle=%p) (%s)", m_handle, m_handle->firstRequest().url().string().utf8().data());
    179179
    180             m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::wrapCFData(data), originalLength);
     180            m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::create(data), originalLength);
    181181        }
    182182
  • TabularUnified trunk/Source/WebCore/platform/network/cf/SynchronousResourceHandleCFURLConnectionDelegate.cpp

    r215661 r215686  
    185185
    186186    if (ResourceHandleClient* client = m_handle->client())
    187         client->didReceiveBuffer(m_handle, SharedBuffer::wrapCFData(data), originalLength);
     187        client->didReceiveBuffer(m_handle, SharedBuffer::create(data), originalLength);
    188188}
    189189
  • TabularUnified trunk/Source/WebCore/platform/network/mac/WebCoreResourceHandleAsDelegate.mm

    r215661 r215686  
    175175    // -1 means we do not provide any data about transfer size to inspector so it would use
    176176    // Content-Length headers or content size to show transfer size.
    177     m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::wrapNSData(data), -1);
     177    m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::create(data), -1);
    178178}
    179179
  • TabularUnified trunk/Source/WebCore/platform/network/mac/WebCoreResourceHandleAsOperationQueueDelegate.mm

    r215661 r215686  
    224224        // -1 means we do not provide any data about transfer size to inspector so it would use
    225225        // Content-Length headers or content size to show transfer size.
    226         m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::wrapNSData(data), -1);
     226        m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::create(data), -1);
    227227    });
    228228}
  • TabularUnified trunk/Source/WebCore/platform/soup/SharedBufferSoup.cpp

    r215661 r215686  
    2828
    2929SharedBuffer::SharedBuffer(SoupBuffer* soupBuffer)
    30     : m_buffer(*new DataBuffer)
    31     , m_soupBuffer(soupBuffer)
    3230{
    3331    ASSERT(soupBuffer);
     32    m_size = soupBuffer->length;
     33    m_segments.append(DataSegment::create(GUniquePtr<SoupBuffer>(soupBuffer)));
    3434}
    3535
     
    4141GUniquePtr<SoupBuffer> SharedBuffer::createSoupBuffer(unsigned offset, unsigned size)
    4242{
    43     if (m_soupBuffer && !offset && !size) {
    44         GUniquePtr<SoupBuffer> buffer(soup_buffer_copy(m_soupBuffer.get()));
    45         return buffer;
    46     }
    47 
    4843    ref();
    4944    GUniquePtr<SoupBuffer> buffer(soup_buffer_new_with_owner(data() + offset, size ? size : this->size(), this, [](void* data) {
     
    5348}
    5449
    55 void SharedBuffer::clearPlatformData()
    56 {
    57     m_soupBuffer.reset();
    58 }
    59 
    60 void SharedBuffer::maybeTransferPlatformData()
    61 {
    62     if (!m_soupBuffer)
    63         return;
    64 
    65     ASSERT(!m_size);
    66 
    67     // Hang on to the m_soupBuffer pointer in a local pointer as append() will re-enter maybeTransferPlatformData()
    68     // and we need to make sure to early return when it does.
    69     GUniquePtr<SoupBuffer> soupBuffer;
    70     soupBuffer.swap(m_soupBuffer);
    71 
    72     append(soupBuffer->data, soupBuffer->length);
    73 }
    74 
    75 bool SharedBuffer::hasPlatformData() const
    76 {
    77     return m_soupBuffer.get();
    78 }
    79 
    80 const char* SharedBuffer::platformData() const
    81 {
    82     return m_soupBuffer->data;
    83 }
    84 
    85 unsigned SharedBuffer::platformDataSize() const
    86 {
    87     return m_soupBuffer->length;
    88 }
    89 
    90 bool SharedBuffer::maybeAppendPlatformData(SharedBuffer&)
    91 {
    92     return false;
    93 }
    94 
    95 bool SharedBuffer::tryReplaceContentsWithPlatformBuffer(SharedBuffer& newContents)
    96 {
    97     if (!newContents.hasPlatformData())
    98         return false;
    99 
    100     clear();
    101     // FIXME: Use GRefPtr instead of GUniquePtr for the SoupBuffer.
    102     m_soupBuffer.swap(newContents.m_soupBuffer);
    103     return true;
    104 }
    105 
    10650} // namespace WebCore
    10751
  • TabularUnified trunk/Source/WebCore/xml/XMLHttpRequest.cpp

    r215173 r215686  
    230230    ASSERT(doneWithoutErrors());
    231231
    232     auto result = m_binaryResponseBuilder ? m_binaryResponseBuilder->createArrayBuffer() : ArrayBuffer::create(nullptr, 0);
     232    auto result = m_binaryResponseBuilder ? m_binaryResponseBuilder->tryCreateArrayBuffer() : ArrayBuffer::create(nullptr, 0);
    233233    m_binaryResponseBuilder = nullptr;
    234234    return result;
  • TabularUnified trunk/Source/WebKit/mac/ChangeLog

    r215685 r215686  
     12017-04-24  Alex Christensen  <achristensen@webkit.org>
     2
     3        Reduce copies and allocations in SharedBuffer::append
     4        https://bugs.webkit.org/show_bug.cgi?id=170956
     5
     6        Reviewed by Andreas Kling.
     7
     8        * WebView/WebArchive.mm:
     9        (-[WebArchive initWithData:]):
     10        * WebView/WebFrame.mm:
     11        (-[WebFrame _loadData:MIMEType:textEncodingName:baseURL:unreachableURL:]):
     12        * WebView/WebResource.mm:
     13        (-[WebResource initWithCoder:]):
     14        (-[WebResource _initWithData:URL:MIMEType:textEncodingName:frameName:response:copyData:]):
     15
    1162017-04-24  Dan Bernstein  <mitz@apple.com>
    217
  • TabularUnified trunk/Source/WebKit/mac/WebView/WebArchive.mm

    r215661 r215686  
    201201
    202202    _private = [[WebArchivePrivate alloc] init];
    203     auto coreArchive = LegacyWebArchive::create(SharedBuffer::wrapNSData(data));
     203    auto coreArchive = LegacyWebArchive::create(SharedBuffer::create(data));
    204204    if (!coreArchive) {
    205205        [self release];
  • TabularUnified trunk/Source/WebKit/mac/WebView/WebFrame.mm

    r215661 r215686  
    24942494
    24952495    ResourceResponse response(responseURL, MIMEType, [data length], encodingName);
    2496     SubstituteData substituteData(WebCore::SharedBuffer::wrapNSData(data), [unreachableURL absoluteURL], response, SubstituteData::SessionHistoryVisibility::Hidden);
     2496    SubstituteData substituteData(WebCore::SharedBuffer::create(data), [unreachableURL absoluteURL], response, SubstituteData::SessionHistoryVisibility::Hidden);
    24972497
    24982498    _private->coreFrame->loader().load(FrameLoadRequest(_private->coreFrame, request, ShouldOpenExternalURLsPolicy::ShouldNotAllow, substituteData));
  • TabularUnified trunk/Source/WebKit/mac/WebView/WebResource.mm

    r215661 r215686  
    150150    }
    151151
    152     auto coreResource = ArchiveResource::create(SharedBuffer::wrapNSData(data), url, mimeType, textEncoding, frameName, response);
     152    auto coreResource = ArchiveResource::create(SharedBuffer::create(data), url, mimeType, textEncoding, frameName, response);
    153153    if (!coreResource) {
    154154        [self release];
     
    302302    }
    303303
    304     auto coreResource = ArchiveResource::create(SharedBuffer::wrapNSData(copyData ? [[data copy] autorelease] : data), URL, MIMEType, textEncodingName, frameName, response);
     304    auto coreResource = ArchiveResource::create(SharedBuffer::create(copyData ? [[data copy] autorelease] : data), URL, MIMEType, textEncodingName, frameName, response);
    305305    if (!coreResource) {
    306306        [self release];
  • TabularUnified trunk/Source/WebKit2/ChangeLog

    r215683 r215686  
     12017-04-24  Alex Christensen  <achristensen@webkit.org>
     2
     3        Reduce copies and allocations in SharedBuffer::append
     4        https://bugs.webkit.org/show_bug.cgi?id=170956
     5
     6        Reviewed by Andreas Kling.
     7
     8        * NetworkProcess/cocoa/NetworkSessionCocoa.mm:
     9        (-[WKNetworkSessionDelegate URLSession:dataTask:didReceiveData:]):
     10        * Platform/IPC/DataReference.cpp:
     11        (IPC::SharedBufferDataReference::encode):
     12        * Shared/ShareableResource.cpp:
     13        (WebKit::ShareableResource::wrapInSharedBuffer):
     14        * UIProcess/API/Cocoa/WKURLSchemeHandlerTask.mm:
     15        (-[WKURLSchemeHandlerTaskImpl didReceiveData:]):
     16        * WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm:
     17        (-[WKWebProcessPlugInBrowserContextController _setEditingDelegate:]):
     18        * WebProcess/Plugins/PDF/PDFPlugin.mm:
     19        (WebKit::PDFPlugin::addArchiveResource):
     20        (WebKit::PDFPlugin::liveResourceData):
     21        (WebKit::PDFPlugin::writeItemsToPasteboard):
     22        * WebProcess/Plugins/PluginView.cpp:
     23        (WebKit::PluginView::redeliverManualStream):
     24        * WebProcess/WebCoreSupport/mac/WebDragClientMac.mm:
     25        (WebKit::WebDragClient::declareAndWriteDragImage):
     26        * WebProcess/WebPage/mac/WebPageMac.mm:
     27        (WebKit::WebPage::cachedResponseDataForURL):
     28
    1292017-04-24  Carlos Garcia Campos  <cgarcia@igalia.com>
    230
  • TabularUnified trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkSessionCocoa.mm

    r215661 r215686  
    387387    auto storedCredentials = _withCredentials ? WebCore::StoredCredentials::AllowStoredCredentials : WebCore::StoredCredentials::DoNotAllowStoredCredentials;
    388388    if (auto* networkDataTask = _session->dataTaskForIdentifier(dataTask.taskIdentifier, storedCredentials))
    389         networkDataTask->didReceiveData(WebCore::SharedBuffer::wrapNSData(data));
     389        networkDataTask->didReceiveData(WebCore::SharedBuffer::create(data));
    390390}
    391391
  • TabularUnified trunk/Source/WebKit2/Platform/IPC/DataReference.cpp

    r215661 r215686  
    4848    encoder << bufferSize;
    4949
    50     const char* partialData;
    51     unsigned position = 0;
    52     while (position < bufferSize) {
    53         unsigned bytesToWrite = m_buffer->getSomeData(partialData, position);
    54         encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(partialData), bytesToWrite, 1);
    55         position += bytesToWrite;
    56     }
     50    for (const auto& segment : *m_buffer)
     51        encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(segment->data()), segment->size(), 1);
    5752}
    5853
  • TabularUnified trunk/Source/WebKit2/Shared/ShareableResource.cpp

    r215661 r215686  
    8888    RetainPtr<CFAllocatorRef> deallocator = adoptCF(createShareableResourceDeallocator(this));
    8989    RetainPtr<CFDataRef> cfData = adoptCF(CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data()), static_cast<CFIndex>(size()), deallocator.get()));
    90     return SharedBuffer::wrapCFData(cfData.get());
     90    return SharedBuffer::create(cfData.get());
    9191#elif USE(SOUP)
    9292    return SharedBuffer::wrapSoupBuffer(soup_buffer_new_with_owner(data(), size(), this, [](void* data) { static_cast<ShareableResource*>(data)->deref(); }));
  • TabularUnified trunk/Source/WebKit2/UIProcess/API/Cocoa/WKURLSchemeHandlerTask.mm

    r215661 r215686  
    7171- (void)didReceiveData:(NSData *)data
    7272{
    73     auto result = _urlSchemeHandlerTask->task().didReceiveData(WebCore::SharedBuffer::wrapNSData(data));
     73    auto result = _urlSchemeHandlerTask->task().didReceiveData(WebCore::SharedBuffer::create(data));
    7474    raiseExceptionIfNecessary(result);
    7575}
  • TabularUnified trunk/Source/WebKit2/WebProcess/InjectedBundle/API/mac/WKWebProcessPlugInBrowserContextController.mm

    r215661 r215686  
    647647            for (NSString *type in dataByType) {
    648648                pasteboardTypes.append(type);
    649                 pasteboardData.append(SharedBuffer::wrapNSData(dataByType[type]));
     649                pasteboardData.append(SharedBuffer::create(dataByType[type]));
    650650            };
    651651        }
  • TabularUnified trunk/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.mm

    r215661 r215686  
    917917    ResourceResponse synthesizedResponse(response.get());
    918918
    919     RefPtr<ArchiveResource> resource = ArchiveResource::create(SharedBuffer::wrapCFData(m_data.get()), m_sourceURL, "application/pdf", String(), String(), synthesizedResponse);
     919    RefPtr<ArchiveResource> resource = ArchiveResource::create(SharedBuffer::create(m_data.get()), m_sourceURL, "application/pdf", String(), String(), synthesizedResponse);
    920920    pluginView()->frame()->document()->loader()->addArchiveResource(resource.releaseNonNull());
    921921}
     
    17571757        return nullptr;
    17581758
    1759     return SharedBuffer::wrapNSData(pdfData);
     1759    return SharedBuffer::create(pdfData);
    17601760}
    17611761
     
    18281828            webProcess.parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::SetPasteboardStringForType(pasteboardName, type, plainTextString.get()), Messages::WebPasteboardProxy::SetPasteboardStringForType::Reply(newChangeCount), 0);
    18291829        } else {
    1830             RefPtr<SharedBuffer> buffer = SharedBuffer::wrapNSData(data);
     1830            RefPtr<SharedBuffer> buffer = SharedBuffer::create(data);
    18311831
    18321832            if (!buffer)
  • TabularUnified trunk/Source/WebKit2/WebProcess/Plugins/PluginView.cpp

    r215661 r215686  
    13121312    // Deliver the data.
    13131313    if (m_manualStreamData) {
    1314         const char* data;
    1315         unsigned position = 0;
    1316 
    1317         while (unsigned length = m_manualStreamData->getSomeData(data, position)) {
    1318             manualLoadDidReceiveData(data, length);
    1319             position += length;
    1320         }
    1321 
     1314        for (const auto& segment : *m_manualStreamData)
     1315            manualLoadDidReceiveData(segment->data(), segment->size());
    13221316        m_manualStreamData = nullptr;
    13231317    }
  • TabularUnified trunk/Source/WebKit2/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm

    r215661 r215686  
    166166    size_t archiveSize = 0;
    167167    if (data) {
    168         RefPtr<SharedBuffer> archiveBuffer = SharedBuffer::wrapNSData((NSData *)data.get());
     168        RefPtr<SharedBuffer> archiveBuffer = SharedBuffer::create((NSData *)data.get());
    169169        RefPtr<SharedMemory> archiveSharedMemoryBuffer = SharedMemory::allocate(archiveBuffer->size());
    170170        if (!archiveSharedMemoryBuffer)
  • TabularUnified trunk/Source/WebKit2/WebProcess/WebPage/mac/WebPageMac.mm

    r215661 r215686  
    710710RefPtr<SharedBuffer> WebPage::cachedResponseDataForURL(const URL& url)
    711711{
    712     return SharedBuffer::wrapNSData([cachedResponseForURL(this, url) data]);
     712    return SharedBuffer::create([cachedResponseForURL(this, url) data]);
    713713}
    714714
  • TabularUnified trunk/Tools/ChangeLog

    r215683 r215686  
     12017-04-24  Alex Christensen  <achristensen@webkit.org>
     2
     3        Reduce copies and allocations in SharedBuffer::append
     4        https://bugs.webkit.org/show_bug.cgi?id=170956
     5
     6        Reviewed by Andreas Kling.
     7
     8        * TestWebKitAPI/Tests/WebCore/cocoa/SharedBuffer.mm:
     9        (TestWebKitAPI::TEST_F):
     10
    1112017-04-24  Carlos Garcia Campos  <cgarcia@igalia.com>
    212
  • TabularUnified trunk/Tools/TestWebKitAPI/Tests/WebCore/SharedBuffer.cpp

    r215319 r215686  
    8888}
    8989
    90 TEST_F(SharedBufferTest, createArrayBuffer)
     90TEST_F(SharedBufferTest, tryCreateArrayBuffer)
    9191{
    9292    char testData0[] = "Hello";
     
    9696    sharedBuffer->append(testData1, strlen(testData1));
    9797    sharedBuffer->append(testData2, strlen(testData2));
    98     RefPtr<ArrayBuffer> arrayBuffer = sharedBuffer->createArrayBuffer();
     98    RefPtr<ArrayBuffer> arrayBuffer = sharedBuffer->tryCreateArrayBuffer();
    9999    char expectedConcatenation[] = "HelloWorldGoodbye";
    100100    ASSERT_EQ(strlen(expectedConcatenation), arrayBuffer->byteLength());
     
    102102}
    103103
    104 TEST_F(SharedBufferTest, createArrayBufferLargeSegments)
     104TEST_F(SharedBufferTest, tryCreateArrayBufferLargeSegments)
    105105{
    106106    Vector<char> vector0(0x4000, 'a');
     
    111111    sharedBuffer->append(WTFMove(vector1));
    112112    sharedBuffer->append(WTFMove(vector2));
    113     RefPtr<ArrayBuffer> arrayBuffer = sharedBuffer->createArrayBuffer();
     113    RefPtr<ArrayBuffer> arrayBuffer = sharedBuffer->tryCreateArrayBuffer();
    114114    ASSERT_EQ(0x4000U + 0x4000U + 0x4000U, arrayBuffer->byteLength());
    115115    int position = 0;
  • TabularUnified trunk/Tools/TestWebKitAPI/Tests/WebCore/cocoa/SharedBuffer.mm

    r215661 r215686  
    6060        expectDataArraysEqual(@[ helloData, worldData ], buffer->createNSDataArray().get());
    6161
    62         expectDataArraysEqual(@[ helloData ], SharedBuffer::wrapNSData(helloData)->createNSDataArray().get());
    63         expectDataArraysEqual(@[ worldData ], SharedBuffer::wrapCFData((CFDataRef)worldData)->createNSDataArray().get());
     62        expectDataArraysEqual(@[ helloData ], SharedBuffer::create(helloData)->createNSDataArray().get());
     63        expectDataArraysEqual(@[ worldData ], SharedBuffer::create((CFDataRef)worldData)->createNSDataArray().get());
    6464
    6565        expectDataArraysEqual(@[ [NSData dataWithContentsOfFile:tempFilePath()] ], SharedBuffer::createWithContentsOfFile(tempFilePath())->createNSDataArray().get());
Note: See TracChangeset for help on using the changeset viewer.