Bug 122516 - Avoid resizing the internal buffer of SharedBuffer when creating a PurgeableBuffer
Summary: Avoid resizing the internal buffer of SharedBuffer when creating a PurgeableB...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Platform (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Daniel Bates
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-10-08 12:38 PDT by Daniel Bates
Modified: 2013-10-10 11:19 PDT (History)
7 users (show)

See Also:


Attachments
Patch (8.17 KB, patch)
2013-10-08 12:48 PDT, Daniel Bates
no flags Details | Formatted Diff | Diff
Patch (8.32 KB, patch)
2013-10-08 15:21 PDT, Daniel Bates
no flags Details | Formatted Diff | Diff
Patch (8.95 KB, patch)
2013-10-08 15:44 PDT, Daniel Bates
no flags Details | Formatted Diff | Diff
Patch (8.98 KB, patch)
2013-10-08 15:45 PDT, Daniel Bates
no flags Details | Formatted Diff | Diff
Patch (8.87 KB, patch)
2013-10-08 16:01 PDT, Daniel Bates
darin: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Daniel Bates 2013-10-08 12:38:43 PDT
Currently we may flatten the SharedBuffer segments into the internal buffer of the SharedBuffer before creating a PurgeableBuffer. As a result we may need to resize the internal buffer of the SharedBuffer to fit the contents of its segments. We can avoid this resize operation by allocating a PurgeableBuffer and copying the SharedBuffer's internal buffer and segments directly into it.
Comment 1 Daniel Bates 2013-10-08 12:48:24 PDT
Created attachment 213708 [details]
Patch
Comment 2 EFL EWS Bot 2013-10-08 12:53:16 PDT
Comment on attachment 213708 [details]
Patch

Attachment 213708 [details] did not pass efl-wk2-ews (efl-wk2):
Output: http://webkit-queues.appspot.com/results/3711268
Comment 3 EFL EWS Bot 2013-10-08 12:55:30 PDT
Comment on attachment 213708 [details]
Patch

Attachment 213708 [details] did not pass efl-ews (efl):
Output: http://webkit-queues.appspot.com/results/3758028
Comment 4 Darin Adler 2013-10-08 12:56:14 PDT
Comment on attachment 213708 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=213708&action=review

I like the direction this patch is going, but there are some details I think you should fix.

> Source/WebCore/platform/PurgeableBuffer.h:38
> +        static PassOwnPtr<PurgeableBuffer> create(size_t);

I think we should follow the pattern for String::createUninitialized here. Use an out argument for the pointer and use the word “uninitialized” in the name of the function. I also suggest including the makePurgeable(false) in that function instead of doing it at the call site.

> Source/WebCore/platform/PurgeableBuffer.h:44
> +        char* data();

I think it would be better to pass the non-const char* out of the create function rather than always exposing a non-const data pointer after the fact on all purgeable buffers. So please change this back.

> Source/WebCore/platform/SharedBuffer.cpp:383
> +void SharedBuffer::copySegmentsOrDataArrayAndClear(char* destination, unsigned bytesToCopy) const

Is there any caller of copyDataArrayAndClear that does not want this behavior? Why do we need a separate function for this?
Comment 5 Daniel Bates 2013-10-08 14:55:00 PDT
(In reply to comment #4)
> [...]
> > Source/WebCore/platform/PurgeableBuffer.h:38
> > +        static PassOwnPtr<PurgeableBuffer> create(size_t);
> 
> I think we should follow the pattern for String::createUninitialized here. Use an out argument for the pointer and use the word “uninitialized” in the name of the function.

I like this idiom. Will modify patch.

> I also suggest including the makePurgeable(false) in that function instead of doing it at the call site.

By adopting the createUninitialized idiom, it seems sufficient to omit this check as we create the PurgeableBuffer in a non-volatile state by default. For some reason, I thought that adding this check at the call site would make the usage of PurgeableBuffer::create(size_t) and the code that writes directly into its buffer less error prone or at least consistent consistent with the document usage for PurgeableBuffer::data(). The new name PurgeableBuffer::createUninitialized(...) seems to obviate the need for such a check since the name better conveys to the caller the state of the PurgeableBuffer. That is, it is uninitialized and hence there is an assumption that it's non-volatile. Do you see a benefit in explicitly checking/asserting makePurgeable(false) is true in PurgeableBuffer::createUninitialized()?

> 
> > Source/WebCore/platform/PurgeableBuffer.h:44
> > +        char* data();
> 
> I think it would be better to pass the non-const char* out of the create function rather than always exposing a non-const data pointer after the fact on all purgeable buffers. So please change this back.
> 

Will revert this change.

> > Source/WebCore/platform/SharedBuffer.cpp:383
> > +void SharedBuffer::copySegmentsOrDataArrayAndClear(char* destination, unsigned bytesToCopy) const
> 
> Is there any caller of copyDataArrayAndClear that does not want this behavior? Why do we need a separate function for this?

Will remove function copySegmentsOrDataArrayAndClear. Instead, will move the !USE(NETWORK_CFDATA_ARRAY_CALLBACK)-guarded code in copySegmentsOrDataArrayAndClear() into a !USE(NETWORK_CFDATA_ARRAY_CALLBACK)-guarded version of copyDataArrayAndClear() such that SharedBuffer.h will declare a platform-independent function called copyDataArrayAndClear, SharedBuffer.cpp will provide the platform-independent implementation of this function and SharedBufferCF.cp will provide a CF-specific implementation of this function.
Comment 6 Daniel Bates 2013-10-08 15:21:27 PDT
Created attachment 213725 [details]
Patch
Comment 7 EFL EWS Bot 2013-10-08 15:34:29 PDT
Comment on attachment 213725 [details]
Patch

Attachment 213725 [details] did not pass efl-ews (efl):
Output: http://webkit-queues.appspot.com/results/3709348
Comment 8 EFL EWS Bot 2013-10-08 15:41:02 PDT
Comment on attachment 213725 [details]
Patch

Attachment 213725 [details] did not pass efl-wk2-ews (efl-wk2):
Output: http://webkit-queues.appspot.com/results/3714305
Comment 9 Daniel Bates 2013-10-08 15:44:29 PDT
Created attachment 213727 [details]
Patch
Comment 10 Daniel Bates 2013-10-08 15:45:06 PDT
Created attachment 213728 [details]
Patch
Comment 11 EFL EWS Bot 2013-10-08 15:49:48 PDT
Comment on attachment 213728 [details]
Patch

Attachment 213728 [details] did not pass efl-ews (efl):
Output: http://webkit-queues.appspot.com/results/3758068
Comment 12 EFL EWS Bot 2013-10-08 15:51:43 PDT
Comment on attachment 213728 [details]
Patch

Attachment 213728 [details] did not pass efl-wk2-ews (efl-wk2):
Output: http://webkit-queues.appspot.com/results/3760083
Comment 13 kov's GTK+ EWS bot 2013-10-08 15:58:27 PDT
Comment on attachment 213728 [details]
Patch

Attachment 213728 [details] did not pass gtk-ews (gtk):
Output: http://webkit-queues.appspot.com/results/3752161
Comment 14 Daniel Bates 2013-10-08 16:01:48 PDT
Created attachment 213729 [details]
Patch
Comment 15 Darin Adler 2013-10-08 22:17:38 PDT
Comment on attachment 213729 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=213729&action=review

> Source/WebCore/platform/SharedBuffer.cpp:233
> +    char* destination = nullptr;

I don’t think this needs to be initialized.

> Source/WebCore/platform/mac/PurgeableBufferMac.cpp:86
> +    char* buffer = allocatePurgeableBuffer(size);
> +    if (!buffer)
> +        return nullptr;
> +    memcpy(buffer, data, size);
> +    return adoptPtr(new PurgeableBuffer(buffer, size));

Seems like this could just call createUninitialized and then do the memcpy. No need for the allocatePurgeableBuffer function at all.
Comment 16 Daniel Bates 2013-10-10 11:18:25 PDT
(In reply to comment #15)
> (From update of attachment 213729 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=213729&action=review
> 
> > Source/WebCore/platform/SharedBuffer.cpp:233
> > +    char* destination = nullptr;
> 
> I don’t think this needs to be initialized.

Will fix.

> 
> > Source/WebCore/platform/mac/PurgeableBufferMac.cpp:86
> > +    char* buffer = allocatePurgeableBuffer(size);
> > +    if (!buffer)
> > +        return nullptr;
> > +    memcpy(buffer, data, size);
> > +    return adoptPtr(new PurgeableBuffer(buffer, size));
> 
> Seems like this could just call createUninitialized and then do the memcpy. No need for the allocatePurgeableBuffer function at all.

Will remove function allocatePurgeableBuffer() and implement PurgeableBuffer::create() in terms of PurgeableBuffer::createUninitialized().
Comment 17 Daniel Bates 2013-10-10 11:19:11 PDT
Committed r157235: <http://trac.webkit.org/changeset/157235>