Diff
Modified: trunk/Source/WebCore/ChangeLog (275374 => 275375)
--- trunk/Source/WebCore/ChangeLog 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebCore/ChangeLog 2021-04-01 20:05:48 UTC (rev 275375)
@@ -1,3 +1,60 @@
+2021-04-01 Chris Dumez <[email protected]>
+
+ Have the ServiceWorker process hold on to a file mapped version of the service worker scripts to save dirty memory
+ https://bugs.webkit.org/show_bug.cgi?id=224015
+ <rdar://75637679>
+
+ Reviewed by Geoffrey Garen.
+
+ Since r275267, the Network process holds on the file mapped (mmap'd) versions of the service worker
+ scripts instead of heap allocated versions, in order to decrease its dirty memory use. However, the
+ ServiceWorker process (which is often a regular WebProcess) was still using heap allocated service
+ worker scripts. This patch is a follow-up to make sure the NetworkProcess sends its file mapped
+ scripts to the ServiceWorker processes as ShareableResource handles in order to decrease the dirty
+ memory usage of the ServiceWorker processes as well.
+
+ No new tests, no Web-facing behavior change, just a decrease in dirty memory use in the ServiceWorker
+ processes (which may be WebProcesses). I have done local testing with a very large service worker
+ that uses a ~100MB main script, which imports another ~100MB sub-script. With my change, dirty
+ memory usage goes from ~440MB to ~230MB in both the cold and warm cases ("Cold" meaning that the
+ service worker was just registed and downloaded from the network and "Warm" meaning that the
+ service worker had been previously registed and was loaded straight from the SWScriptStorage).
+
+ * platform/SharedBuffer.cpp:
+ (WebCore::SharedBuffer::hasOneSegment const):
+ Add a utility function to SharedBuffer to check if it contains a single data segment.
+
+ (WebCore::SharedBuffer::DataSegment::containsMappedFileData const):
+ Add a utility function to check if a SharedBuffer DataSegment contains a MappedFileData object.
+
+ * platform/SharedBuffer.h:
+
+ * workers/service/ServiceWorkerContextData.h:
+ (WebCore::ServiceWorkerContextData::ImportedScript::isolatedCopy const):
+ Move IPC encoders / decoders for ServiceWorkerContextData and ServiceWorkerContextData::ImportedScript
+ to the WebKit layer, in WebCoreArgumentCoders. This allows us to encode / decode the scripts as
+ WebKit::ShareableHandle whenever possible. This way, when the NetworkProcess sends a
+ ServiceWorkerContextData to the ServiceWorker process to launch a service worker, both the
+ ServiceWorker process and the Network process share the same mmap'd versions of the scripts and we
+ save on dirty memory use. This helps reduce dirty memory use in the ServiceWorker process in the
+ warm case, where the scripts are loaded straight from the disk (via SWScriptStorage).
+
+ * workers/service/ServiceWorkerGlobalScope.cpp:
+ (WebCore::ServiceWorkerGlobalScope::didSaveScriptsToDisk):
+ * workers/service/ServiceWorkerGlobalScope.h:
+ * workers/service/context/SWContextManager.cpp:
+ (WebCore::SWContextManager::didSaveScriptsToDisk):
+ * workers/service/context/SWContextManager.h:
+ * workers/service/context/ServiceWorkerThreadProxy.cpp:
+ (WebCore::ServiceWorkerThreadProxy::didSaveScriptsToDisk):
+ * workers/service/context/ServiceWorkerThreadProxy.h:
+ * workers/service/server/SWServerToContextConnection.h:
+ * workers/service/server/SWServerWorker.cpp:
+ (WebCore::SWServerWorker::didSaveScriptsToDisk):
+ In the cold case, once the NetworkProcess is done saving the scripts to disk, it now sends the
+ file mapped version of the scripts to the ServiceWorker process, so that it can also replace
+ its heap-allocated copies and save on dirty memory use.
+
2021-04-01 Fujii Hironori <[email protected]>
[WebGL] Use GraphicsContextGLOpenGLManager for ports using TextureMapper
Modified: trunk/Source/WebCore/platform/SharedBuffer.cpp (275374 => 275375)
--- trunk/Source/WebCore/platform/SharedBuffer.cpp 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebCore/platform/SharedBuffer.cpp 2021-04-01 20:05:48 UTC (rev 275375)
@@ -216,6 +216,12 @@
return clone;
}
+bool SharedBuffer::hasOneSegment() const
+{
+ auto it = begin();
+ return it != end() && ++it == end();
+}
+
#if ASSERT_ENABLED
bool SharedBuffer::internallyConsistent() const
{
@@ -247,6 +253,11 @@
return WTF::visit(visitor, m_immutableData);
}
+bool SharedBuffer::DataSegment::containsMappedFileData() const
+{
+ return WTF::holds_alternative<FileSystem::MappedFileData>(m_immutableData);
+}
+
#if !USE(CF)
void SharedBuffer::hintMemoryNotNeededSoon() const
{
Modified: trunk/Source/WebCore/platform/SharedBuffer.h (275374 => 275375)
--- trunk/Source/WebCore/platform/SharedBuffer.h 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebCore/platform/SharedBuffer.h 2021-04-01 20:05:48 UTC (rev 275375)
@@ -146,6 +146,8 @@
RetainPtr<NSData> createNSData() const;
#endif
+ bool containsMappedFileData() const;
+
private:
DataSegment(Vector<char>&& data)
: m_immutableData(WTFMove(data)) { }
@@ -185,6 +187,7 @@
using DataSegmentVector = Vector<DataSegmentVectorEntry, 1>;
DataSegmentVector::const_iterator begin() const { return m_segments.begin(); }
DataSegmentVector::const_iterator end() const { return m_segments.end(); }
+ bool hasOneSegment() const;
// begin and end take O(1) time, this takes O(log(N)) time.
SharedBufferDataView getSomeData(size_t position) const;
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContextData.h (275374 => 275375)
--- trunk/Source/WebCore/workers/service/ServiceWorkerContextData.h 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContextData.h 2021-04-01 20:05:48 UTC (rev 275375)
@@ -50,35 +50,6 @@
String mimeType;
ImportedScript isolatedCopy() const { return { script->copy(), responseURL.isolatedCopy(), mimeType.isolatedCopy() }; }
-
- template<class Encoder> void encode(Encoder& encoder) const
- {
- encoder << script << responseURL << mimeType;
- }
-
- template<class Decoder> static Optional<ImportedScript> decode(Decoder& decoder)
- {
- Optional<RefPtr<SharedBuffer>> script;
- decoder >> script;
- if (!script)
- return WTF::nullopt;
-
- Optional<URL> responseURL;
- decoder >> responseURL;
- if (!responseURL)
- return WTF::nullopt;
-
- Optional<String> mimeType;
- decoder >> mimeType;
- if (!mimeType)
- return WTF::nullopt;
-
- return {{
- WTFMove(*script),
- WTFMove(*responseURL),
- WTFMove(*mimeType)
- }};
- }
};
Optional<ServiceWorkerJobDataIdentifier> jobDataIdentifier;
@@ -93,86 +64,9 @@
bool loadedFromDisk;
HashMap<URL, ImportedScript> scriptResourceMap;
- template<class Encoder> void encode(Encoder&) const;
- template<class Decoder> static Optional<ServiceWorkerContextData> decode(Decoder&);
-
ServiceWorkerContextData isolatedCopy() const;
};
-template<class Encoder>
-void ServiceWorkerContextData::encode(Encoder& encoder) const
-{
- encoder << jobDataIdentifier << registration << serviceWorkerIdentifier << script << contentSecurityPolicy << referrerPolicy << scriptURL << workerType << loadedFromDisk;
- encoder << scriptResourceMap;
- encoder << certificateInfo;
-}
-
-template<class Decoder>
-Optional<ServiceWorkerContextData> ServiceWorkerContextData::decode(Decoder& decoder)
-{
- Optional<Optional<ServiceWorkerJobDataIdentifier>> jobDataIdentifier;
- decoder >> jobDataIdentifier;
- if (!jobDataIdentifier)
- return WTF::nullopt;
-
- Optional<ServiceWorkerRegistrationData> registration;
- decoder >> registration;
- if (!registration)
- return WTF::nullopt;
-
- auto serviceWorkerIdentifier = ServiceWorkerIdentifier::decode(decoder);
- if (!serviceWorkerIdentifier)
- return WTF::nullopt;
-
- Optional<Ref<SharedBuffer>> script;
- decoder >> script;
- if (!script)
- return WTF::nullopt;
-
- ContentSecurityPolicyResponseHeaders contentSecurityPolicy;
- if (!decoder.decode(contentSecurityPolicy))
- return WTF::nullopt;
-
- String referrerPolicy;
- if (!decoder.decode(referrerPolicy))
- return WTF::nullopt;
-
- URL scriptURL;
- if (!decoder.decode(scriptURL))
- return WTF::nullopt;
-
- WorkerType workerType;
- if (!decoder.decode(workerType))
- return WTF::nullopt;
-
- bool loadedFromDisk;
- if (!decoder.decode(loadedFromDisk))
- return WTF::nullopt;
-
- HashMap<URL, ImportedScript> scriptResourceMap;
- if (!decoder.decode(scriptResourceMap))
- return WTF::nullopt;
-
- Optional<CertificateInfo> certificateInfo;
- decoder >> certificateInfo;
- if (!certificateInfo)
- return WTF::nullopt;
-
- return {{
- WTFMove(*jobDataIdentifier),
- WTFMove(*registration),
- WTFMove(*serviceWorkerIdentifier),
- WTFMove(*script),
- WTFMove(*certificateInfo),
- WTFMove(contentSecurityPolicy),
- WTFMove(referrerPolicy),
- WTFMove(scriptURL),
- workerType,
- loadedFromDisk,
- WTFMove(scriptResourceMap)
- }};
-}
-
} // namespace WebCore
#endif // ENABLE(SERVICE_WORKER)
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp (275374 => 275375)
--- trunk/Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerGlobalScope.cpp 2021-04-01 20:05:48 UTC (rev 275375)
@@ -155,6 +155,22 @@
m_contextData.scriptResourceMap.set(url, WTFMove(script));
}
+void ServiceWorkerGlobalScope::didSaveScriptsToDisk(RefPtr<SharedBuffer>&& script, HashMap<URL, RefPtr<SharedBuffer>>&& importedScripts)
+{
+ // These scripts should be identical to the ones we have. However, these are mmap'd so using them helps reduce dirty memory usage.
+ if (script) {
+ ASSERT(m_contextData.script.get() == *script);
+ m_contextData.script = script.releaseNonNull();
+ }
+ for (auto& pair : importedScripts) {
+ auto it = m_contextData.scriptResourceMap.find(pair.key);
+ if (it == m_contextData.scriptResourceMap.end())
+ continue;
+ ASSERT(*it->value.script == *pair.value); // Do a memcmp to make sure the scripts are identical.
+ it->value.script = WTFMove(pair.value);
+ }
+}
+
} // namespace WebCore
#endif // ENABLE(SERVICE_WORKER)
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerGlobalScope.h (275374 => 275375)
--- trunk/Source/WebCore/workers/service/ServiceWorkerGlobalScope.h 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerGlobalScope.h 2021-04-01 20:05:48 UTC (rev 275375)
@@ -68,6 +68,8 @@
const ServiceWorkerContextData::ImportedScript* scriptResource(const URL&) const;
void setScriptResource(const URL&, ServiceWorkerContextData::ImportedScript&&);
+ void didSaveScriptsToDisk(RefPtr<SharedBuffer>&& script, HashMap<URL, RefPtr<SharedBuffer>>&& importedScripts);
+
const ServiceWorkerContextData& contextData() const { return m_contextData; }
const CertificateInfo& certificateInfo() const { return m_contextData.certificateInfo; }
Modified: trunk/Source/WebCore/workers/service/context/SWContextManager.cpp (275374 => 275375)
--- trunk/Source/WebCore/workers/service/context/SWContextManager.cpp 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebCore/workers/service/context/SWContextManager.cpp 2021-04-01 20:05:48 UTC (rev 275375)
@@ -120,6 +120,12 @@
stopWorker(*serviceWorker, timeout, WTFMove(completionHandler));
}
+void SWContextManager::didSaveScriptsToDisk(ServiceWorkerIdentifier identifier, RefPtr<SharedBuffer>&& script, HashMap<URL, RefPtr<SharedBuffer>>&& importedScripts)
+{
+ if (auto serviceWorker = m_workerMap.get(identifier))
+ serviceWorker->didSaveScriptsToDisk(WTFMove(script), WTFMove(importedScripts));
+}
+
void SWContextManager::stopWorker(ServiceWorkerThreadProxy& serviceWorker, Seconds timeout, Function<void()>&& completionHandler)
{
auto identifier = serviceWorker.identifier();
Modified: trunk/Source/WebCore/workers/service/context/SWContextManager.h (275374 => 275375)
--- trunk/Source/WebCore/workers/service/context/SWContextManager.h 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebCore/workers/service/context/SWContextManager.h 2021-04-01 20:05:48 UTC (rev 275375)
@@ -90,6 +90,7 @@
WEBCORE_EXPORT void fireInstallEvent(ServiceWorkerIdentifier);
WEBCORE_EXPORT void fireActivateEvent(ServiceWorkerIdentifier);
WEBCORE_EXPORT void terminateWorker(ServiceWorkerIdentifier, Seconds timeout, Function<void()>&&);
+ WEBCORE_EXPORT void didSaveScriptsToDisk(ServiceWorkerIdentifier, RefPtr<SharedBuffer>&& script, HashMap<URL, RefPtr<SharedBuffer>>&& importedScripts);
void forEachServiceWorkerThread(const WTF::Function<void(ServiceWorkerThreadProxy&)>&);
Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp (275374 => 275375)
--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp 2021-04-01 20:05:48 UTC (rev 275375)
@@ -281,6 +281,13 @@
});
}
+void ServiceWorkerThreadProxy::didSaveScriptsToDisk(RefPtr<SharedBuffer>&& script, HashMap<URL, RefPtr<SharedBuffer>>&& importedScripts)
+{
+ thread().runLoop().postTask([script = WTFMove(script), importedScripts = WTFMove(importedScripts)](auto& context) mutable {
+ downcast<ServiceWorkerGlobalScope>(context).didSaveScriptsToDisk(WTFMove(script), WTFMove(importedScripts));
+ });
+}
+
} // namespace WebCore
#endif // ENABLE(SERVICE_WORKER)
Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h (275374 => 275375)
--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h 2021-04-01 20:05:48 UTC (rev 275375)
@@ -78,6 +78,7 @@
void postMessageToServiceWorker(MessageWithMessagePorts&&, ServiceWorkerOrClientData&&);
void fireInstallEvent();
void fireActivateEvent();
+ void didSaveScriptsToDisk(RefPtr<SharedBuffer>&& script, HashMap<URL, RefPtr<SharedBuffer>>&& importedScripts);
WEBCORE_EXPORT void setLastNavigationWasAppBound(bool);
Modified: trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h (275374 => 275375)
--- trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h 2021-04-01 20:05:48 UTC (rev 275375)
@@ -54,6 +54,7 @@
virtual void fireInstallEvent(ServiceWorkerIdentifier) = 0;
virtual void fireActivateEvent(ServiceWorkerIdentifier) = 0;
virtual void terminateWorker(ServiceWorkerIdentifier) = 0;
+ virtual void didSaveScriptsToDisk(ServiceWorkerIdentifier, SharedBuffer& script, const HashMap<URL, RefPtr<SharedBuffer>>& importedScripts) = 0;
virtual void findClientByIdentifierCompleted(uint64_t requestIdentifier, const Optional<ServiceWorkerClientData>&, bool hasSecurityError) = 0;
virtual void matchAllCompleted(uint64_t requestIdentifier, const Vector<ServiceWorkerClientData>&) = 0;
Modified: trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp (275374 => 275375)
--- trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp 2021-04-01 20:05:48 UTC (rev 275375)
@@ -240,7 +240,11 @@
void SWServerWorker::didSaveScriptsToDisk(Ref<SharedBuffer>&& mainScript, HashMap<URL, RefPtr<SharedBuffer>>&& importedScripts)
{
- // The scripts were saved to disk, replace our scripts with the mmap'd version to save memory.
+ // Send mmap'd version of the scripts to the ServiceWorker process so we can save dirty memory.
+ if (auto* contextConnection = this->contextConnection())
+ contextConnection->didSaveScriptsToDisk(identifier(), mainScript, importedScripts);
+
+ // The scripts were saved to disk, replace our scripts with the mmap'd version to save dirty memory.
ASSERT(mainScript.get() == m_script.get()); // Do a memcmp to make sure the scripts are identical.
m_script = WTFMove(mainScript);
for (auto& pair : importedScripts) {
Modified: trunk/Source/WebKit/ChangeLog (275374 => 275375)
--- trunk/Source/WebKit/ChangeLog 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebKit/ChangeLog 2021-04-01 20:05:48 UTC (rev 275375)
@@ -1,3 +1,44 @@
+2021-04-01 Chris Dumez <[email protected]>
+
+ Have the ServiceWorker process hold on to a file mapped version of the service worker scripts to save dirty memory
+ https://bugs.webkit.org/show_bug.cgi?id=224015
+ <rdar://75637679>
+
+ Reviewed by Geoffrey Garen.
+
+ * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
+ (WebKit::WebSWServerToContextConnection::didSaveScriptsToDisk):
+ * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h:
+ * WebProcess/Storage/WebSWContextManagerConnection.cpp:
+ (WebKit::WebSWContextManagerConnection::didSaveScriptsToDisk):
+ * WebProcess/Storage/WebSWContextManagerConnection.h:
+ * WebProcess/Storage/WebSWContextManagerConnection.messages.in:
+ When the NetworkProcess is done saving the service worker scripts to disk and it gets
+ a file mapped version, it now sends them to the ServiceWorker process as ShareableResource
+ handles via IPC. This allows the ServiceWorker process to replace its heap-allocated
+ versions of the script and save on dirty memory use (in the cold case).
+
+ * Shared/ShareableResource.h:
+ Fix bug where 2 of ShareableResource data members were not properly initialized by the default
+ constructor.
+
+ * Shared/WebCoreArgumentCoders.cpp:
+ (IPC::encodeServiceWorkerContextDataScript):
+ (IPC::decodeServiceWorkerContextDataScript):
+ (IPC::ArgumentCoder<ServiceWorkerContextData::ImportedScript>::encode):
+ (IPC::ArgumentCoder<ServiceWorkerContextData::ImportedScript>::decode):
+ (IPC::ArgumentCoder<ServiceWorkerContextData>::encode):
+ (IPC::ArgumentCoder<ServiceWorkerContextData>::decode):
+ (IPC::tryConvertToShareableResourceHandle):
+ * Shared/WebCoreArgumentCoders.h:
+ Moved IPC encoders / decoders for ServiceWorkerContextData and ServiceWorkerContextData::ImportedScript
+ to the WebKit layer, in WebCoreArgumentCoders. This allows us to encode / decode the scripts as
+ WebKit::ShareableHandle whenever possible. This way, when the NetworkProcess sends a
+ ServiceWorkerContextData to the ServiceWorker process to launch a service worker, both the
+ ServiceWorker process and the Network process share the same mmap'd versions of the scripts and we
+ save on dirty memory use. This helps reduce dirty memory use in the ServiceWorker process in the
+ warm case, where the scripts are loaded straight from the disk (via SWScriptStorage).
+
2021-04-01 Myles C. Maxfield <[email protected]>
[Cocoa] REGRESSION(r272999): User-installed fonts no longer work in Mail
Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp (275374 => 275375)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp 2021-04-01 20:05:48 UTC (rev 275375)
@@ -107,6 +107,25 @@
send(Messages::WebSWContextManagerConnection::TerminateWorker(serviceWorkerIdentifier));
}
+void WebSWServerToContextConnection::didSaveScriptsToDisk(ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::SharedBuffer& script, const HashMap<URL, RefPtr<SharedBuffer>>& importedScripts)
+{
+#if ENABLE(SHAREABLE_RESOURCE) && PLATFORM(COCOA)
+ auto scriptHandle = IPC::tryConvertToShareableResourceHandle(script);
+ HashMap<URL, ShareableResource::Handle> importedScriptHandles;
+ for (auto& pair : importedScripts) {
+ auto handle = IPC::tryConvertToShareableResourceHandle(*pair.value);
+ if (handle.isNull())
+ continue;
+ importedScriptHandles.add(pair.key, WTFMove(handle));
+ }
+ if (!scriptHandle.isNull() || !importedScriptHandles.isEmpty())
+ send(Messages::WebSWContextManagerConnection::DidSaveScriptsToDisk { serviceWorkerIdentifier, scriptHandle, importedScriptHandles });
+#else
+ UNUSED_PARAM(script);
+ UNUSED_PARAM(importedScripts);
+#endif
+}
+
void WebSWServerToContextConnection::terminateDueToUnresponsiveness()
{
m_connection.networkProcess().parentProcessConnection()->send(Messages::NetworkProcessProxy::TerminateUnresponsiveServiceWorkerProcesses { webProcessIdentifier() }, 0);
Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h (275374 => 275375)
--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h 2021-04-01 20:05:48 UTC (rev 275375)
@@ -88,6 +88,7 @@
void fireInstallEvent(WebCore::ServiceWorkerIdentifier) final;
void fireActivateEvent(WebCore::ServiceWorkerIdentifier) final;
void terminateWorker(WebCore::ServiceWorkerIdentifier) final;
+ void didSaveScriptsToDisk(WebCore::ServiceWorkerIdentifier, WebCore::SharedBuffer& script, const HashMap<URL, RefPtr<WebCore::SharedBuffer>>& importedScripts) final;
void findClientByIdentifierCompleted(uint64_t requestIdentifier, const Optional<WebCore::ServiceWorkerClientData>&, bool hasSecurityError) final;
void matchAllCompleted(uint64_t requestIdentifier, const Vector<WebCore::ServiceWorkerClientData>&) final;
Modified: trunk/Source/WebKit/Shared/ShareableResource.cpp (275374 => 275375)
--- trunk/Source/WebKit/Shared/ShareableResource.cpp 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebKit/Shared/ShareableResource.cpp 2021-04-01 20:05:48 UTC (rev 275375)
@@ -34,9 +34,7 @@
namespace WebKit {
using namespace WebCore;
-ShareableResource::Handle::Handle()
-{
-}
+ShareableResource::Handle::Handle() = default;
void ShareableResource::Handle::encode(IPC::Encoder& encoder) const
{
Modified: trunk/Source/WebKit/Shared/ShareableResource.h (275374 => 275375)
--- trunk/Source/WebKit/Shared/ShareableResource.h 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebKit/Shared/ShareableResource.h 2021-04-01 20:05:48 UTC (rev 275375)
@@ -60,8 +60,8 @@
friend class ShareableResource;
mutable SharedMemory::Handle m_handle;
- unsigned m_offset;
- unsigned m_size;
+ unsigned m_offset { 0 };
+ unsigned m_size { 0 };
};
// Create a shareable resource that uses malloced memory.
Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp (275374 => 275375)
--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp 2021-04-01 20:05:48 UTC (rev 275375)
@@ -2828,8 +2828,145 @@
}
return true;
}
+
+static void encodeServiceWorkerContextDataScript(Encoder& encoder, SharedBuffer& script)
+{
+#if ENABLE(SHAREABLE_RESOURCE) && PLATFORM(COCOA)
+ auto handle = tryConvertToShareableResourceHandle(script);
+ bool isShareableResourceHandle = !handle.isNull();
+ encoder << isShareableResourceHandle;
+ if (isShareableResourceHandle) {
+ encoder << handle;
+ return;
+ }
#endif
+ encoder << makeRef(script);
+}
+static Optional<Ref<SharedBuffer>> decodeServiceWorkerContextDataScript(Decoder& decoder)
+{
+#if ENABLE(SHAREABLE_RESOURCE) && PLATFORM(COCOA)
+ Optional<bool> isShareableResourceHandle;
+ decoder >> isShareableResourceHandle;
+ if (!isShareableResourceHandle)
+ return WTF::nullopt;
+ if (*isShareableResourceHandle) {
+ ShareableResource::Handle handle;
+ if (!decoder.decode(handle) || handle.isNull())
+ return WTF::nullopt;
+ auto buffer = handle.tryWrapInSharedBuffer();
+ if (!buffer)
+ return WTF::nullopt;
+ return buffer.releaseNonNull();
+ }
+#endif
+ Optional<Ref<SharedBuffer>> script;
+ decoder >> script;
+ return script;
+}
+
+void ArgumentCoder<ServiceWorkerContextData::ImportedScript>::encode(Encoder& encoder, const ServiceWorkerContextData::ImportedScript& importedScript)
+{
+ encodeServiceWorkerContextDataScript(encoder, *importedScript.script);
+ encoder << importedScript.responseURL << importedScript.mimeType;
+}
+
+Optional<ServiceWorkerContextData::ImportedScript> ArgumentCoder<ServiceWorkerContextData::ImportedScript>::decode(Decoder& decoder)
+{
+ auto script = decodeServiceWorkerContextDataScript(decoder);
+ if (!script)
+ return WTF::nullopt;
+
+ Optional<URL> responseURL;
+ decoder >> responseURL;
+ if (!responseURL)
+ return WTF::nullopt;
+
+ Optional<String> mimeType;
+ decoder >> mimeType;
+ if (!mimeType)
+ return WTF::nullopt;
+
+ return {{
+ WTFMove(*script),
+ WTFMove(*responseURL),
+ WTFMove(*mimeType)
+ }};
+}
+
+void ArgumentCoder<ServiceWorkerContextData>::encode(Encoder& encoder, const ServiceWorkerContextData& data)
+{
+ encodeServiceWorkerContextDataScript(encoder, data.script);
+ encoder << data.jobDataIdentifier << data.registration << data.serviceWorkerIdentifier << data.contentSecurityPolicy << data.referrerPolicy
+ << data.scriptURL << data.workerType << data.loadedFromDisk << data.scriptResourceMap << data.certificateInfo;
+}
+
+Optional<ServiceWorkerContextData> ArgumentCoder<ServiceWorkerContextData>::decode(Decoder& decoder)
+{
+ auto script = decodeServiceWorkerContextDataScript(decoder);
+ if (!script)
+ return WTF::nullopt;
+
+ Optional<Optional<ServiceWorkerJobDataIdentifier>> jobDataIdentifier;
+ decoder >> jobDataIdentifier;
+ if (!jobDataIdentifier)
+ return WTF::nullopt;
+
+ Optional<ServiceWorkerRegistrationData> registration;
+ decoder >> registration;
+ if (!registration)
+ return WTF::nullopt;
+
+ auto serviceWorkerIdentifier = ServiceWorkerIdentifier::decode(decoder);
+ if (!serviceWorkerIdentifier)
+ return WTF::nullopt;
+
+ ContentSecurityPolicyResponseHeaders contentSecurityPolicy;
+ if (!decoder.decode(contentSecurityPolicy))
+ return WTF::nullopt;
+
+ String referrerPolicy;
+ if (!decoder.decode(referrerPolicy))
+ return WTF::nullopt;
+
+ URL scriptURL;
+ if (!decoder.decode(scriptURL))
+ return WTF::nullopt;
+
+ WorkerType workerType;
+ if (!decoder.decode(workerType))
+ return WTF::nullopt;
+
+ bool loadedFromDisk;
+ if (!decoder.decode(loadedFromDisk))
+ return WTF::nullopt;
+
+ HashMap<URL, ServiceWorkerContextData::ImportedScript> scriptResourceMap;
+ if (!decoder.decode(scriptResourceMap))
+ return WTF::nullopt;
+
+ Optional<CertificateInfo> certificateInfo;
+ decoder >> certificateInfo;
+ if (!certificateInfo)
+ return WTF::nullopt;
+
+ return {{
+ WTFMove(*jobDataIdentifier),
+ WTFMove(*registration),
+ WTFMove(*serviceWorkerIdentifier),
+ WTFMove(*script),
+ WTFMove(*certificateInfo),
+ WTFMove(contentSecurityPolicy),
+ WTFMove(referrerPolicy),
+ WTFMove(scriptURL),
+ workerType,
+ loadedFromDisk,
+ WTFMove(scriptResourceMap)
+ }};
+}
+
+#endif
+
#if ENABLE(CSS_SCROLL_SNAP)
void ArgumentCoder<ScrollOffsetRange<float>>::encode(Encoder& encoder, const ScrollOffsetRange<float>& range)
@@ -3066,6 +3203,30 @@
return buffer.releaseNonNull();
}
+#if ENABLE(SHAREABLE_RESOURCE) && PLATFORM(COCOA)
+ShareableResource::Handle tryConvertToShareableResourceHandle(SharedBuffer& buffer)
+{
+ if (!buffer.hasOneSegment())
+ return ShareableResource::Handle { };
+
+ auto& segment = buffer.begin()->segment;
+ if (!segment->containsMappedFileData())
+ return ShareableResource::Handle { };
+
+ auto sharedMemory = SharedMemory::wrapMap(const_cast<char*>(segment->data()), segment->size(), SharedMemory::Protection::ReadOnly);
+ if (!sharedMemory)
+ return ShareableResource::Handle { };
+
+ auto shareableResource = ShareableResource::create(sharedMemory.releaseNonNull(), 0, segment->size());
+ if (!shareableResource)
+ return ShareableResource::Handle { };
+
+ ShareableResource::Handle shareableResourceHandle;
+ shareableResource->createHandle(shareableResourceHandle);
+ return shareableResourceHandle;
+}
+#endif
+
#if ENABLE(ENCRYPTED_MEDIA)
void ArgumentCoder<WebCore::CDMInstanceSession::Message>::encode(Encoder& encoder, const WebCore::CDMInstanceSession::Message& message)
{
Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h (275374 => 275375)
--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h 2021-04-01 20:05:48 UTC (rev 275375)
@@ -26,6 +26,7 @@
#pragma once
#include "ArgumentCoders.h"
+#include "ShareableResource.h"
#include <WebCore/AutoplayEvent.h>
#include <WebCore/ColorSpace.h>
#include <WebCore/DiagnosticLoggingClient.h>
@@ -41,6 +42,7 @@
#include <WebCore/RenderingMode.h>
#include <WebCore/ScrollSnapOffsetsInfo.h>
#include <WebCore/SerializedPlatformDataCueValue.h>
+#include <WebCore/ServiceWorkerContextData.h>
#include <WebCore/ServiceWorkerTypes.h>
#include <WebCore/StoredCredentialsPolicy.h>
#include <WebCore/WorkerType.h>
@@ -735,6 +737,16 @@
static WARN_UNUSED_RETURN bool decode(Decoder&, WebCore::ServiceWorkerOrClientIdentifier&);
};
+template<> struct ArgumentCoder<WebCore::ServiceWorkerContextData> {
+ static void encode(Encoder&, const WebCore::ServiceWorkerContextData&);
+ static Optional<WebCore::ServiceWorkerContextData> decode(Decoder&);
+};
+
+template<> struct ArgumentCoder<WebCore::ServiceWorkerContextData::ImportedScript> {
+ static void encode(Encoder&, const WebCore::ServiceWorkerContextData::ImportedScript&);
+ static Optional<WebCore::ServiceWorkerContextData::ImportedScript> decode(Decoder&);
+};
+
#endif
#if ENABLE(CSS_SCROLL_SNAP)
@@ -796,6 +808,12 @@
static Optional<Ref<WebCore::SharedBuffer>> decode(Decoder&);
};
+#if ENABLE(SHAREABLE_RESOURCE) && PLATFORM(COCOA)
+// If the SharedBuffer contains a single segment and the segment is MappedFileData, then convert it into
+// a ShareableResource handle so that it can be sent over IPC and shared with another process.
+WebKit::ShareableResource::Handle tryConvertToShareableResourceHandle(WebCore::SharedBuffer&);
+#endif
+
#if ENABLE(ENCRYPTED_MEDIA)
template<> struct ArgumentCoder<WebCore::CDMInstanceSession::Message> {
static void encode(Encoder&, const WebCore::CDMInstanceSession::Message&);
Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp (275374 => 275375)
--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp 2021-04-01 20:05:48 UTC (rev 275375)
@@ -262,6 +262,26 @@
SWContextManager::singleton().terminateWorker(identifier, SWContextManager::workerTerminationTimeout, nullptr);
}
+#if ENABLE(SHAREABLE_RESOURCE) && PLATFORM(COCOA)
+void WebSWContextManagerConnection::didSaveScriptsToDisk(WebCore::ServiceWorkerIdentifier identifier, const ShareableResource::Handle& scriptHandle, const HashMap<URL, ShareableResource::Handle>& importedScriptHandles)
+{
+ auto toSharedBuffer = [](const ShareableResource::Handle& handle) -> RefPtr<SharedBuffer> {
+ if (handle.isNull())
+ return nullptr;
+ auto sharedBuffer = handle.tryWrapInSharedBuffer();
+ if (!sharedBuffer)
+ RELEASE_LOG_ERROR(ServiceWorker, "WebSWContextManagerConnection::didSaveScriptsToDisk: Failed to wrap ShareableResource handle in a SharedBuffer");
+ return sharedBuffer;
+ };
+ HashMap<URL, RefPtr<SharedBuffer>> importedScripts;
+ for (auto& pair : importedScriptHandles) {
+ if (auto sharedBuffer = toSharedBuffer(pair.value))
+ importedScripts.add(pair.key, WTFMove(sharedBuffer));
+ }
+ SWContextManager::singleton().didSaveScriptsToDisk(identifier, toSharedBuffer(scriptHandle), WTFMove(importedScripts));
+}
+#endif
+
void WebSWContextManagerConnection::postMessageToServiceWorkerClient(const ServiceWorkerClientIdentifier& destinationIdentifier, const MessageWithMessagePorts& message, ServiceWorkerIdentifier sourceIdentifier, const String& sourceOrigin)
{
m_connectionToNetworkProcess->send(Messages::WebSWServerToContextConnection::PostMessageToServiceWorkerClient(destinationIdentifier, message, sourceIdentifier, sourceOrigin), 0);
Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h (275374 => 275375)
--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h 2021-04-01 20:05:48 UTC (rev 275375)
@@ -29,6 +29,7 @@
#include "Connection.h"
#include "MessageReceiver.h"
+#include "ShareableResource.h"
#include "UserContentControllerIdentifier.h"
#include "WebPageProxyIdentifier.h"
#include "WebSWContextManagerConnectionMessagesReplies.h"
@@ -90,6 +91,9 @@
void fireInstallEvent(WebCore::ServiceWorkerIdentifier);
void fireActivateEvent(WebCore::ServiceWorkerIdentifier);
void terminateWorker(WebCore::ServiceWorkerIdentifier);
+#if ENABLE(SHAREABLE_RESOURCE) && PLATFORM(COCOA)
+ void didSaveScriptsToDisk(WebCore::ServiceWorkerIdentifier, const ShareableResource::Handle& script, const HashMap<URL, ShareableResource::Handle>& importedScripts);
+#endif
void findClientByIdentifierCompleted(uint64_t requestIdentifier, Optional<WebCore::ServiceWorkerClientData>&&, bool hasSecurityError);
void matchAllCompleted(uint64_t matchAllRequestIdentifier, Vector<WebCore::ServiceWorkerClientData>&&);
void setUserAgent(String&& userAgent);
Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in (275374 => 275375)
--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in 2021-04-01 20:02:50 UTC (rev 275374)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in 2021-04-01 20:05:48 UTC (rev 275375)
@@ -31,6 +31,9 @@
FireInstallEvent(WebCore::ServiceWorkerIdentifier identifier)
FireActivateEvent(WebCore::ServiceWorkerIdentifier identifier)
TerminateWorker(WebCore::ServiceWorkerIdentifier identifier)
+#if ENABLE(SHAREABLE_RESOURCE) && PLATFORM(COCOA)
+ DidSaveScriptsToDisk(WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebKit::ShareableResource::Handle script, HashMap<URL, WebKit::ShareableResource::Handle> importedScripts);
+#endif
FindClientByIdentifierCompleted(uint64_t clientIdRequestIdentifier, Optional<WebCore::ServiceWorkerClientData> data, bool hasSecurityError)
MatchAllCompleted(uint64_t matchAllRequestIdentifier, Vector<WebCore::ServiceWorkerClientData> clientsData)
SetUserAgent(String userAgent)