Title: [134987] trunk/Source/WebCore
Revision
134987
Author
psola...@apple.com
Date
2012-11-16 12:46:59 -0800 (Fri, 16 Nov 2012)

Log Message

For single element arrays use the pointer into the CFDataRef instead of copying data
https://bugs.webkit.org/show_bug.cgi?id=102306
<rdar://problem/12267471>

Reviewed by Alexey Proskuryakov.

We generally copy the data received from CFNetwork into our own buffers. But if the
CFArrayRef has exactly one CFDataRef inside it, then we can just hold on to the CFDataRef
and access its memory directly and avoid making a copy.

This also moves the creation of PurgeableBuffer from CachedResource to SharedBuffer.
SharedBuffer::createPurgeableBuffer() will avoid creating PurgeableBuffer when the
SharedBuffer is backed by a NSData/CFDataRef and when we want to optimize and directly use
the memory in the data array.

No new tests because no change in functionality.

* loader/ResourceBuffer.cpp:
(WebCore::ResourceBuffer::createPurgeableBuffer): Added.
* loader/ResourceBuffer.h:
* loader/cache/CachedResource.cpp:
(WebCore::CachedResource::makePurgeable):
* platform/SharedBuffer.cpp:
(WebCore::SharedBuffer::createPurgeableBuffer): Added.
(WebCore::SharedBuffer::data):
* platform/SharedBuffer.h:
* platform/cf/SharedBufferCF.cpp:
(WebCore::SharedBuffer::platformData): Use reinterpret_cast instead of C-style cast.
(WebCore::SharedBuffer::maybeTransferPlatformData): Use reinterpret_cast instead of C-style cast.
(WebCore::SharedBuffer::singleDataArrayBuffer): Added.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (134986 => 134987)


--- trunk/Source/WebCore/ChangeLog	2012-11-16 20:36:03 UTC (rev 134986)
+++ trunk/Source/WebCore/ChangeLog	2012-11-16 20:46:59 UTC (rev 134987)
@@ -1,3 +1,36 @@
+2012-11-16  Pratik Solanki  <psola...@apple.com>
+
+        For single element arrays use the pointer into the CFDataRef instead of copying data
+        https://bugs.webkit.org/show_bug.cgi?id=102306
+        <rdar://problem/12267471>
+
+        Reviewed by Alexey Proskuryakov.
+
+        We generally copy the data received from CFNetwork into our own buffers. But if the
+        CFArrayRef has exactly one CFDataRef inside it, then we can just hold on to the CFDataRef
+        and access its memory directly and avoid making a copy.
+
+        This also moves the creation of PurgeableBuffer from CachedResource to SharedBuffer.
+        SharedBuffer::createPurgeableBuffer() will avoid creating PurgeableBuffer when the
+        SharedBuffer is backed by a NSData/CFDataRef and when we want to optimize and directly use
+        the memory in the data array.
+
+        No new tests because no change in functionality.
+
+        * loader/ResourceBuffer.cpp:
+        (WebCore::ResourceBuffer::createPurgeableBuffer): Added.
+        * loader/ResourceBuffer.h:
+        * loader/cache/CachedResource.cpp:
+        (WebCore::CachedResource::makePurgeable):
+        * platform/SharedBuffer.cpp:
+        (WebCore::SharedBuffer::createPurgeableBuffer): Added.
+        (WebCore::SharedBuffer::data):
+        * platform/SharedBuffer.h:
+        * platform/cf/SharedBufferCF.cpp:
+        (WebCore::SharedBuffer::platformData): Use reinterpret_cast instead of C-style cast.
+        (WebCore::SharedBuffer::maybeTransferPlatformData): Use reinterpret_cast instead of C-style cast.
+        (WebCore::SharedBuffer::singleDataArrayBuffer): Added.
+
 2012-11-16  Antti Koivisto  <an...@apple.com>
 
         REGRESSION(r129644): User StyleSheet not applying

Modified: trunk/Source/WebCore/loader/ResourceBuffer.cpp (134986 => 134987)


--- trunk/Source/WebCore/loader/ResourceBuffer.cpp	2012-11-16 20:36:03 UTC (rev 134986)
+++ trunk/Source/WebCore/loader/ResourceBuffer.cpp	2012-11-16 20:46:59 UTC (rev 134987)
@@ -100,6 +100,12 @@
     return m_sharedBuffer->hasPurgeableBuffer();
 }
 
+void ResourceBuffer::createPurgeableBuffer() const
+{
+    ASSERT(m_sharedBuffer);
+    sharedBuffer()->createPurgeableBuffer();
+}
+
 PassOwnPtr<PurgeableBuffer> ResourceBuffer::releasePurgeableBuffer()
 {
     return m_sharedBuffer->releasePurgeableBuffer();

Modified: trunk/Source/WebCore/loader/ResourceBuffer.h (134986 => 134987)


--- trunk/Source/WebCore/loader/ResourceBuffer.h	2012-11-16 20:36:03 UTC (rev 134986)
+++ trunk/Source/WebCore/loader/ResourceBuffer.h	2012-11-16 20:46:59 UTC (rev 134987)
@@ -63,6 +63,7 @@
     PassRefPtr<ResourceBuffer> copy() const;
 
     bool hasPurgeableBuffer() const;
+    void createPurgeableBuffer() const;
     
     // Ensure this buffer has no other clients before calling this.
     PassOwnPtr<PurgeableBuffer> releasePurgeableBuffer();

Modified: trunk/Source/WebCore/loader/cache/CachedResource.cpp (134986 => 134987)


--- trunk/Source/WebCore/loader/cache/CachedResource.cpp	2012-11-16 20:36:03 UTC (rev 134986)
+++ trunk/Source/WebCore/loader/cache/CachedResource.cpp	2012-11-16 20:46:59 UTC (rev 134987)
@@ -801,16 +801,13 @@
         // Should not make buffer purgeable if it has refs other than this since we don't want two copies.
         if (!m_data->hasOneRef())
             return false;
-        
-        if (m_data->hasPurgeableBuffer()) {
-            m_purgeableData = m_data->releasePurgeableBuffer();
-        } else {
-            m_purgeableData = PurgeableBuffer::create(m_data->data(), m_data->size());
-            if (!m_purgeableData)
-                return false;
-            m_purgeableData->setPurgePriority(purgePriority());
-        }
-        
+
+        m_data->createPurgeableBuffer();
+        if (!m_data->hasPurgeableBuffer())
+            return false;
+
+        m_purgeableData = m_data->releasePurgeableBuffer();
+        m_purgeableData->setPurgePriority(purgePriority());
         m_purgeableData->makePurgeable(true);
         m_data.clear();
         return true;

Modified: trunk/Source/WebCore/platform/SharedBuffer.cpp (134986 => 134987)


--- trunk/Source/WebCore/platform/SharedBuffer.cpp	2012-11-16 20:36:03 UTC (rev 134986)
+++ trunk/Source/WebCore/platform/SharedBuffer.cpp	2012-11-16 20:46:59 UTC (rev 134987)
@@ -124,10 +124,32 @@
     return m_size;
 }
 
+void SharedBuffer::createPurgeableBuffer() const
+{
+    if (m_purgeableBuffer)
+        return;
+
+    if (hasPlatformData())
+        return;
+
+#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
+    if (singleDataArrayBuffer())
+        return;
+#endif
+
+    m_purgeableBuffer = PurgeableBuffer::create(buffer().data(), m_size);
+}
+
 const char* SharedBuffer::data() const
 {
     if (hasPlatformData())
         return platformData();
+
+#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
+    const char* directBuffer = singleDataArrayBuffer();
+    if (directBuffer)
+        return directBuffer;
+#endif
     
     if (m_purgeableBuffer)
         return m_purgeableBuffer->data();

Modified: trunk/Source/WebCore/platform/SharedBuffer.h (134986 => 134987)


--- trunk/Source/WebCore/platform/SharedBuffer.h	2012-11-16 20:36:03 UTC (rev 134986)
+++ trunk/Source/WebCore/platform/SharedBuffer.h	2012-11-16 20:46:59 UTC (rev 134987)
@@ -116,6 +116,8 @@
 
     void reportMemoryUsage(MemoryObjectInfo*) const;
 
+    void createPurgeableBuffer() const;
+
 private:
     SharedBuffer();
     explicit SharedBuffer(size_t);
@@ -136,11 +138,12 @@
     unsigned m_size;
     mutable Vector<char> m_buffer;
     mutable Vector<char*> m_segments;
-    OwnPtr<PurgeableBuffer> m_purgeableBuffer;
+    mutable OwnPtr<PurgeableBuffer> m_purgeableBuffer;
 #if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
     mutable Vector<RetainPtr<CFDataRef> > m_dataArray;
     void copyDataArrayAndClear(char *destination, unsigned bytesToCopy) const;
     unsigned copySomeDataFromDataArray(const char*& someData, unsigned position) const;
+    const char *singleDataArrayBuffer() const;
 #endif
 #if USE(CF)
     explicit SharedBuffer(CFDataRef);

Modified: trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp (134986 => 134987)


--- trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp	2012-11-16 20:36:03 UTC (rev 134986)
+++ trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp	2012-11-16 20:46:59 UTC (rev 134987)
@@ -66,7 +66,7 @@
 
 const char* SharedBuffer::platformData() const
 {
-    return (const char*)CFDataGetBytePtr(m_cfData.get());
+    return reinterpret_cast<const char*>(CFDataGetBytePtr(m_cfData.get()));
 }
 
 unsigned SharedBuffer::platformDataSize() const
@@ -81,7 +81,7 @@
     
     ASSERT(!m_size);
         
-    append((const char*)CFDataGetBytePtr(m_cfData.get()), CFDataGetLength(m_cfData.get()));
+    append(reinterpret_cast<const char*>(CFDataGetBytePtr(m_cfData.get())), CFDataGetLength(m_cfData.get()));
         
     m_cfData = 0;
 }
@@ -132,6 +132,19 @@
     }
     return 0;
 }
+
+const char *SharedBuffer::singleDataArrayBuffer() const
+{
+    // If we had previously copied data into m_buffer in copyDataArrayAndClear() or some other
+    // function, then we can't return a pointer to the CFDataRef buffer.
+    if (m_buffer.size())
+        return 0;
+
+    if (m_dataArray.size() == 1)
+        return reinterpret_cast<const char*>(CFDataGetBytePtr(m_dataArray.at(0).get()));
+
+    return 0;
+}
 #endif
 
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to