Skip to content
Permalink
Browse files
Reduce refcount of SharedMemory when sending them over IPC.
https://bugs.webkit.org/show_bug.cgi?id=240855
rdar://problem/93806688

Reviewed by Jer Noble.

In the future, we want to be able to donate memory with exclusive access to another process, this require the VM to have a refcount of 1.
No change in obeservable behaviour. Covered by existing tests.

* Source/WebKit/Shared/WebCoreArgumentCoders.cpp:
(IPC::encodeSharedBuffer):
* Source/WebKit/UIProcess/Cocoa/WebPasteboardProxyCocoa.mm:
(WebKit::WebPasteboardProxy::getPasteboardBufferForType):
(WebKit::WebPasteboardProxy::readBufferFromPasteboard):
* Source/WebKit/WebProcess/GPU/media/RemoteMediaResourceProxy.cpp:
(WebKit::RemoteMediaResourceProxy::dataReceived):
* Source/WebKit/WebProcess/GPU/media/SourceBufferPrivateRemote.cpp:
(WebKit::SourceBufferPrivateRemote::append):
* Source/WebKit/WebProcess/Plugins/PDF/PDFPlugin.mm:
(WebKit::PDFPlugin::writeItemsToPasteboard):
* Source/WebKit/WebProcess/WebCoreSupport/mac/WebDragClientMac.mm:
(WebKit::WebDragClient::declareAndWriteDragImage):
* Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::performActionOnElement):
(WebKit::WebPage::didFinishLoadForQuickLookDocumentInMainFrame):
* Source/WebKit/WebProcess/WebPage/mac/WebPageMac.mm:
(WebKit::WebPage::getDataSelectionForPasteboard):

Canonical link: https://commits.webkit.org/250943@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@294784 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
jyavenard committed May 25, 2022
1 parent edec03c commit 6a4bb0e83ea07ae1e8d5967dc153590e561e98a2
Showing 8 changed files with 65 additions and 47 deletions.
@@ -188,8 +188,10 @@ static void encodeSharedBuffer(Encoder& encoder, const FragmentedSharedBuffer* b
encoder.encodeFixedLengthData(element.segment->data(), element.segment->size(), 1);
#else
SharedMemory::Handle handle;
auto sharedMemoryBuffer = SharedMemory::copyBuffer(*buffer);
sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly);
{
auto sharedMemoryBuffer = SharedMemory::copyBuffer(*buffer);
sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly);
}
encoder << SharedMemory::IPCHandle { WTFMove(handle), bufferSize };
#endif
}
@@ -232,12 +232,14 @@
uint64_t size = buffer->size();
if (!size)
return completionHandler({ });
auto sharedMemoryBuffer = SharedMemory::copyBuffer(*buffer);
if (!sharedMemoryBuffer)
return completionHandler({ });
SharedMemory::Handle handle;
if (!sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly))
return completionHandler({ });
{
auto sharedMemoryBuffer = SharedMemory::copyBuffer(*buffer);
if (!sharedMemoryBuffer)
return completionHandler({ });
if (!sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly))
return completionHandler({ });
}
completionHandler(SharedMemory::IPCHandle { WTFMove(handle), size });
});
}
@@ -554,12 +556,14 @@
uint64_t size = buffer->size();
if (!size)
return completionHandler({ });
auto sharedMemoryBuffer = SharedMemory::copyBuffer(*buffer);
if (!sharedMemoryBuffer)
return completionHandler({ });
SharedMemory::Handle handle;
if (!sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly))
return completionHandler({ });
{
auto sharedMemoryBuffer = SharedMemory::copyBuffer(*buffer);
if (!sharedMemoryBuffer)
return completionHandler({ });
if (!sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly))
return completionHandler({ });
}
completionHandler(SharedMemory::IPCHandle { WTFMove(handle), size });
});
}
@@ -74,12 +74,13 @@ void RemoteMediaResourceProxy::dataSent(WebCore::PlatformMediaResource&, unsigne

void RemoteMediaResourceProxy::dataReceived(WebCore::PlatformMediaResource&, const WebCore::SharedBuffer& buffer)
{
auto sharedMemory = SharedMemory::copyBuffer(buffer);
if (!sharedMemory)
return;

SharedMemory::Handle handle;
sharedMemory->createHandle(handle, SharedMemory::Protection::ReadOnly);
{
auto sharedMemory = SharedMemory::copyBuffer(buffer);
if (!sharedMemory)
return;
sharedMemory->createHandle(handle, SharedMemory::Protection::ReadOnly);
}
// Take ownership of shared memory and mark it as media-related memory.
handle.takeOwnershipOfMemory(MemoryLedger::Media);
m_connection->send(Messages::RemoteMediaResourceManager::DataReceived(m_id, SharedMemory::IPCHandle { WTFMove(handle), buffer.size() }), 0);
@@ -83,14 +83,17 @@ void SourceBufferPrivateRemote::append(Ref<SharedBuffer>&& data)
if (!m_gpuProcessConnection)
return;

auto sharedData = SharedMemory::copyBuffer(data);
SharedMemory::Handle handle;
sharedData->createHandle(handle, SharedMemory::Protection::ReadOnly);

{
auto sharedData = SharedMemory::copyBuffer(data);
if (!sharedData)
return;
sharedData->createHandle(handle, SharedMemory::Protection::ReadOnly);
}
// Take ownership of shared memory and mark it as media-related memory.
handle.takeOwnershipOfMemory(MemoryLedger::Media);

m_gpuProcessConnection->connection().send(Messages::RemoteSourceBufferProxy::Append(SharedMemory::IPCHandle { WTFMove(handle), sharedData->size() }), m_remoteSourceBufferIdentifier);
m_gpuProcessConnection->connection().send(Messages::RemoteSourceBufferProxy::Append(SharedMemory::IPCHandle { WTFMove(handle), data->size() }), m_remoteSourceBufferIdentifier);
}

void SourceBufferPrivateRemote::abort()
@@ -2567,12 +2567,14 @@ static bool getEventTypeFromWebEvent(const WebEvent& event, NSEventType& eventTy
auto plainTextString = adoptNS([[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
webProcess.parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::SetPasteboardStringForType(pasteboardName, type, plainTextString.get(), pageIdentifier), Messages::WebPasteboardProxy::SetPasteboardStringForType::Reply(newChangeCount), 0);
} else {
auto buffer = SharedBuffer::create(data);
auto sharedMemory = SharedMemory::copyBuffer(buffer.get());
if (!sharedMemory)
continue;
SharedMemory::Handle handle;
sharedMemory->createHandle(handle, SharedMemory::Protection::ReadOnly);
auto buffer = SharedBuffer::create(data);
{
auto sharedMemory = SharedMemory::copyBuffer(buffer.get());
if (!sharedMemory)
continue;
sharedMemory->createHandle(handle, SharedMemory::Protection::ReadOnly);
}
webProcess.parentProcessConnection()->sendSync(Messages::WebPasteboardProxy::SetPasteboardBufferForType(pasteboardName, type, SharedMemory::IPCHandle { WTFMove(handle), buffer->size() }, pageIdentifier), Messages::WebPasteboardProxy::SetPasteboardBufferForType::Reply(newChangeCount), 0);
}
}
@@ -153,12 +153,13 @@
auto imageBuffer = image->image()->data();
size_t imageSize = imageBuffer->size();

auto sharedMemoryBuffer = SharedMemory::copyBuffer(*imageBuffer);
if (!sharedMemoryBuffer)
return;
SharedMemory::Handle imageHandle;
sharedMemoryBuffer->createHandle(imageHandle, SharedMemory::Protection::ReadOnly);

{
auto sharedMemoryBuffer = SharedMemory::copyBuffer(*imageBuffer);
if (!sharedMemoryBuffer)
return;
sharedMemoryBuffer->createHandle(imageHandle, SharedMemory::Protection::ReadOnly);
}
RetainPtr<CFDataRef> data = archive ? archive->rawDataRepresentation() : 0;
SharedMemory::Handle archiveHandle;
size_t archiveSize = 0;
@@ -3344,11 +3344,13 @@ static void populateCaretContext(const HitTestResult& hitTestResult, const Inter
RefPtr<FragmentedSharedBuffer> buffer = cachedImage->resourceBuffer();
if (!buffer)
return;
auto sharedMemoryBuffer = SharedMemory::copyBuffer(*buffer);
if (!sharedMemoryBuffer)
return;
SharedMemory::Handle handle;
sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly);
{
auto sharedMemoryBuffer = SharedMemory::copyBuffer(*buffer);
if (!sharedMemoryBuffer)
return;
sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly);
}
send(Messages::WebPageProxy::SaveImageToLibrary(SharedMemory::IPCHandle { WTFMove(handle), buffer->size() }, authorizationToken));
}
}
@@ -4822,19 +4824,20 @@ static VisiblePositionRange constrainRangeToSelection(const VisiblePositionRange
{
ASSERT(!buffer.isEmpty());

// FIXME: In some cases, buffer conains a single segment that wraps an existing ShareableResource.
// FIXME: In some cases, buffer contains a single segment that wraps an existing ShareableResource.
// If we could create a handle from that existing resource then we could avoid this extra
// allocation and copy.

auto sharedMemory = SharedMemory::copyBuffer(buffer);
if (!sharedMemory)
return;

ShareableResource::Handle handle;
auto shareableResource = ShareableResource::create(sharedMemory.releaseNonNull(), 0, buffer.size());
if (!shareableResource || !shareableResource->createHandle(handle))
return;
{
auto sharedMemory = SharedMemory::copyBuffer(buffer);
if (!sharedMemory)
return;

auto shareableResource = ShareableResource::create(sharedMemory.releaseNonNull(), 0, buffer.size());
if (!shareableResource || !shareableResource->createHandle(handle))
return;
}
send(Messages::WebPageProxy::DidFinishLoadForQuickLookDocumentInMainFrame(handle));
}

@@ -509,11 +509,13 @@ static String commandNameForSelectorName(const String& selectorName)
auto buffer = frame.editor().dataSelectionForPasteboard(pasteboardType);
if (!buffer)
return completionHandler({ });
auto sharedMemoryBuffer = SharedMemory::copyBuffer(*buffer);
if (!sharedMemoryBuffer)
return completionHandler({ });
SharedMemory::Handle handle;
sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly);
{
auto sharedMemoryBuffer = SharedMemory::copyBuffer(*buffer);
if (!sharedMemoryBuffer)
return completionHandler({ });
sharedMemoryBuffer->createHandle(handle, SharedMemory::Protection::ReadOnly);
}
completionHandler(SharedMemory::IPCHandle { WTFMove(handle), buffer->size() });
}

0 comments on commit 6a4bb0e

Please sign in to comment.