Modified: trunk/Source/WebKit/UIProcess/WebProcessCache.cpp (242725 => 242726)
--- trunk/Source/WebKit/UIProcess/WebProcessCache.cpp 2019-03-11 19:21:48 UTC (rev 242725)
+++ trunk/Source/WebKit/UIProcess/WebProcessCache.cpp 2019-03-11 19:30:42 UTC (rev 242726)
@@ -37,6 +37,12 @@
Seconds WebProcessCache::cachedProcessLifetime { 30_min };
Seconds WebProcessCache::clearingDelayAfterApplicationResignsActive { 5_min };
+static uint64_t generateAddRequestIdentifier()
+{
+ static uint64_t identifier = 0;
+ return ++identifier;
+}
+
WebProcessCache::WebProcessCache(WebProcessPool& processPool)
: m_evictionTimer(RunLoop::main(), this, &WebProcessCache::clear)
{
@@ -73,38 +79,47 @@
if (!canCacheProcess(process))
return false;
+ uint64_t requestIdentifier = generateAddRequestIdentifier();
+ m_pendingAddRequests.add(requestIdentifier, std::make_unique<CachedProcess>(process.copyRef()));
+
RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::addProcessIfPossible(): Checking if process %i is responsive before caching it...", this, process->processIdentifier());
- process->setIsInProcessCache(true);
- process->isResponsive([process = process.copyRef(), processPool = makeRef(process->processPool()), registrableDomain](bool isResponsive) {
- process->setIsInProcessCache(false);
+ process->isResponsive([this, processPool = makeRef(process->processPool()), requestIdentifier](bool isResponsive) {
+ auto cachedProcess = m_pendingAddRequests.take(requestIdentifier);
+ if (!cachedProcess)
+ return;
+
if (!isResponsive) {
- RELEASE_LOG_ERROR(ProcessSwapping, "%p - WebProcessCache::addProcessIfPossible(): Not caching process %i because it is not responsive", &process->processPool().webProcessCache(), process->processIdentifier());
- process->shutDown();
+ RELEASE_LOG_ERROR(ProcessSwapping, "%p - WebProcessCache::addProcessIfPossible(): Not caching process %i because it is not responsive", &processPool->webProcessCache(), cachedProcess->process().processIdentifier());
return;
}
- if (!processPool->webProcessCache().addProcess(registrableDomain, process.copyRef()))
- process->shutDown();
+ processPool->webProcessCache().addProcess(WTFMove(cachedProcess));
});
return true;
}
-bool WebProcessCache::addProcess(const String& registrableDomain, Ref<WebProcessProxy>&& process)
+bool WebProcessCache::addProcess(std::unique_ptr<CachedProcess>&& cachedProcess)
{
- ASSERT(!process->pageCount());
- ASSERT(!process->provisionalPageCount());
- ASSERT(!process->suspendedPageCount());
+ ASSERT(!cachedProcess->process().pageCount());
+ ASSERT(!cachedProcess->process().provisionalPageCount());
+ ASSERT(!cachedProcess->process().suspendedPageCount());
- if (!canCacheProcess(process))
+ if (!canCacheProcess(cachedProcess->process()))
return false;
+ auto registrableDomain = cachedProcess->process().registrableDomain();
+ RELEASE_ASSERT(!registrableDomain.isEmpty());
+
+ if (auto previousProcess = m_processesPerRegistrableDomain.take(registrableDomain))
+ RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::addProcess(): Evicting process %i from WebProcess cache because a new process was added for the same domain", this, previousProcess->process().processIdentifier());
+
while (m_processesPerRegistrableDomain.size() >= capacity()) {
auto it = m_processesPerRegistrableDomain.random();
- RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::addProcess(): Evicting process %i from WebProcess cache", this, it->value->process().processIdentifier());
+ RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::addProcess(): Evicting process %i from WebProcess cache because capacity was reached", this, it->value->process().processIdentifier());
m_processesPerRegistrableDomain.remove(it);
}
- m_processesPerRegistrableDomain.set(registrableDomain, std::make_unique<CachedProcess>(process.copyRef()));
- RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::addProcess: Adding process %i to WebProcess cache, cache size: [%u / %u]", this, process->processIdentifier(), size(), capacity());
+ RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::addProcess: Added process %i to WebProcess cache, cache size: [%u / %u]", this, cachedProcess->process().processIdentifier(), size() + 1, capacity());
+ m_processesPerRegistrableDomain.add(registrableDomain, WTFMove(cachedProcess));
return true;
}
@@ -155,10 +170,11 @@
void WebProcessCache::clear()
{
- if (m_processesPerRegistrableDomain.isEmpty())
+ if (m_pendingAddRequests.isEmpty() && m_processesPerRegistrableDomain.isEmpty())
return;
- RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::clear() evicting %u processes", this, m_processesPerRegistrableDomain.size());
+ RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::clear() evicting %u processes", this, m_pendingAddRequests.size() + m_processesPerRegistrableDomain.size());
+ m_pendingAddRequests.clear();
m_processesPerRegistrableDomain.clear();
}
@@ -173,6 +189,16 @@
}
for (auto& key : keysToRemove)
m_processesPerRegistrableDomain.remove(key);
+
+ Vector<uint64_t> pendingRequestsToRemove;
+ for (auto& pair : m_pendingAddRequests) {
+ if (pair.value->process().websiteDataStore().sessionID() == sessionID) {
+ RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::clearAllProcessesForSession() evicting process %i because its session was destroyed", this, pair.value->process().processIdentifier());
+ pendingRequestsToRemove.append(pair.key);
+ }
+ }
+ for (auto& key : pendingRequestsToRemove)
+ m_pendingAddRequests.remove(key);
}
void WebProcessCache::setApplicationIsActive(bool isActive)
@@ -184,16 +210,32 @@
m_evictionTimer.startOneShot(clearingDelayAfterApplicationResignsActive);
}
-void WebProcessCache::evictProcess(WebProcessProxy& process)
+void WebProcessCache::removeProcess(WebProcessProxy& process, ShouldShutDownProcess shouldShutDownProcess)
{
RELEASE_ASSERT(!process.registrableDomain().isEmpty());
+ RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::evictProcess(): Evicting process %i from WebProcess cache because it expired", this, process.processIdentifier());
+
+ std::unique_ptr<CachedProcess> cachedProcess;
auto it = m_processesPerRegistrableDomain.find(process.registrableDomain());
- ASSERT(it != m_processesPerRegistrableDomain.end());
- ASSERT(&it->value->process() == &process);
+ if (it != m_processesPerRegistrableDomain.end() && &it->value->process() == &process) {
+ cachedProcess = WTFMove(it->value);
+ m_processesPerRegistrableDomain.remove(it);
+ } else {
+ for (auto& pair : m_pendingAddRequests) {
+ if (&pair.value->process() == &process) {
+ cachedProcess = WTFMove(pair.value);
+ m_pendingAddRequests.remove(pair.key);
+ break;
+ }
+ }
+ }
+ ASSERT(cachedProcess);
+ if (!cachedProcess)
+ return;
- RELEASE_LOG(ProcessSwapping, "%p - WebProcessCache::evictProcess(): Evicting process %i from WebProcess cache because it expired", this, process.processIdentifier());
-
- m_processesPerRegistrableDomain.remove(it);
+ ASSERT(&cachedProcess->process() == &process);
+ if (shouldShutDownProcess == ShouldShutDownProcess::No)
+ cachedProcess->takeProcess();
}
WebProcessCache::CachedProcess::CachedProcess(Ref<WebProcessProxy>&& process)
@@ -228,7 +270,7 @@
void WebProcessCache::CachedProcess::evictionTimerFired()
{
ASSERT(m_process);
- m_process->processPool().webProcessCache().evictProcess(*m_process);
+ m_process->processPool().webProcessCache().removeProcess(*m_process, ShouldShutDownProcess::Yes);
}
#if !PLATFORM(COCOA)
Modified: trunk/Source/WebKit/UIProcess/WebProcessCache.h (242725 => 242726)
--- trunk/Source/WebKit/UIProcess/WebProcessCache.h 2019-03-11 19:21:48 UTC (rev 242725)
+++ trunk/Source/WebKit/UIProcess/WebProcessCache.h 2019-03-11 19:30:42 UTC (rev 242726)
@@ -55,17 +55,13 @@
void clearAllProcessesForSession(PAL::SessionID);
+ enum class ShouldShutDownProcess { No, Yes };
+ void removeProcess(WebProcessProxy&, ShouldShutDownProcess);
+
private:
static Seconds cachedProcessLifetime;
static Seconds clearingDelayAfterApplicationResignsActive;
- bool canCacheProcess(WebProcessProxy&) const;
- void evictProcess(WebProcessProxy&);
- void platformInitialize();
- bool addProcess(const String& registrableDomain, Ref<WebProcessProxy>&&);
-
- unsigned m_capacity { 0 };
-
class CachedProcess {
WTF_MAKE_FAST_ALLOCATED;
public:
@@ -82,6 +78,13 @@
RunLoop::Timer<CachedProcess> m_evictionTimer;
};
+ bool canCacheProcess(WebProcessProxy&) const;
+ void platformInitialize();
+ bool addProcess(std::unique_ptr<CachedProcess>&&);
+
+ unsigned m_capacity { 0 };
+
+ HashMap<uint64_t, std::unique_ptr<CachedProcess>> m_pendingAddRequests;
HashMap<String, std::unique_ptr<CachedProcess>> m_processesPerRegistrableDomain;
RunLoop::Timer<WebProcessCache> m_evictionTimer;
};
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.cpp (242725 => 242726)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2019-03-11 19:21:48 UTC (rev 242725)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2019-03-11 19:30:42 UTC (rev 242726)
@@ -2260,8 +2260,8 @@
// Make sure we remove the process from the cache if it is in there since we're about to use it.
if (process->isInProcessCache()) {
- auto removedProcess = webProcessCache().takeProcess(process->registrableDomain(), process->websiteDataStore());
- ASSERT_UNUSED(removedProcess, removedProcess.get() == process.get());
+ webProcessCache().removeProcess(*process, WebProcessCache::ShouldShutDownProcess::No);
+ ASSERT(!process->isInProcessCache());
}
return completionHandler(process.releaseNonNull(), nullptr, "Using target back/forward item's process"_s);