Title: [231041] trunk/Source/WebKit
Revision
231041
Author
[email protected]
Date
2018-04-25 20:33:58 -0700 (Wed, 25 Apr 2018)

Log Message

dlopen the bundle's executable before calling -[NSBundle load] since that will also do a bunch of other things we don't need
https://bugs.webkit.org/show_bug.cgi?id=184904

Reviewed by Geoffrey Garen.

Loading an NSBundle does a lot of work to find the principal class inside
the bundle. This means it walks all the objective C class names loaded
by the bundle. Doing this is *really* expensive.

Some users of the injected bundle define a WKBundleInitialize function.
In such a case, we don't need the principal class, so we can skip loading
the NSBundle. Now, before we load the bundle, we dlopen and dlsym looking
for the WKBundleInitialize function. If we find it, we skip loading
the bundle. If we don't find the WKBundleInitialize function, we fall
back to loading the bundle and finding the principal class.

This speeds up initializeWebProcess by ~70ms on my MBP.

* WebProcess/InjectedBundle/mac/InjectedBundleMac.mm:
(WebKit::InjectedBundle::initialize):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (231040 => 231041)


--- trunk/Source/WebKit/ChangeLog	2018-04-26 03:21:55 UTC (rev 231040)
+++ trunk/Source/WebKit/ChangeLog	2018-04-26 03:33:58 UTC (rev 231041)
@@ -1,3 +1,26 @@
+2018-04-25  Saam Barati  <[email protected]>
+
+        dlopen the bundle's executable before calling -[NSBundle load] since that will also do a bunch of other things we don't need
+        https://bugs.webkit.org/show_bug.cgi?id=184904
+
+        Reviewed by Geoffrey Garen.
+
+        Loading an NSBundle does a lot of work to find the principal class inside
+        the bundle. This means it walks all the objective C class names loaded
+        by the bundle. Doing this is *really* expensive.
+        
+        Some users of the injected bundle define a WKBundleInitialize function.
+        In such a case, we don't need the principal class, so we can skip loading
+        the NSBundle. Now, before we load the bundle, we dlopen and dlsym looking
+        for the WKBundleInitialize function. If we find it, we skip loading
+        the bundle. If we don't find the WKBundleInitialize function, we fall
+        back to loading the bundle and finding the principal class.
+        
+        This speeds up initializeWebProcess by ~70ms on my MBP.
+
+        * WebProcess/InjectedBundle/mac/InjectedBundleMac.mm:
+        (WebKit::InjectedBundle::initialize):
+
 2018-04-25  Youenn Fablet  <[email protected]>
 
         Use NetworkLoadChecker for all subresource loads except fetch/XHR

Modified: trunk/Source/WebKit/WebProcess/InjectedBundle/mac/InjectedBundleMac.mm (231040 => 231041)


--- trunk/Source/WebKit/WebProcess/InjectedBundle/mac/InjectedBundleMac.mm	2018-04-26 03:21:55 UTC (rev 231040)
+++ trunk/Source/WebKit/WebProcess/InjectedBundle/mac/InjectedBundleMac.mm	2018-04-26 03:33:58 UTC (rev 231041)
@@ -33,7 +33,9 @@
 #import "WKWebProcessBundleParameters.h"
 #import "WKWebProcessPlugInInternal.h"
 #import "WebProcessCreationParameters.h"
+#import <CoreFoundation/CFURL.h>
 #import <Foundation/NSBundle.h>
+#import <dlfcn.h>
 #import <pal/spi/cocoa/NSKeyedArchiverSPI.h>
 #import <stdio.h>
 #import <wtf/RetainPtr.h>
@@ -76,10 +78,23 @@
         WTFLogAlways("InjectedBundle::load failed - Could not create the bundle.\n");
         return false;
     }
+
+    WKBundleInitializeFunctionPtr initializeFunction = nullptr;
+    if (RetainPtr<CFURLRef> executableURL = adoptCF(CFBundleCopyExecutableURL([m_platformBundle _cfBundle]))) {
+        static constexpr size_t maxPathSize = 4096;
+        char pathToExecutable[maxPathSize];
+        if (CFURLGetFileSystemRepresentation(executableURL.get(), true, bitwise_cast<uint8_t*>(pathToExecutable), maxPathSize)) {
+            // We don't hold onto this handle anywhere more permanent since we never dlcose.
+            if (void* handle = dlopen(pathToExecutable, RTLD_LAZY | RTLD_GLOBAL | RTLD_FIRST))
+                initializeFunction = bitwise_cast<WKBundleInitializeFunctionPtr>(dlsym(handle, "WKBundleInitialize"));
+        }
+    }
         
-    if (![m_platformBundle load]) {
-        WTFLogAlways("InjectedBundle::load failed - Could not load the executable from the bundle.\n");
-        return false;
+    if (!initializeFunction) {
+        if (![m_platformBundle load]) {
+            WTFLogAlways("InjectedBundle::load failed - Could not load the executable from the bundle.\n");
+            return false;
+        }
     }
 
 #if WK_API_ENABLED
@@ -100,9 +115,11 @@
         m_bundleParameters = adoptNS([[WKWebProcessBundleParameters alloc] initWithDictionary:dictionary]);
     }
 #endif
+    
+    if (!initializeFunction)
+        initializeFunction = bitwise_cast<WKBundleInitializeFunctionPtr>(CFBundleGetFunctionPointerForName([m_platformBundle _cfBundle], CFSTR("WKBundleInitialize")));
 
     // First check to see if the bundle has a WKBundleInitialize function.
-    WKBundleInitializeFunctionPtr initializeFunction = reinterpret_cast<WKBundleInitializeFunctionPtr>(CFBundleGetFunctionPointerForName([m_platformBundle _cfBundle], CFSTR("WKBundleInitialize")));
     if (initializeFunction) {
         initializeFunction(toAPI(this), toAPI(initializationUserData));
         return true;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to