Copy SharedBuffer data into IPC message directly
authorpsolanki@apple.com <psolanki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jun 2014 18:33:20 +0000 (18:33 +0000)
committerpsolanki@apple.com <psolanki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jun 2014 18:33:20 +0000 (18:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=133920

Reviewed by Anders Carlsson.

When data array callbacks are enabled, we currently merge all the CFDataRefs in SharedBuffer
into one contiguous memory buffer when creating IPC::DataReference. This patch creates a
subclass of DataReference that uses SharedBuffer::getSomeData() to copy the data directly
into the IPC message.

* NetworkProcess/AsynchronousNetworkLoaderClient.cpp:
(WebKit::AsynchronousNetworkLoaderClient::didReceiveBuffer):
* Platform/IPC/ArgumentEncoder.cpp:
(IPC::ArgumentEncoder::reserve): Added.
(IPC::ArgumentEncoder::grow):
* Platform/IPC/ArgumentEncoder.h:
* Platform/IPC/DataReference.cpp:
(IPC::SharedBufferDataReference::encode):
* Platform/IPC/DataReference.h:
(IPC::DataReference::~DataReference):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@170154 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit2/ChangeLog
Source/WebKit2/NetworkProcess/AsynchronousNetworkLoaderClient.cpp
Source/WebKit2/Platform/IPC/ArgumentEncoder.cpp
Source/WebKit2/Platform/IPC/ArgumentEncoder.h
Source/WebKit2/Platform/IPC/DataReference.cpp
Source/WebKit2/Platform/IPC/DataReference.h

index d2435f0..6f68501 100644 (file)
@@ -1,3 +1,26 @@
+2014-06-19  Pratik Solanki  <psolanki@apple.com>
+
+        Copy SharedBuffer data into IPC message directly
+        https://bugs.webkit.org/show_bug.cgi?id=133920
+
+        Reviewed by Anders Carlsson.
+
+        When data array callbacks are enabled, we currently merge all the CFDataRefs in SharedBuffer
+        into one contiguous memory buffer when creating IPC::DataReference. This patch creates a
+        subclass of DataReference that uses SharedBuffer::getSomeData() to copy the data directly
+        into the IPC message.
+
+        * NetworkProcess/AsynchronousNetworkLoaderClient.cpp:
+        (WebKit::AsynchronousNetworkLoaderClient::didReceiveBuffer):
+        * Platform/IPC/ArgumentEncoder.cpp:
+        (IPC::ArgumentEncoder::reserve): Added.
+        (IPC::ArgumentEncoder::grow):
+        * Platform/IPC/ArgumentEncoder.h:
+        * Platform/IPC/DataReference.cpp:
+        (IPC::SharedBufferDataReference::encode):
+        * Platform/IPC/DataReference.h:
+        (IPC::DataReference::~DataReference):
+
 2014-06-18  Zan Dobersek  <zdobersek@igalia.com>
 
         Unreviewed. Fixing the GTK+ build after r170114.
 2014-06-18  Zan Dobersek  <zdobersek@igalia.com>
 
         Unreviewed. Fixing the GTK+ build after r170114.
index 7bb141e..f9bde5e 100644 (file)
@@ -75,7 +75,7 @@ void AsynchronousNetworkLoaderClient::didReceiveBuffer(NetworkResourceLoader* lo
     }
 #endif // __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
 
     }
 #endif // __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
 
-    IPC::DataReference dataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
+    IPC::SharedBufferDataReference dataReference(buffer);
     loader->sendAbortingOnFailure(Messages::WebResourceLoader::DidReceiveData(dataReference, encodedDataLength));
 }
 
     loader->sendAbortingOnFailure(Messages::WebResourceLoader::DidReceiveData(dataReference, encodedDataLength));
 }
 
index ee85630..c71e1a1 100644 (file)
@@ -81,27 +81,32 @@ static inline size_t roundUpToAlignment(size_t value, unsigned alignment)
     return ((value + alignment - 1) / alignment) * alignment;
 }
 
     return ((value + alignment - 1) / alignment) * alignment;
 }
 
-uint8_t* ArgumentEncoder::grow(unsigned alignment, size_t size)
+void ArgumentEncoder::reserve(size_t size)
 {
 {
-    size_t alignedSize = roundUpToAlignment(m_bufferSize, alignment);
-    
-    if (alignedSize + size > m_bufferCapacity) {
-        size_t newCapacity = roundUpToAlignment(m_bufferCapacity * 2, 4096);
-        while (newCapacity < alignedSize + size)
-            newCapacity *= 2;
+    if (size <= m_bufferCapacity)
+        return;
 
 
-        uint8_t* newBuffer = static_cast<uint8_t*>(allocBuffer(newCapacity));
-        if (!newBuffer)
-            CRASH();
+    size_t newCapacity = roundUpToAlignment(m_bufferCapacity * 2, 4096);
+    while (newCapacity < size)
+        newCapacity *= 2;
 
 
-        memcpy(newBuffer, m_buffer, m_bufferSize);
+    uint8_t* newBuffer = static_cast<uint8_t*>(allocBuffer(newCapacity));
+    if (!newBuffer)
+        CRASH();
 
 
-        if (m_buffer != m_inlineBuffer)
-            freeBuffer(m_buffer, m_bufferCapacity);
+    memcpy(newBuffer, m_buffer, m_bufferSize);
+
+    if (m_buffer != m_inlineBuffer)
+        freeBuffer(m_buffer, m_bufferCapacity);
 
 
-        m_buffer = newBuffer;
-        m_bufferCapacity = newCapacity;
-    }
+    m_buffer = newBuffer;
+    m_bufferCapacity = newCapacity;
+}
+
+uint8_t* ArgumentEncoder::grow(unsigned alignment, size_t size)
+{
+    size_t alignedSize = roundUpToAlignment(m_bufferSize, alignment);
+    reserve(alignedSize + size);
 
     m_bufferSize = alignedSize + size;
     m_bufferPointer = m_buffer + alignedSize + size;
 
     m_bufferSize = alignedSize + size;
     m_bufferPointer = m_buffer + alignedSize + size;
index f3fb4fa..75d0bfb 100644 (file)
@@ -67,6 +67,7 @@ public:
 
     void addAttachment(const Attachment&);
     Vector<Attachment> releaseAttachments();
 
     void addAttachment(const Attachment&);
     Vector<Attachment> releaseAttachments();
+    void reserve(size_t);
 
 private:
     void encode(bool);
 
 private:
     void encode(bool);
index 0047022..ca61fa6 100644 (file)
@@ -41,4 +41,19 @@ bool DataReference::decode(ArgumentDecoder& decoder, DataReference& dataReferenc
     return decoder.decodeVariableLengthByteArray(dataReference);
 }
 
     return decoder.decodeVariableLengthByteArray(dataReference);
 }
 
+void SharedBufferDataReference::encode(ArgumentEncoder& encoder) const
+{
+    uint64_t bufferSize = static_cast<uint64_t>(m_buffer->size());
+    encoder.reserve(bufferSize + sizeof(uint64_t));
+    encoder << bufferSize;
+
+    const char* partialData;
+    unsigned position = 0;
+    while (position < bufferSize) {
+        unsigned bytesToWrite = m_buffer->getSomeData(partialData, position);
+        encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(partialData), bytesToWrite, 1);
+        position += bytesToWrite;
+    }
+}
+
 } // namespace IPC
 } // namespace IPC
index 66c3761..4f8f48d 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef DataReference_h
 #define DataReference_h
 
 #ifndef DataReference_h
 #define DataReference_h
 
+#include <WebCore/SharedBuffer.h>
 #include <wtf/Vector.h>
 
 namespace IPC {
 #include <wtf/Vector.h>
 
 namespace IPC {
@@ -72,14 +73,34 @@ public:
         return result;
     }
 
         return result;
     }
 
-    void encode(ArgumentEncoder&) const;
+    virtual void encode(ArgumentEncoder&) const;
     static bool decode(ArgumentDecoder&, DataReference&);
 
     static bool decode(ArgumentDecoder&, DataReference&);
 
+    virtual ~DataReference() { }
+
 private:
     const uint8_t* m_data;
     size_t m_size;
 };
 
 private:
     const uint8_t* m_data;
     size_t m_size;
 };
 
+class SharedBufferDataReference: public DataReference {
+public:
+    SharedBufferDataReference(WebCore::SharedBuffer* buffer)
+    {
+        m_buffer = buffer;
+    }
+
+    size_t size() const { return m_buffer->size(); }
+    const uint8_t* data() const = delete;
+    Vector<uint8_t> vector() const = delete;
+
+    void encode(ArgumentEncoder&) const override;
+    virtual ~SharedBufferDataReference() { m_buffer = 0; }
+
+private:
+    RefPtr<WebCore::SharedBuffer> m_buffer;
+};
+
 } // namespace IPC
 
 #endif // DataReference_h
 } // namespace IPC
 
 #endif // DataReference_h