Bug 233363 - Remove unnecessary flattening of SharedBuffer when sending them over IPC
Summary: Remove unnecessary flattening of SharedBuffer when sending them over IPC
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Page Loading (show other bugs)
Version: Other
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Jean-Yves Avenard [:jya]
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2021-11-19 06:16 PST by Jean-Yves Avenard [:jya]
Modified: 2021-11-25 17:37 PST (History)
3 users (show)

See Also:


Attachments
Patch (11.74 KB, patch)
2021-11-19 06:49 PST, Jean-Yves Avenard [:jya]
no flags Details | Formatted Diff | Diff
Patch (11.75 KB, patch)
2021-11-19 14:08 PST, Jean-Yves Avenard [:jya]
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jean-Yves Avenard [:jya] 2021-11-19 06:16:34 PST
In a few places in the code, a pattern to send a SharedBuffer across IPC doing like so:

```
        RefPtr<SharedBuffer> buffer = cachedImage->resourceBuffer();
        if (!buffer)
            return;
        uint64_t bufferSize = buffer->size();
        RefPtr<SharedMemory> sharedMemoryBuffer = SharedMemory::allocate(bufferSize);
        memcpy(sharedMemoryBuffer->data(), buffer->data(), bufferSize);
        SharedMemory::Handle handle;
        sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly);
        send(Messages::WebPageProxy::SaveImageToLibrary(SharedMemory::IPCHandle { WTFMove(handle), bufferSize }));
```

SharedBuffer::data() will silently flatten the Sharedbuffer if made of multiple segments, which includes a new memory allocation and a copy.

When the above could be done like so:
```
        RefPtr<SharedBuffer> buffer = cachedImage->resourceBuffer();
        if (!buffer)
            return;
        auto sharedMemoryBuffer = SharedMemory::copyBuffer(*buffer);
        SharedMemory::Handle handle;
        sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly);
        send(Messages::WebPageProxy::SaveImageToLibrary(SharedMemory::IPCHandle { WTFMove(handle), buffer->size() }));
```

the call SharedMemory::copyBuffer will achieve the same as above, but without the preliminary flattening of the SharedBuffer, eliminating a memory allocation and a copy.
Comment 1 Radar WebKit Bug Importer 2021-11-19 06:38:43 PST
<rdar://problem/85600684>
Comment 2 Jean-Yves Avenard [:jya] 2021-11-19 06:49:24 PST
Created attachment 444814 [details]
Patch
Comment 3 Jean-Yves Avenard [:jya] 2021-11-19 14:08:26 PST
Created attachment 444854 [details]
Patch

Ref<T> doesn't support indirection operator
Comment 4 Sam Weinig 2021-11-20 09:49:05 PST
Comment on attachment 444854 [details]
Patch

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

> Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm:2668
>              auto buffer = SharedBuffer::create(data);
> +            auto sharedMemory = SharedMemory::copyBuffer(buffer.get());
> +            if (!sharedMemory)
> +                continue;

Would be nice to avoid the SharedBuffer allocation here also at some point by adding something like a SharedMemory::copyBuffer() that took a Span.
Comment 5 Jean-Yves Avenard [:jya] 2021-11-20 15:10:01 PST
Comment on attachment 444854 [details]
Patch

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

>> Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm:2668
>> +                continue;
> 
> Would be nice to avoid the SharedBuffer allocation here also at some point by adding something like a SharedMemory::copyBuffer() that took a Span.

data is a NSData, the SharedBuffer here creates a DataSegment that keeps a ref to the NSData; so there's no copy ; it works in practice like a span.

in bug 230329; we added the ability to append to a SharedBuffer a DataSegment::Provider which is a struct providing two methods: size() and data()
Comment 6 EWS 2021-11-20 15:22:02 PST
Committed r286097 (244484@main): <https://commits.webkit.org/244484@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 444854 [details].
Comment 7 Sam Weinig 2021-11-25 17:37:33 PST
(In reply to Jean-Yves Avenard [:jya] from comment #5)
> Comment on attachment 444854 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=444854&action=review
> 
> >> Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm:2668
> >> +                continue;
> > 
> > Would be nice to avoid the SharedBuffer allocation here also at some point by adding something like a SharedMemory::copyBuffer() that took a Span.
> 
> data is a NSData, the SharedBuffer here creates a DataSegment that keeps a
> ref to the NSData; so there's no copy ; it works in practice like a span.
> 
> in bug 230329; we added the ability to append to a SharedBuffer a
> DataSegment::Provider which is a struct providing two methods: size() and
> data()

I wasn't worried about a copy, just trying to avoid an extra allocation of the SharedBuffer itself.