Title: [149944] trunk/Source/WebKit2
Revision
149944
Author
[email protected]
Date
2013-05-11 16:28:26 -0700 (Sat, 11 May 2013)

Log Message

Don't pass malloced pointers as out-of-line data when sending Mach messages
https://bugs.webkit.org/show_bug.cgi?id=115970
<rdar://problem/13144680>

Reviewed by Sam Weinig.

Give ArgumentEncoder an inline buffer of 512 bytes. If we need more than that, use mmap to allocate data
since that gives us fresh zero-filled memory that we can safely share.

* Platform/CoreIPC/ArgumentEncoder.cpp:
(CoreIPC::ArgumentEncoder::ArgumentEncoder):
Set up the buffer pointers to point to the inline buffer.

(CoreIPC::ArgumentEncoder::~ArgumentEncoder):
Unmap the buffer if necessary.

(CoreIPC::ArgumentEncoder::grow):
Grow the allocation exponentially, rounded up to the nearest page. This is a simplification from the
current strategy, but most messages are either tiny in which case they will fit inside the inline buffer,
or big in which case we'll end up doing less allocations + memory copying.

* Platform/CoreIPC/ArgumentEncoder.h:
(ArgumentEncoder):

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (149943 => 149944)


--- trunk/Source/WebKit2/ChangeLog	2013-05-11 23:26:30 UTC (rev 149943)
+++ trunk/Source/WebKit2/ChangeLog	2013-05-11 23:28:26 UTC (rev 149944)
@@ -1,3 +1,29 @@
+2013-05-11  Anders Carlsson  <[email protected]>
+
+        Don't pass malloced pointers as out-of-line data when sending Mach messages
+        https://bugs.webkit.org/show_bug.cgi?id=115970
+        <rdar://problem/13144680>
+
+        Reviewed by Sam Weinig.
+
+        Give ArgumentEncoder an inline buffer of 512 bytes. If we need more than that, use mmap to allocate data
+        since that gives us fresh zero-filled memory that we can safely share.
+
+        * Platform/CoreIPC/ArgumentEncoder.cpp:
+        (CoreIPC::ArgumentEncoder::ArgumentEncoder):
+        Set up the buffer pointers to point to the inline buffer.
+
+        (CoreIPC::ArgumentEncoder::~ArgumentEncoder):
+        Unmap the buffer if necessary.
+
+        (CoreIPC::ArgumentEncoder::grow):
+        Grow the allocation exponentially, rounded up to the nearest page. This is a simplification from the
+        current strategy, but most messages are either tiny in which case they will fit inside the inline buffer,
+        or big in which case we'll end up doing less allocations + memory copying.
+
+        * Platform/CoreIPC/ArgumentEncoder.h:
+        (ArgumentEncoder):
+
 2013-05-11  Zan Dobersek  <[email protected]>
 
         Unreviewed GTK build fix after r149904.

Modified: trunk/Source/WebKit2/Platform/CoreIPC/ArgumentEncoder.cpp (149943 => 149944)


--- trunk/Source/WebKit2/Platform/CoreIPC/ArgumentEncoder.cpp	2013-05-11 23:26:30 UTC (rev 149943)
+++ trunk/Source/WebKit2/Platform/CoreIPC/ArgumentEncoder.cpp	2013-05-11 23:28:26 UTC (rev 149944)
@@ -38,17 +38,18 @@
 }
 
 ArgumentEncoder::ArgumentEncoder()
-    : m_buffer(0)
-    , m_bufferPointer(0)
+    : m_buffer(m_inlineBuffer)
+    , m_bufferPointer(m_inlineBuffer)
     , m_bufferSize(0)
-    , m_bufferCapacity(0)
+    , m_bufferCapacity(sizeof(m_inlineBuffer))
 {
 }
 
 ArgumentEncoder::~ArgumentEncoder()
 {
-    if (m_buffer)
-        free(m_buffer);
+    if (m_buffer != m_inlineBuffer)
+        munmap(m_buffer, m_bufferCapacity);
+
 #if !USE(UNIX_DOMAIN_SOCKETS)
     // FIXME: We need to dispose of the attachments in cases of failure.
 #else
@@ -67,22 +68,21 @@
     size_t alignedSize = roundUpToAlignment(m_bufferSize, alignment);
     
     if (alignedSize + size > m_bufferCapacity) {
-        size_t newCapacity = std::max(alignedSize + size, std::max(static_cast<size_t>(32), m_bufferCapacity + m_bufferCapacity / 4 + 1));
-        // Use system malloc / realloc instead of fastMalloc due to 
-        // fastMalloc using MADV_FREE_REUSABLE which doesn't work with
-        // mach messages with OOL message and MACH_MSG_VIRTUAL_COPY.
-        // System malloc also calls madvise(MADV_FREE_REUSABLE) but after first
-        // checking via madvise(CAN_REUSE) that it will succeed. Should this
-        // behavior change we'll need to revisit this.
-        if (!m_buffer)
-            m_buffer = static_cast<uint8_t*>(malloc(newCapacity));
-        else
-            m_buffer = static_cast<uint8_t*>(realloc(m_buffer, newCapacity));
+        size_t newCapacity = roundUpToAlignment(m_bufferCapacity * 2, 4096);
+        while (newCapacity < alignedSize + size)
+            newCapacity *= 2;
 
-        if (!m_buffer)
+        uint8_t* newBuffer = static_cast<uint8_t*>(mmap(0, newCapacity, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0));
+        if (!newBuffer)
             CRASH();
 
-        m_bufferCapacity = newCapacity;        
+        memcpy(newBuffer, m_buffer, m_bufferSize);
+
+        if (m_buffer != m_inlineBuffer)
+            munmap(m_buffer, m_bufferCapacity);
+
+        m_buffer = newBuffer;
+        m_bufferCapacity = newCapacity;
     }
 
     m_bufferSize = alignedSize + size;

Modified: trunk/Source/WebKit2/Platform/CoreIPC/ArgumentEncoder.h (149943 => 149944)


--- trunk/Source/WebKit2/Platform/CoreIPC/ArgumentEncoder.h	2013-05-11 23:26:30 UTC (rev 149943)
+++ trunk/Source/WebKit2/Platform/CoreIPC/ArgumentEncoder.h	2013-05-11 23:28:26 UTC (rev 149944)
@@ -84,7 +84,9 @@
     void encode(double);
 
     uint8_t* grow(unsigned alignment, size_t size);
-    
+
+    uint8_t m_inlineBuffer[512];
+
     uint8_t* m_buffer;
     uint8_t* m_bufferPointer;
     
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to