Title: [145820] trunk/Source/WebCore
Revision
145820
Author
beid...@apple.com
Date
2013-03-14 09:28:04 -0700 (Thu, 14 Mar 2013)

Log Message

Add a mode to ResourceLoader that takes SharedBuffers instead of raw pointers and lengths.
<rdar://problem/13416953> and https://bugs.webkit.org/show_bug.cgi?id=112310

Reviewed by Andy Estes.

No new tests (No independently testable change in behavior).

Many of the tested platforms deliver data buffers to their ResourceHandles from objects
that encapsulate a data buffer such as NSData (Mac), CFDataRef (CF), or QByteArray (qt).

If those platforms also augmented SharedBuffer to wrap their native object (which Mac/CF do)
and there existed ResourceLoader callbacks to take that SharedBuffer instead of char* + length,
then many resource loads could avoid a useless copy.

At least on Mac, there are some extremely important behind-the-scenes optimizations for NS/CFData
that will be a more important win than simply avoiding a copy.

This patch adds that SharedBuffer-based callback with the hope that all platforms could find a
way to use a buffer-encapsulating object going forward, and we could therefore deprecate the
char* + length version of didReceiveData.

* platform/network/ResourceHandleClient.h:
(WebCore::ResourceHandleClient::didReceiveBuffer): Add a didReceiveBuffer callback that takes
  a SharedBuffer object. The default implementation passes raw bytes + length to didReceiveData.

* loader/ResourceLoader.cpp:
(WebCore::ResourceLoader::addDataOrBuffer): Replacing addData(), optionally adding the data from
  either a data+length or SharedBuffer
(WebCore::ResourceLoader::didReceiveData): Pipe to didReceiveDataOrBuffer.
(WebCore::ResourceLoader::didReceiveBuffer): Pipe to didReceiveDataOrBuffer.
(WebCore::ResourceLoader::didReceiveDataOrBuffer): Single chokepoint for receiving data.
* loader/ResourceLoader.h: Add OVERRIDE to all of the ResourceHandleClient methods to help
  catch future mistakes. Remove "virtual" from methods that didn't need it. Make "addData" into
  "addDataOrBuffer" and make it private.

* loader/NetscapePlugInStreamLoader.cpp:
(WebCore::NetscapePlugInStreamLoader::didReceiveData): Pipe to didReceiveDataOrBuffer.
(WebCore::NetscapePlugInStreamLoader::didReceiveBuffer): Pipe to didReceiveDataOrBuffer.
(WebCore::NetscapePlugInStreamLoader::didReceiveDataOrBuffer): Single chokepoint for receiving data.
* loader/NetscapePlugInStreamLoader.h:

* loader/SubresourceLoader.cpp:
(WebCore::SubresourceLoader::didReceiveData): Pipe to didReceiveDataOrBuffer.
(WebCore::SubresourceLoader::didReceiveBuffer): Pipe to didReceiveDataOrBuffer.
(WebCore::SubresourceLoader::didReceiveDataOrBuffer): Single chokepoint for receiving data. Also,
  rely on ResourceLoader's base implementation for notifying the ResourceLoadNotifier.
* loader/SubresourceLoader.h:

* loader/ResourceBuffer.cpp:
(WebCore::ResourceBuffer::append): Add a mode that appends a SharedBuffer.
* loader/ResourceBuffer.h:

* platform/cf/SharedBufferCF.cpp:
(WebCore::SharedBuffer::maybeTransferPlatformData): Fix a bug where appending data to a CFData-backed
  SharedBuffer would re-enter maybeTransferPlatformData and blow out the stack.

* platform/network/mac/ResourceHandleMac.mm:
(-[WebCoreResourceHandleAsDelegate connection:didReceiveData:lengthReceived:]): Send a wrapped NSData
  to didReceiveBuffer() instead of sending its char* and length to didReceiveData()

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (145819 => 145820)


--- trunk/Source/WebCore/ChangeLog	2013-03-14 16:14:57 UTC (rev 145819)
+++ trunk/Source/WebCore/ChangeLog	2013-03-14 16:28:04 UTC (rev 145820)
@@ -1,3 +1,65 @@
+2013-03-14  Brady Eidson  <beid...@apple.com>
+
+        Add a mode to ResourceLoader that takes SharedBuffers instead of raw pointers and lengths.
+        <rdar://problem/13416953> and https://bugs.webkit.org/show_bug.cgi?id=112310
+
+        Reviewed by Andy Estes.
+
+        No new tests (No independently testable change in behavior).
+
+        Many of the tested platforms deliver data buffers to their ResourceHandles from objects
+        that encapsulate a data buffer such as NSData (Mac), CFDataRef (CF), or QByteArray (qt).
+
+        If those platforms also augmented SharedBuffer to wrap their native object (which Mac/CF do)
+        and there existed ResourceLoader callbacks to take that SharedBuffer instead of char* + length,
+        then many resource loads could avoid a useless copy.
+
+        At least on Mac, there are some extremely important behind-the-scenes optimizations for NS/CFData
+        that will be a more important win than simply avoiding a copy.
+
+        This patch adds that SharedBuffer-based callback with the hope that all platforms could find a 
+        way to use a buffer-encapsulating object going forward, and we could therefore deprecate the
+        char* + length version of didReceiveData.
+
+        * platform/network/ResourceHandleClient.h:
+        (WebCore::ResourceHandleClient::didReceiveBuffer): Add a didReceiveBuffer callback that takes 
+          a SharedBuffer object. The default implementation passes raw bytes + length to didReceiveData.
+
+        * loader/ResourceLoader.cpp:
+        (WebCore::ResourceLoader::addDataOrBuffer): Replacing addData(), optionally adding the data from
+          either a data+length or SharedBuffer
+        (WebCore::ResourceLoader::didReceiveData): Pipe to didReceiveDataOrBuffer.
+        (WebCore::ResourceLoader::didReceiveBuffer): Pipe to didReceiveDataOrBuffer.
+        (WebCore::ResourceLoader::didReceiveDataOrBuffer): Single chokepoint for receiving data.
+        * loader/ResourceLoader.h: Add OVERRIDE to all of the ResourceHandleClient methods to help
+          catch future mistakes. Remove "virtual" from methods that didn't need it. Make "addData" into
+          "addDataOrBuffer" and make it private.
+
+        * loader/NetscapePlugInStreamLoader.cpp:
+        (WebCore::NetscapePlugInStreamLoader::didReceiveData): Pipe to didReceiveDataOrBuffer.
+        (WebCore::NetscapePlugInStreamLoader::didReceiveBuffer): Pipe to didReceiveDataOrBuffer.
+        (WebCore::NetscapePlugInStreamLoader::didReceiveDataOrBuffer): Single chokepoint for receiving data.
+        * loader/NetscapePlugInStreamLoader.h:
+
+        * loader/SubresourceLoader.cpp:
+        (WebCore::SubresourceLoader::didReceiveData): Pipe to didReceiveDataOrBuffer.
+        (WebCore::SubresourceLoader::didReceiveBuffer): Pipe to didReceiveDataOrBuffer.
+        (WebCore::SubresourceLoader::didReceiveDataOrBuffer): Single chokepoint for receiving data. Also,
+          rely on ResourceLoader's base implementation for notifying the ResourceLoadNotifier.
+        * loader/SubresourceLoader.h:
+
+        * loader/ResourceBuffer.cpp:
+        (WebCore::ResourceBuffer::append): Add a mode that appends a SharedBuffer.
+        * loader/ResourceBuffer.h:
+
+        * platform/cf/SharedBufferCF.cpp:
+        (WebCore::SharedBuffer::maybeTransferPlatformData): Fix a bug where appending data to a CFData-backed
+          SharedBuffer would re-enter maybeTransferPlatformData and blow out the stack.
+
+        * platform/network/mac/ResourceHandleMac.mm:
+        (-[WebCoreResourceHandleAsDelegate connection:didReceiveData:lengthReceived:]): Send a wrapped NSData
+          to didReceiveBuffer() instead of sending its char* and length to didReceiveData()
+
 2013-03-14  Yury Semikhatsky  <yu...@chromium.org>
 
         Web Inspector: nuke bottom up CPU profile calculation on backend

Modified: trunk/Source/WebCore/loader/NetscapePlugInStreamLoader.cpp (145819 => 145820)


--- trunk/Source/WebCore/loader/NetscapePlugInStreamLoader.cpp	2013-03-14 16:14:57 UTC (rev 145819)
+++ trunk/Source/WebCore/loader/NetscapePlugInStreamLoader.cpp	2013-03-14 16:28:04 UTC (rev 145820)
@@ -95,11 +95,21 @@
 
 void NetscapePlugInStreamLoader::didReceiveData(const char* data, int length, long long encodedDataLength, DataPayloadType dataPayloadType)
 {
+    didReceiveDataOrBuffer(data, length, 0, encodedDataLength, dataPayloadType);
+}
+
+void NetscapePlugInStreamLoader::didReceiveBuffer(PassRefPtr<SharedBuffer> buffer, long long encodedDataLength, DataPayloadType dataPayloadType)
+{
+    didReceiveDataOrBuffer(0, 0, buffer, encodedDataLength, dataPayloadType);
+}
+
+void NetscapePlugInStreamLoader::didReceiveDataOrBuffer(const char* data, int length, PassRefPtr<SharedBuffer> buffer, long long encodedDataLength, DataPayloadType dataPayloadType)
+{
     RefPtr<NetscapePlugInStreamLoader> protect(this);
+    
+    m_client->didReceiveData(this, buffer ? buffer->data() : data, buffer ? buffer->size() : length);
 
-    m_client->didReceiveData(this, data, length);
-    
-    ResourceLoader::didReceiveData(data, length, encodedDataLength, dataPayloadType);
+    ResourceLoader::didReceiveDataOrBuffer(data, length, buffer, encodedDataLength, dataPayloadType);
 }
 
 void NetscapePlugInStreamLoader::didFinishLoading(double finishTime)

Modified: trunk/Source/WebCore/loader/NetscapePlugInStreamLoader.h (145819 => 145820)


--- trunk/Source/WebCore/loader/NetscapePlugInStreamLoader.h	2013-03-14 16:14:57 UTC (rev 145819)
+++ trunk/Source/WebCore/loader/NetscapePlugInStreamLoader.h	2013-03-14 16:28:04 UTC (rev 145820)
@@ -58,6 +58,7 @@
 private:
     virtual void didReceiveResponse(const ResourceResponse&) OVERRIDE;
     virtual void didReceiveData(const char*, int, long long encodedDataLength, DataPayloadType) OVERRIDE;
+    virtual void didReceiveBuffer(PassRefPtr<SharedBuffer>, long long encodedDataLength, DataPayloadType) OVERRIDE;
     virtual void didFinishLoading(double finishTime) OVERRIDE;
     virtual void didFail(const ResourceError&) OVERRIDE;
 
@@ -68,6 +69,8 @@
     virtual void willCancel(const ResourceError&) OVERRIDE;
     virtual void didCancel(const ResourceError&) OVERRIDE;
 
+    void didReceiveDataOrBuffer(const char*, int, PassRefPtr<SharedBuffer>, long long encodedDataLength, DataPayloadType);
+
     NetscapePlugInStreamLoaderClient* m_client;
 };
 

Modified: trunk/Source/WebCore/loader/ResourceBuffer.cpp (145819 => 145820)


--- trunk/Source/WebCore/loader/ResourceBuffer.cpp	2013-03-14 16:14:57 UTC (rev 145819)
+++ trunk/Source/WebCore/loader/ResourceBuffer.cpp	2013-03-14 16:28:04 UTC (rev 145820)
@@ -71,6 +71,11 @@
     m_sharedBuffer->append(data, size);
 }
 
+void ResourceBuffer::append(SharedBuffer* buffer)
+{
+    m_sharedBuffer->append(buffer);
+}
+
 #if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
 void ResourceBuffer::append(CFDataRef data)
 {

Modified: trunk/Source/WebCore/loader/ResourceBuffer.h (145819 => 145820)


--- trunk/Source/WebCore/loader/ResourceBuffer.h	2013-03-14 16:14:57 UTC (rev 145819)
+++ trunk/Source/WebCore/loader/ResourceBuffer.h	2013-03-14 16:28:04 UTC (rev 145820)
@@ -55,6 +55,7 @@
     virtual bool isEmpty() const;
 
     void append(const char*, unsigned);
+    void append(SharedBuffer*);
 #if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
     void append(CFDataRef);
 #endif

Modified: trunk/Source/WebCore/loader/ResourceLoader.cpp (145819 => 145820)


--- trunk/Source/WebCore/loader/ResourceLoader.cpp	2013-03-14 16:14:57 UTC (rev 145819)
+++ trunk/Source/WebCore/loader/ResourceLoader.cpp	2013-03-14 16:28:04 UTC (rev 145820)
@@ -200,20 +200,24 @@
 }
     
 
-void ResourceLoader::addData(const char* data, int length, DataPayloadType dataPayloadType)
+void ResourceLoader::addDataOrBuffer(const char* data, int length, SharedBuffer* buffer, DataPayloadType dataPayloadType)
 {
     if (m_options.dataBufferingPolicy == DoNotBufferData)
         return;
 
     if (dataPayloadType == DataPayloadWholeResource) {
-        m_resourceData = ResourceBuffer::create(data, length);
+        m_resourceData = buffer ? ResourceBuffer::adoptSharedBuffer(buffer) : ResourceBuffer::create(data, length);
         return;
     }
         
     if (!m_resourceData)
-        m_resourceData = ResourceBuffer::create(data, length);
-    else
-        m_resourceData->append(data, length);
+        m_resourceData = buffer ? ResourceBuffer::adoptSharedBuffer(buffer) : ResourceBuffer::create(data, length);
+    else {
+        if (buffer)
+            m_resourceData->append(buffer);
+        else
+            m_resourceData->append(data, length);
+    }
 }
 
 void ResourceLoader::clearResourceData()
@@ -295,16 +299,31 @@
     // ASSERT(con == connection);
     // ASSERT(!m_reachedTerminalState);
 
+    didReceiveDataOrBuffer(data, length, 0, encodedDataLength, dataPayloadType);
+}
+
+void ResourceLoader::didReceiveBuffer(PassRefPtr<SharedBuffer> buffer, long long encodedDataLength, DataPayloadType dataPayloadType)
+{
+    didReceiveDataOrBuffer(0, 0, buffer, encodedDataLength, dataPayloadType);
+}
+
+void ResourceLoader::didReceiveDataOrBuffer(const char* data, int length, PassRefPtr<SharedBuffer> prpBuffer, long long encodedDataLength, DataPayloadType dataPayloadType)
+{
+    // This method should only get data+length *OR* a SharedBuffer.
+    ASSERT(!prpBuffer || (!data && !length));
+
     // Protect this in this delegate method since the additional processing can do
     // anything including possibly derefing this; one example of this is Radar 3266216.
     RefPtr<ResourceLoader> protector(this);
+    RefPtr<SharedBuffer> buffer = prpBuffer;
 
-    addData(data, length, dataPayloadType);
+    addDataOrBuffer(data, length, buffer.get(), dataPayloadType);
+    
     // FIXME: If we get a resource with more than 2B bytes, this code won't do the right thing.
     // However, with today's computers and networking speeds, this won't happen in practice.
     // Could be an issue with a giant local file.
     if (m_options.sendLoadCallbacks == SendCallbacks && m_frame)
-        frameLoader()->notifier()->didReceiveData(this, data, length, static_cast<int>(encodedDataLength));
+        frameLoader()->notifier()->didReceiveData(this, buffer ? buffer->data() : data, buffer ? buffer->size() : length, static_cast<int>(encodedDataLength));
 }
 
 void ResourceLoader::willStopBufferingData(const char* data, int length)
@@ -469,6 +488,13 @@
     InspectorInstrumentation::didReceiveResourceData(cookie);
 }
 
+void ResourceLoader::didReceiveBuffer(ResourceHandle*, PassRefPtr<SharedBuffer> buffer, int encodedDataLength)
+{
+    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willReceiveResourceData(m_frame.get(), identifier(), encodedDataLength);
+    didReceiveBuffer(buffer, encodedDataLength, DataPayloadBytes);
+    InspectorInstrumentation::didReceiveResourceData(cookie);
+}
+
 void ResourceLoader::didFinishLoading(ResourceHandle*, double finishTime)
 {
     didFinishLoading(finishTime);

Modified: trunk/Source/WebCore/loader/ResourceLoader.h (145819 => 145820)


--- trunk/Source/WebCore/loader/ResourceLoader.h	2013-03-14 16:14:57 UTC (rev 145819)
+++ trunk/Source/WebCore/loader/ResourceLoader.h	2013-03-14 16:28:04 UTC (rev 145820)
@@ -73,15 +73,16 @@
     virtual void releaseResources();
     const ResourceResponse& response() const;
 
-    virtual void addData(const char*, int, DataPayloadType);
-    virtual PassRefPtr<ResourceBuffer> resourceData();
+    PassRefPtr<ResourceBuffer> resourceData();
     void clearResourceData();
+    
     virtual bool isSubresourceLoader();
     
     virtual void willSendRequest(ResourceRequest&, const ResourceResponse& redirectResponse);
     virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
     virtual void didReceiveResponse(const ResourceResponse&);
     virtual void didReceiveData(const char*, int, long long encodedDataLength, DataPayloadType);
+    virtual void didReceiveBuffer(PassRefPtr<SharedBuffer>, long long encodedDataLength, DataPayloadType);
     virtual void didReceiveCachedMetadata(const char*, int) { }
     void willStopBufferingData(const char*, int);
     virtual void didFinishLoading(double finishTime);
@@ -100,36 +101,37 @@
     virtual void receivedCancellation(const AuthenticationChallenge&);
 
     // ResourceHandleClient
-    virtual void willSendRequest(ResourceHandle*, ResourceRequest&, const ResourceResponse& redirectResponse);
-    virtual void didSendData(ResourceHandle*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
-    virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&);
-    virtual void didReceiveData(ResourceHandle*, const char*, int, int encodedDataLength);
-    virtual void didReceiveCachedMetadata(ResourceHandle*, const char* data, int length) { didReceiveCachedMetadata(data, length); }
-    virtual void didFinishLoading(ResourceHandle*, double finishTime);
-    virtual void didFail(ResourceHandle*, const ResourceError&);
-    virtual void wasBlocked(ResourceHandle*);
-    virtual void cannotShowURL(ResourceHandle*);
+    virtual void willSendRequest(ResourceHandle*, ResourceRequest&, const ResourceResponse& redirectResponse) OVERRIDE;
+    virtual void didSendData(ResourceHandle*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) OVERRIDE;
+    virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&) OVERRIDE;
+    virtual void didReceiveData(ResourceHandle*, const char*, int, int encodedDataLength) OVERRIDE;
+    virtual void didReceiveBuffer(ResourceHandle*, PassRefPtr<SharedBuffer>, int encodedDataLength) OVERRIDE;
+    virtual void didReceiveCachedMetadata(ResourceHandle*, const char* data, int length) OVERRIDE { didReceiveCachedMetadata(data, length); }
+    virtual void didFinishLoading(ResourceHandle*, double finishTime) OVERRIDE;
+    virtual void didFail(ResourceHandle*, const ResourceError&) OVERRIDE;
+    virtual void wasBlocked(ResourceHandle*) OVERRIDE;
+    virtual void cannotShowURL(ResourceHandle*) OVERRIDE;
     virtual void willStopBufferingData(ResourceHandle*, const char* data, int length) { willStopBufferingData(data, length); } 
-    virtual bool shouldUseCredentialStorage(ResourceHandle*) { return shouldUseCredentialStorage(); }
-    virtual void didReceiveAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge& challenge) { didReceiveAuthenticationChallenge(challenge); } 
-    virtual void didCancelAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge& challenge) { didCancelAuthenticationChallenge(challenge); } 
+    virtual bool shouldUseCredentialStorage(ResourceHandle*) OVERRIDE { return shouldUseCredentialStorage(); }
+    virtual void didReceiveAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge& challenge) OVERRIDE { didReceiveAuthenticationChallenge(challenge); } 
+    virtual void didCancelAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge& challenge) OVERRIDE { didCancelAuthenticationChallenge(challenge); } 
 #if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
-    virtual void didReceiveDataArray(ResourceHandle*, CFArrayRef dataArray);
+    virtual void didReceiveDataArray(ResourceHandle*, CFArrayRef dataArray) OVERRIDE;
 #endif
 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
-    virtual bool canAuthenticateAgainstProtectionSpace(ResourceHandle*, const ProtectionSpace& protectionSpace) { return canAuthenticateAgainstProtectionSpace(protectionSpace); }
+    virtual bool canAuthenticateAgainstProtectionSpace(ResourceHandle*, const ProtectionSpace& protectionSpace) OVERRIDE { return canAuthenticateAgainstProtectionSpace(protectionSpace); }
 #endif
-    virtual void receivedCancellation(ResourceHandle*, const AuthenticationChallenge& challenge) { receivedCancellation(challenge); }
+    virtual void receivedCancellation(ResourceHandle*, const AuthenticationChallenge& challenge) OVERRIDE { receivedCancellation(challenge); }
 #if PLATFORM(MAC)
 #if USE(CFNETWORK)
-    virtual CFCachedURLResponseRef willCacheResponse(ResourceHandle*, CFCachedURLResponseRef);
+    virtual CFCachedURLResponseRef willCacheResponse(ResourceHandle*, CFCachedURLResponseRef) OVERRIDE;
 #else
-    virtual NSCachedURLResponse* willCacheResponse(ResourceHandle*, NSCachedURLResponse*);
+    virtual NSCachedURLResponse* willCacheResponse(ResourceHandle*, NSCachedURLResponse*) OVERRIDE;
 #endif
 #endif // PLATFORM(MAC)
 #if PLATFORM(WIN) && USE(CFNETWORK)
     // FIXME: Windows should use willCacheResponse - <https://bugs.webkit.org/show_bug.cgi?id=57257>.
-    virtual bool shouldCacheResponse(ResourceHandle*, CFCachedURLResponseRef);
+    virtual bool shouldCacheResponse(ResourceHandle*, CFCachedURLResponseRef) OVERRIDE;
 #endif
 #if PLATFORM(CHROMIUM)
     virtual void didDownloadData(ResourceHandle*, int);
@@ -162,6 +164,8 @@
 
     bool cancelled() const { return m_cancelled; }
 
+    void didReceiveDataOrBuffer(const char*, int, PassRefPtr<SharedBuffer>, long long encodedDataLength, DataPayloadType);
+
     RefPtr<ResourceHandle> m_handle;
     RefPtr<Frame> m_frame;
     RefPtr<DocumentLoader> m_documentLoader;
@@ -171,6 +175,8 @@
     virtual void willCancel(const ResourceError&) = 0;
     virtual void didCancel(const ResourceError&) = 0;
 
+    void addDataOrBuffer(const char*, int, SharedBuffer*, DataPayloadType);
+
     ResourceRequest m_request;
     ResourceRequest m_originalRequest; // Before redirects.
     RefPtr<ResourceBuffer> m_resourceData;

Modified: trunk/Source/WebCore/loader/SubresourceLoader.cpp (145819 => 145820)


--- trunk/Source/WebCore/loader/SubresourceLoader.cpp	2013-03-14 16:14:57 UTC (rev 145819)
+++ trunk/Source/WebCore/loader/SubresourceLoader.cpp	2013-03-14 16:28:04 UTC (rev 145820)
@@ -215,6 +215,16 @@
 
 void SubresourceLoader::didReceiveData(const char* data, int length, long long encodedDataLength, DataPayloadType dataPayloadType)
 {
+    didReceiveDataOrBuffer(data, length, 0, encodedDataLength, dataPayloadType);
+}
+
+void SubresourceLoader::didReceiveBuffer(PassRefPtr<SharedBuffer> buffer, long long encodedDataLength, DataPayloadType dataPayloadType)
+{
+    didReceiveDataOrBuffer(0, 0, buffer, encodedDataLength, dataPayloadType);
+}
+
+void SubresourceLoader::didReceiveDataOrBuffer(const char* data, int length, PassRefPtr<SharedBuffer> prpBuffer, long long encodedDataLength, DataPayloadType dataPayloadType)
+{
     if (m_resource->response().httpStatusCode() >= 400 && !m_resource->shouldIgnoreHTTPStatusCodeErrors())
         return;
     ASSERT(!m_resource->resourceToRevalidate());
@@ -223,11 +233,12 @@
     // Reference the object in this method since the additional processing can do
     // anything including removing the last reference to this object; one example of this is 3266216.
     RefPtr<SubresourceLoader> protect(this);
-    addData(data, length, dataPayloadType);
+    RefPtr<SharedBuffer> buffer = prpBuffer;
+    
+    ResourceLoader::didReceiveDataOrBuffer(data, length, buffer, encodedDataLength, dataPayloadType);
+
     if (!m_loadingMultipartContent)
-        sendDataToResource(data, length);
-    if (shouldSendResourceLoadCallbacks() && m_frame)
-        frameLoader()->notifier()->didReceiveData(this, data, length, static_cast<int>(encodedDataLength));
+        sendDataToResource(buffer ? buffer->data() : data, buffer ? buffer->size() : length);
 }
 
 bool SubresourceLoader::checkForHTTPStatusCodeError()

Modified: trunk/Source/WebCore/loader/SubresourceLoader.h (145819 => 145820)


--- trunk/Source/WebCore/loader/SubresourceLoader.h	2013-03-14 16:14:57 UTC (rev 145819)
+++ trunk/Source/WebCore/loader/SubresourceLoader.h	2013-03-14 16:28:04 UTC (rev 145820)
@@ -61,6 +61,7 @@
     virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) OVERRIDE;
     virtual void didReceiveResponse(const ResourceResponse&) OVERRIDE;
     virtual void didReceiveData(const char*, int, long long encodedDataLength, DataPayloadType) OVERRIDE;
+    virtual void didReceiveBuffer(PassRefPtr<SharedBuffer>, long long encodedDataLength, DataPayloadType) OVERRIDE;
     virtual void didReceiveCachedMetadata(const char*, int) OVERRIDE;
     virtual void didFinishLoading(double finishTime) OVERRIDE;
     virtual void didFail(const ResourceError&) OVERRIDE;
@@ -79,6 +80,8 @@
     bool checkForHTTPStatusCodeError();
     void sendDataToResource(const char*, int);
 
+    void didReceiveDataOrBuffer(const char*, int, PassRefPtr<SharedBuffer>, long long encodedDataLength, DataPayloadType);
+
     enum SubresourceLoaderState {
         Uninitialized,
         Initialized,

Modified: trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp (145819 => 145820)


--- trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp	2013-03-14 16:14:57 UTC (rev 145819)
+++ trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp	2013-03-14 16:28:04 UTC (rev 145820)
@@ -80,10 +80,12 @@
         return;
     
     ASSERT(!m_size);
-        
-    append(reinterpret_cast<const char*>(CFDataGetBytePtr(m_cfData.get())), CFDataGetLength(m_cfData.get()));
-        
-    m_cfData = 0;
+    
+    // Hang on to the m_cfData pointer in a local pointer as append() will re-enter maybeTransferPlatformData()
+    // and we need to make sure to early return when it does.
+    RetainPtr<CFDataRef> cfData = m_cfData.leakRef();
+
+    append(reinterpret_cast<const char*>(CFDataGetBytePtr(cfData.get())), CFDataGetLength(cfData.get()));
 }
 
 void SharedBuffer::clearPlatformData()

Modified: trunk/Source/WebCore/platform/network/ResourceHandleClient.h (145819 => 145820)


--- trunk/Source/WebCore/platform/network/ResourceHandleClient.h	2013-03-14 16:14:57 UTC (rev 145819)
+++ trunk/Source/WebCore/platform/network/ResourceHandleClient.h	2013-03-14 16:28:04 UTC (rev 145820)
@@ -26,6 +26,7 @@
 #ifndef ResourceHandleClient_h
 #define ResourceHandleClient_h
 
+#include "SharedBuffer.h"
 #include <wtf/CurrentTime.h>
 #include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
@@ -86,7 +87,13 @@
         virtual void didSendData(ResourceHandle*, unsigned long long /*bytesSent*/, unsigned long long /*totalBytesToBeSent*/) { }
 
         virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&) { }
+        
         virtual void didReceiveData(ResourceHandle*, const char*, int, int /*encodedDataLength*/) { }
+        virtual void didReceiveBuffer(ResourceHandle* handle, PassRefPtr<SharedBuffer> buffer, int encodedDataLength)
+        {
+            didReceiveData(handle, buffer->data(), buffer->size(), encodedDataLength);
+        }
+        
         virtual void didReceiveCachedMetadata(ResourceHandle*, const char*, int) { }
         virtual void didFinishLoading(ResourceHandle*, double /*finishTime*/) { }
         virtual void didFail(ResourceHandle*, const ResourceError&) { }

Modified: trunk/Source/WebCore/platform/network/mac/ResourceHandleMac.mm (145819 => 145820)


--- trunk/Source/WebCore/platform/network/mac/ResourceHandleMac.mm	2013-03-14 16:14:57 UTC (rev 145819)
+++ trunk/Source/WebCore/platform/network/mac/ResourceHandleMac.mm	2013-03-14 16:28:04 UTC (rev 145820)
@@ -756,7 +756,7 @@
     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=19793
     // -1 means we do not provide any data about transfer size to inspector so it would use
     // Content-Length headers or content size to show transfer size.
-    m_handle->client()->didReceiveData(m_handle, (const char*)[data bytes], [data length], -1);
+    m_handle->client()->didReceiveBuffer(m_handle, SharedBuffer::wrapNSData(data), -1);
 }
 
 - (void)connection:(NSURLConnection *)connection willStopBufferingData:(NSData *)data
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to