Title: [137255] trunk/Source/WebKit2
Revision
137255
Author
[email protected]
Date
2012-12-10 23:33:01 -0800 (Mon, 10 Dec 2012)

Log Message

[WK2] Add a user default to limit the number of web processes
https://bugs.webkit.org/show_bug.cgi?id=104606

Reviewed by Sam Weinig.

When the limit is reached, we'll reuse an existing process with fewest pages.

* UIProcess/WebContext.cpp:
(WebKit::WebContext::WebContext): Initialize m_webProcessCountLimit.
(WebKit::WebContext::platformInitialize): Added a hook for reading the preference,
empty implementation on most platforms.
(WebKit::WebContext::createNewWebProcess): Changed to return a raw pointer. The new
process is put into a vector anyway, so there is no ownership transfer.
(WebKit::WebContext::warmInitialProcess): Don't create a new process if that would
exceed the limit.
(WebKit::WebContext::createNewWebProcessRespectingProcessCountLimit): Added a new
function that wither creates a new process, or picks an existing one.
(WebKit::WebContext::createWebPage): Call the above new function instead of
unconditionally creating a process.

* UIProcess/WebContext.h: createNewWebProcess is no private. All clients should
respect the process count limit.

* UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::reattachToWebProcess):
Respect the process count limit.

* UIProcess/mac/WebContextMac.mm:
(WebKit::registerUserDefaultsIfNeeded): Register the new default.
(WebKit::WebContext::platformInitialize): Read the default into a WebContext
member variable.
(WebKit::WebContext::platformInitializeWebProcess): Moved registerUserDefaultsIfNeeded()
from here to platformInitialize(), as that's a better place for it. Also added a
FIXME for an unrelated issue.

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (137254 => 137255)


--- trunk/Source/WebKit2/ChangeLog	2012-12-11 07:31:17 UTC (rev 137254)
+++ trunk/Source/WebKit2/ChangeLog	2012-12-11 07:33:01 UTC (rev 137255)
@@ -1,3 +1,39 @@
+2012-12-10  Alexey Proskuryakov  <[email protected]>
+
+        [WK2] Add a user default to limit the number of web processes
+        https://bugs.webkit.org/show_bug.cgi?id=104606
+
+        Reviewed by Sam Weinig.
+
+        When the limit is reached, we'll reuse an existing process with fewest pages.
+
+        * UIProcess/WebContext.cpp:
+        (WebKit::WebContext::WebContext): Initialize m_webProcessCountLimit.
+        (WebKit::WebContext::platformInitialize): Added a hook for reading the preference,
+        empty implementation on most platforms.
+        (WebKit::WebContext::createNewWebProcess): Changed to return a raw pointer. The new
+        process is put into a vector anyway, so there is no ownership transfer.
+        (WebKit::WebContext::warmInitialProcess): Don't create a new process if that would
+        exceed the limit.
+        (WebKit::WebContext::createNewWebProcessRespectingProcessCountLimit): Added a new
+        function that wither creates a new process, or picks an existing one.
+        (WebKit::WebContext::createWebPage): Call the above new function instead of
+        unconditionally creating a process.
+
+        * UIProcess/WebContext.h: createNewWebProcess is no private. All clients should
+        respect the process count limit.
+
+        * UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::reattachToWebProcess):
+        Respect the process count limit.
+
+        * UIProcess/mac/WebContextMac.mm:
+        (WebKit::registerUserDefaultsIfNeeded): Register the new default.
+        (WebKit::WebContext::platformInitialize): Read the default into a WebContext
+        member variable.
+        (WebKit::WebContext::platformInitializeWebProcess): Moved registerUserDefaultsIfNeeded()
+        from here to platformInitialize(), as that's a better place for it. Also added a
+        FIXME for an unrelated issue.
+
 2012-12-10  Jon Lee  <[email protected]>
 
         Build fix.

Modified: trunk/Source/WebKit2/UIProcess/WebContext.cpp (137254 => 137255)


--- trunk/Source/WebKit2/UIProcess/WebContext.cpp	2012-12-11 07:31:17 UTC (rev 137254)
+++ trunk/Source/WebKit2/UIProcess/WebContext.cpp	2012-12-11 07:33:01 UTC (rev 137255)
@@ -120,6 +120,7 @@
 
 WebContext::WebContext(ProcessModel processModel, const String& injectedBundlePath)
     : m_processModel(processModel)
+    , m_webProcessCountLimit(UINT_MAX)
     , m_haveInitialEmptyProcess(false)
     , m_defaultPageGroup(WebPageGroup::create())
     , m_injectedBundlePath(injectedBundlePath)
@@ -139,6 +140,8 @@
     , m_usesNetworkProcess(false)
 #endif
 {
+    platformInitialize();
+
     addMessageReceiver(Messages::WebContext::messageReceiverName(), this);
     addMessageReceiver(CoreIPC::MessageKindTraits<WebContextLegacyMessage::Kind>::messageReceiverName(), this);
 
@@ -184,6 +187,12 @@
 #endif
 }
 
+#if !PLATFORM(MAC)
+void WebContext::platformInitialize()
+{
+}
+#endif
+
 WebContext::~WebContext()
 {
     ASSERT(contexts().find(this) != notFound);
@@ -388,7 +397,7 @@
     return m_processes[0].get();
 }
 
-PassRefPtr<WebProcessProxy> WebContext::createNewWebProcess()
+WebProcessProxy* WebContext::createNewWebProcess()
 {
 #if ENABLE(NETWORK_PROCESS)
     if (m_usesNetworkProcess)
@@ -480,8 +489,7 @@
     } else
         ASSERT(m_messagesToInjectedBundlePostedToEmptyContext.isEmpty());
 
-
-    return process.release();
+    return process.get();
 }
 
 void WebContext::warmInitialProcess()  
@@ -491,6 +499,9 @@
         return;
     }
 
+    if (m_processes.size() >= m_webProcessCountLimit)
+        return;
+
     createNewWebProcess();
     m_haveInitialEmptyProcess = true;
 }
@@ -615,6 +626,23 @@
     m_processes.remove(m_processes.find(process));
 }
 
+WebProcessProxy* WebContext::createNewWebProcessRespectingProcessCountLimit()
+{
+    if (m_processes.size() < m_webProcessCountLimit)
+        return createNewWebProcess();
+
+    // Choose a process with fewest pages, to achieve flat distribution.
+    WebProcessProxy* result = 0;
+    unsigned fewestPagesSeen = UINT_MAX;
+    for (unsigned i = 0; i < m_processes.size(); ++i) {
+        if (fewestPagesSeen > m_processes[i]->pages().size()) {
+            result = m_processes[i].get();
+            fewestPagesSeen = m_processes[i]->pages().size();
+        }
+    }
+    return result;
+}
+
 PassRefPtr<WebPageProxy> WebContext::createWebPage(PageClient* pageClient, WebPageGroup* pageGroup, WebPageProxy* relatedPage)
 {
     RefPtr<WebProcessProxy> process;
@@ -627,10 +655,8 @@
         } else if (relatedPage) {
             // Sharing processes, e.g. when creating the page via window.open().
             process = relatedPage->process();
-        } else {
-            // FIXME (Multi-WebProcess): <rdar://problem/12239661> Consider limiting the number of web processes in per-tab process model.
-            process = createNewWebProcess();
-        }
+        } else
+            process = createNewWebProcessRespectingProcessCountLimit();
     }
 
     if (!pageGroup)

Modified: trunk/Source/WebKit2/UIProcess/WebContext.h (137254 => 137255)


--- trunk/Source/WebKit2/UIProcess/WebContext.h	2012-12-11 07:31:17 UTC (rev 137254)
+++ trunk/Source/WebKit2/UIProcess/WebContext.h	2012-12-11 07:33:01 UTC (rev 137255)
@@ -220,7 +220,7 @@
     void setCookieStorageDirectory(const String& dir) { m_overrideCookieStorageDirectory = dir; }
 
     WebProcessProxy* ensureSharedWebProcess();
-    PassRefPtr<WebProcessProxy> createNewWebProcess();
+    WebProcessProxy* createNewWebProcessRespectingProcessCountLimit(); // Will return an existing one if limit is met.
     void warmInitialProcess();
 
     bool shouldTerminate(WebProcessProxy*);
@@ -256,12 +256,15 @@
 
 private:
     WebContext(ProcessModel, const String& injectedBundlePath);
+    void platformInitialize();
 
     virtual Type type() const { return APIType; }
 
     void platformInitializeWebProcess(WebProcessCreationParameters&);
     void platformInvalidateContext();
 
+    WebProcessProxy* createNewWebProcess();
+
 #if PLATFORM(MAC)
     void getPasteboardTypes(const String& pasteboardName, Vector<String>& pasteboardTypes);
     void getPasteboardPathnamesForType(const String& pasteboardName, const String& pasteboardType, Vector<String>& pathnames);
@@ -318,6 +321,7 @@
     void addPlugInAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash);
 
     ProcessModel m_processModel;
+    unsigned m_webProcessCountLimit; // The limit has no effect when process model is ProcessModelSharedSecondaryProcess.
     
     Vector<RefPtr<WebProcessProxy> > m_processes;
     bool m_haveInitialEmptyProcess;

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (137254 => 137255)


--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp	2012-12-11 07:31:17 UTC (rev 137254)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp	2012-12-11 07:33:01 UTC (rev 137255)
@@ -385,7 +385,7 @@
     if (m_process->context()->processModel() == ProcessModelSharedSecondaryProcess)
         m_process = m_process->context()->ensureSharedWebProcess();
     else
-        m_process = m_process->context()->createNewWebProcess();
+        m_process = m_process->context()->createNewWebProcessRespectingProcessCountLimit();
     m_process->addExistingWebPage(this, m_pageID);
 
     initializeWebPage();

Modified: trunk/Source/WebKit2/UIProcess/mac/WebContextMac.mm (137254 => 137255)


--- trunk/Source/WebKit2/UIProcess/mac/WebContextMac.mm	2012-12-11 07:31:17 UTC (rev 137254)
+++ trunk/Source/WebKit2/UIProcess/mac/WebContextMac.mm	2012-12-11 07:33:01 UTC (rev 137255)
@@ -47,6 +47,7 @@
 NSString *WebKitLocalCacheDefaultsKey = @"WebKitLocalCache";
 NSString *WebStorageDirectoryDefaultsKey = @"WebKitLocalStorageDatabasePathPreferenceKey";
 NSString *WebKitKerningAndLigaturesEnabledByDefaultDefaultsKey = @"WebKitKerningAndLigaturesEnabledByDefault";
+NSString *WebKitWebProcessCountLimitDefaultsKey = @"WebKitWebProcessCountLimit";
 
 static NSString *WebKitApplicationDidChangeAccessibilityEnhancedUserInterfaceNotification = @"NSApplicationDidChangeAccessibilityEnhancedUserInterfaceNotification";
 
@@ -60,6 +61,32 @@
 
 bool WebContext::s_applicationIsOccluded = false;
 
+static void registerUserDefaultsIfNeeded()
+{
+    static bool didRegister;
+    if (didRegister)
+        return;
+
+    didRegister = true;
+    NSMutableDictionary *registrationDictionary = [NSMutableDictionary dictionary];
+    
+    [registrationDictionary setObject:[NSNumber numberWithInteger:INT_MAX] forKey:WebKitWebProcessCountLimitDefaultsKey];
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+    [registrationDictionary setObject:[NSNumber numberWithBool:YES] forKey:WebKitKerningAndLigaturesEnabledByDefaultDefaultsKey];
+#endif
+
+    [[NSUserDefaults standardUserDefaults] registerDefaults:registrationDictionary];
+}
+
+void WebContext::platformInitialize()
+{
+    registerUserDefaultsIfNeeded();
+
+    m_webProcessCountLimit = [[NSUserDefaults standardUserDefaults] integerForKey:WebKitWebProcessCountLimitDefaultsKey];
+    if (m_webProcessCountLimit <= 0)
+        m_webProcessCountLimit = 1;
+}
+
 String WebContext::applicationCacheDirectory()
 {
     NSString *appName = [[NSBundle mainBundle] bundleIdentifier];
@@ -82,18 +109,6 @@
     return [cacheDir stringByAppendingPathComponent:appName];
 }
 
-static void registerUserDefaultsIfNeeded()
-{
-    static bool didRegister;
-    if (didRegister)
-        return;
-
-    didRegister = true;
-#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
-    [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:WebKitKerningAndLigaturesEnabledByDefaultDefaultsKey]];
-#endif
-}
-
 void WebContext::platformInitializeWebProcess(WebProcessCreationParameters& parameters)
 {
     parameters.presenterApplicationPid = getpid();
@@ -102,7 +117,6 @@
     parameters.nsURLCacheMemoryCapacity = [urlCache memoryCapacity];
     parameters.nsURLCacheDiskCapacity = [urlCache diskCapacity];
 
-    registerUserDefaultsIfNeeded();
 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
     parameters.shouldForceScreenFontSubstitution = [[NSUserDefaults standardUserDefaults] boolForKey:@"NSFontDefaultScreenFontSubstitutionEnabled"];
 #endif
@@ -123,7 +137,9 @@
     NSArray *schemes = [[WKBrowsingContextController customSchemes] allObjects];
     for (size_t i = 0; i < [schemes count]; ++i)
         parameters.urlSchemesRegisteredForCustomProtocols.append([schemes objectAtIndex:i]);
-    
+
+    // FIXME(Multi-WebProcess): We register observers for every process that is created, which makes no sense.
+
     m_customSchemeRegisteredObserver = [[NSNotificationCenter defaultCenter] addObserverForName:WebKit::SchemeForCustomProtocolRegisteredNotificationName object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
         NSString *scheme = [notification object];
         ASSERT([scheme isKindOfClass:[NSString class]]);
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to