Changeset 209212 in webkit
- Timestamp:
- Dec 1, 2016 2:31:01 PM (7 years ago)
- Location:
- trunk/Source/WebKit2
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit2/ChangeLog
r209189 r209212 1 2016-12-01 Tim Horton <timothy_horton@apple.com> 2 3 Every WKWebView initialization spends a few milliseconds hitting the disk 4 https://bugs.webkit.org/show_bug.cgi?id=165268 5 <rdar://problem/29010113> 6 7 Reviewed by Brady Eidson. 8 9 Every WKWebView init currently involves doing directory creation and 10 symlink resolution for a number of paths (to create sandbox extensions 11 for all of our storage directories), which means touching the disk a 12 lot during init. All of these paths are immutable per-WebProcessPool, 13 so, instead, cache them on WebProcessPool and create sandbox extensions 14 from the already-resolved paths. This is a sizable (~4x) speedup when 15 initializing subsequent web views. 16 17 * Shared/SandboxExtension.h: 18 (WebKit::SandboxExtension::createHandleWithoutResolvingPath): 19 Add createHandleWithoutResolvingPath, which makes a sandbox extension 20 handle without doing symlink resolution. 21 22 (WebKit::resolvePathForSandboxExtension): 23 (WebKit::resolveAndCreateReadWriteDirectoryForSandboxExtension): 24 Add two functions that do the same resolution that SandboxExtension::createHandle 25 and ::createHandleForReadWriteDirectory do, but just return the paths, 26 for later use with createHandleWithoutResolvingPath. 27 28 * Shared/mac/SandboxExtensionMac.mm: 29 (WebKit::resolveAndCreateReadWriteDirectoryForSandboxExtension): 30 (WebKit::resolvePathForSandboxExtension): 31 (WebKit::SandboxExtension::createHandleWithoutResolvingPath): 32 (WebKit::SandboxExtension::createHandle): 33 (WebKit::SandboxExtension::createHandleForReadWriteDirectory): 34 Implement the aforementioned functions, and reimplement the existing 35 createHandle{ForReadWriteDirectory} functions in terms of them. 36 37 * UIProcess/Cocoa/WebProcessPoolCocoa.mm: 38 (WebKit::WebProcessPool::platformDefaultIconDatabasePath): 39 Stop wasting time generating and resolving a platform default icon 40 database path, since we don't actually use it for anything anymore except 41 to determine whether the icon database is enabled, and we only want to 42 enable it if the client has provided a path. 43 44 (WebKit::WebProcessPool::platformResolvePathsForSandboxExtensions): 45 (WebKit::WebProcessPool::platformInitializeWebProcess): 46 * UIProcess/WebProcessPool.cpp: 47 (WebKit::m_hiddenPageThrottlingTimer): 48 (WebKit::WebProcessPool::resolvePathsForSandboxExtensions): 49 (WebKit::WebProcessPool::createNewWebProcess): 50 * UIProcess/WebProcessPool.h: 51 Resolve paths in resolvePathsForSandboxExtensions, and use the resolved 52 paths along with createHandleWithoutResolvingPath in order to effectively 53 cache the resolution operation. 54 1 55 2016-12-01 Antti Koivisto <antti@apple.com> 2 56 -
trunk/Source/WebKit2/Shared/SandboxExtension.h
r207704 r209212 92 92 93 93 static RefPtr<SandboxExtension> create(const Handle&); 94 static bool createHandle(const String& path, Type type, Handle&); 94 static bool createHandle(const String& path, Type, Handle&); 95 static bool createHandleWithoutResolvingPath(const String& path, Type, Handle&); 95 96 static bool createHandleForReadWriteDirectory(const String& path, Handle&); // Will attempt to create the directory. 96 static String createHandleForTemporaryFile(const String& prefix, Type type, Handle&);97 static String createHandleForTemporaryFile(const String& prefix, Type, Handle&); 97 98 static bool createHandleForGenericExtension(const String& extensionClass, Handle&); 98 99 ~SandboxExtension(); … … 128 129 inline RefPtr<SandboxExtension> SandboxExtension::create(const Handle&) { return nullptr; } 129 130 inline bool SandboxExtension::createHandle(const String&, Type, Handle&) { return true; } 131 inline bool SandboxExtension::createHandleWithoutResolvingPath(const String&, Type, Handle&) { return true; } 130 132 inline bool SandboxExtension::createHandleForReadWriteDirectory(const String&, Handle&) { return true; } 131 133 inline String SandboxExtension::createHandleForTemporaryFile(const String& /*prefix*/, Type, Handle&) {return String();} … … 137 139 inline bool SandboxExtension::consumePermanently(const Handle&) { return true; } 138 140 inline String stringByResolvingSymlinksInPath(const String& path) { return path; } 141 inline String resolvePathForSandboxExtension(const String& path) { return path; } 142 inline String resolveAndCreateReadWriteDirectoryForSandboxExtension(const String& path) { return path; } 139 143 #else 140 144 String stringByResolvingSymlinksInPath(const String& path); 145 String resolvePathForSandboxExtension(const String& path); 146 String resolveAndCreateReadWriteDirectoryForSandboxExtension(const String& path); 141 147 #endif 142 148 -
trunk/Source/WebKit2/Shared/mac/SandboxExtensionMac.mm
r207704 r209212 216 216 } 217 217 218 bool SandboxExtension::createHandle(const String& path, Type type, Handle& handle) 219 { 220 ASSERT(!handle.m_sandboxExtension); 221 218 String resolveAndCreateReadWriteDirectoryForSandboxExtension(const String& path) 219 { 220 NSError *error = nil; 221 NSString *nsPath = path; 222 223 if (![[NSFileManager defaultManager] createDirectoryAtPath:nsPath withIntermediateDirectories:YES attributes:nil error:&error]) { 224 NSLog(@"could not create \"%@\", error %@", nsPath, error); 225 return { }; 226 } 227 228 return resolvePathForSandboxExtension(path); 229 } 230 231 String resolvePathForSandboxExtension(const String& path) 232 { 222 233 // FIXME: Do we need both resolveSymlinksInPath() and -stringByStandardizingPath? 223 234 CString fileSystemPath = fileSystemRepresentation([(NSString *)path stringByStandardizingPath]); 224 235 if (fileSystemPath.isNull()) { 225 236 LOG_ERROR("Could not create a valid file system representation for the string '%s' of length %lu", fileSystemPath.data(), fileSystemPath.length()); 226 return false;237 return { }; 227 238 } 228 239 229 240 CString standardizedPath = resolveSymlinksInPath(fileSystemPath); 230 handle.m_sandboxExtension = WKSandboxExtensionCreate(standardizedPath.data(), wkSandboxExtensionType(type)); 241 return String::fromUTF8(standardizedPath); 242 } 243 244 bool SandboxExtension::createHandleWithoutResolvingPath(const String& path, Type type, Handle& handle) 245 { 246 ASSERT(!handle.m_sandboxExtension); 247 248 handle.m_sandboxExtension = WKSandboxExtensionCreate(path.utf8().data(), wkSandboxExtensionType(type)); 231 249 if (!handle.m_sandboxExtension) { 232 250 LOG_ERROR("Could not create a sandbox extension for '%s'", path.utf8().data()); … … 236 254 } 237 255 256 bool SandboxExtension::createHandle(const String& path, Type type, Handle& handle) 257 { 258 ASSERT(!handle.m_sandboxExtension); 259 260 return createHandleWithoutResolvingPath(resolvePathForSandboxExtension(path), type, handle); 261 } 262 238 263 bool SandboxExtension::createHandleForReadWriteDirectory(const String& path, SandboxExtension::Handle& handle) 239 264 { 240 NSError *error = nil; 241 NSString *nsPath = path; 242 243 if (![[NSFileManager defaultManager] createDirectoryAtPath:nsPath withIntermediateDirectories:YES attributes:nil error:&error]) { 244 NSLog(@"could not create \"%@\", error %@", nsPath, error); 245 return false; 246 } 247 248 return SandboxExtension::createHandle(path, SandboxExtension::ReadWrite, handle); 265 String resolvedPath = resolveAndCreateReadWriteDirectoryForSandboxExtension(path); 266 if (resolvedPath.isNull()) 267 return false; 268 269 return SandboxExtension::createHandleWithoutResolvingPath(resolvedPath, SandboxExtension::ReadWrite, handle); 249 270 } 250 271 -
trunk/Source/WebKit2/UIProcess/Cocoa/WebProcessPoolCocoa.mm
r207812 r209212 160 160 #endif 161 161 162 void WebProcessPool::platformResolvePathsForSandboxExtensions() 163 { 164 m_resolvedPaths.uiProcessBundleResourcePath = resolvePathForSandboxExtension([[NSBundle mainBundle] resourcePath]); 165 166 #if PLATFORM(IOS) 167 m_resolvedPaths.cookieStorageDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(cookieStorageDirectory()); 168 m_resolvedPaths.containerCachesDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(webContentCachesDirectory()); 169 m_resolvedPaths.containerTemporaryDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(containerTemporaryDirectory()); 170 #endif 171 } 172 162 173 void WebProcessPool::platformInitializeWebProcess(WebProcessCreationParameters& parameters) 163 174 { … … 187 198 188 199 // FIXME: This should really be configurable; we shouldn't just blindly allow read access to the UI process bundle. 189 parameters.uiProcessBundleResourcePath = [[NSBundle mainBundle] resourcePath];190 SandboxExtension::createHandle (parameters.uiProcessBundleResourcePath, SandboxExtension::ReadOnly, parameters.uiProcessBundleResourcePathExtensionHandle);200 parameters.uiProcessBundleResourcePath = m_resolvedPaths.uiProcessBundleResourcePath; 201 SandboxExtension::createHandleWithoutResolvingPath(parameters.uiProcessBundleResourcePath, SandboxExtension::ReadOnly, parameters.uiProcessBundleResourcePathExtensionHandle); 191 202 192 203 parameters.uiProcessBundleIdentifier = String([[NSBundle mainBundle] bundleIdentifier]); 204 205 #if PLATFORM(IOS) 206 if (!m_resolvedPaths.cookieStorageDirectory.isEmpty()) 207 SandboxExtension::createHandleWithoutResolvingPath(m_resolvedPaths.cookieStorageDirectory, SandboxExtension::ReadWrite, parameters.cookieStorageDirectoryExtensionHandle); 208 209 if (!m_resolvedPaths.containerCachesDirectory.isEmpty()) 210 SandboxExtension::createHandleWithoutResolvingPath(m_resolvedPaths.containerCachesDirectory, SandboxExtension::ReadWrite, parameters.containerCachesDirectoryExtensionHandle); 211 212 if (!m_resolvedPaths.containerTemporaryDirectory.isEmpty()) 213 SandboxExtension::createHandleWithoutResolvingPath(m_resolvedPaths.containerTemporaryDirectory, SandboxExtension::ReadWrite, parameters.containerTemporaryDirectoryExtensionHandle); 214 #endif 193 215 194 216 parameters.fontWhitelist = m_fontWhitelist; … … 438 460 String WebProcessPool::platformDefaultIconDatabasePath() const 439 461 { 440 // FIXME: <rdar://problem/9138817> - After this "backwards compatibility" radar is removed, this code should be removed to only return an empty String. 441 NSString *databasesDirectory = [[NSUserDefaults standardUserDefaults] objectForKey:WebIconDatabaseDirectoryDefaultsKey]; 442 if (!databasesDirectory || ![databasesDirectory isKindOfClass:[NSString class]]) 443 databasesDirectory = @"~/Library/Icons/WebpageIcons.db"; 444 return stringByResolvingSymlinksInPath([databasesDirectory stringByStandardizingPath]); 462 return ""; 445 463 } 446 464 -
trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp
r208959 r209212 203 203 addLanguageChangeObserver(this, languageChanged); 204 204 205 resolvePathsForSandboxExtensions(); 206 205 207 #if !LOG_DISABLED || !RELEASE_LOG_DISABLED 206 208 WebCore::initializeLogChannelsIfNecessary(); … … 528 530 } 529 531 532 void WebProcessPool::resolvePathsForSandboxExtensions() 533 { 534 m_resolvedPaths.injectedBundlePath = resolvePathForSandboxExtension(injectedBundlePath()); 535 m_resolvedPaths.applicationCacheDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->applicationCacheDirectory()); 536 m_resolvedPaths.webSQLDatabaseDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->webSQLDatabaseDirectory()); 537 m_resolvedPaths.mediaCacheDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->mediaCacheDirectory()); 538 m_resolvedPaths.mediaKeyStorageDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(m_configuration->mediaKeysStorageDirectory()); 539 540 platformResolvePathsForSandboxExtensions(); 541 } 542 530 543 WebProcessProxy& WebProcessPool::createNewWebProcess() 531 544 { … … 538 551 parameters.urlParserEnabled = URLParser::enabled(); 539 552 540 parameters.injectedBundlePath = injectedBundlePath();553 parameters.injectedBundlePath = m_resolvedPaths.injectedBundlePath; 541 554 if (!parameters.injectedBundlePath.isEmpty()) 542 SandboxExtension::createHandle(parameters.injectedBundlePath, SandboxExtension::ReadOnly, parameters.injectedBundlePathExtensionHandle); 543 544 parameters.applicationCacheDirectory = m_configuration->applicationCacheDirectory(); 555 SandboxExtension::createHandleWithoutResolvingPath(parameters.injectedBundlePath, SandboxExtension::ReadOnly, parameters.injectedBundlePathExtensionHandle); 556 557 parameters.applicationCacheDirectory = m_resolvedPaths.applicationCacheDirectory; 558 if (!parameters.applicationCacheDirectory.isEmpty()) 559 SandboxExtension::createHandleWithoutResolvingPath(parameters.applicationCacheDirectory, SandboxExtension::ReadWrite, parameters.applicationCacheDirectoryExtensionHandle); 560 545 561 parameters.applicationCacheFlatFileSubdirectoryName = m_configuration->applicationCacheFlatFileSubdirectoryName(); 546 562 547 if (!parameters.applicationCacheDirectory.isEmpty()) 548 SandboxExtension::createHandleForReadWriteDirectory(parameters.applicationCacheDirectory, parameters.applicationCacheDirectoryExtensionHandle); 549 550 parameters.webSQLDatabaseDirectory = m_configuration->webSQLDatabaseDirectory(); 563 parameters.webSQLDatabaseDirectory = m_resolvedPaths.webSQLDatabaseDirectory; 551 564 if (!parameters.webSQLDatabaseDirectory.isEmpty()) 552 SandboxExtension::createHandle ForReadWriteDirectory(parameters.webSQLDatabaseDirectory, parameters.webSQLDatabaseDirectoryExtensionHandle);553 554 parameters.mediaCacheDirectory = m_ configuration->mediaCacheDirectory();565 SandboxExtension::createHandleWithoutResolvingPath(parameters.webSQLDatabaseDirectory, SandboxExtension::ReadWrite, parameters.webSQLDatabaseDirectoryExtensionHandle); 566 567 parameters.mediaCacheDirectory = m_resolvedPaths.mediaCacheDirectory; 555 568 if (!parameters.mediaCacheDirectory.isEmpty()) 556 SandboxExtension::createHandleForReadWriteDirectory(parameters.mediaCacheDirectory, parameters.mediaCacheDirectoryExtensionHandle); 557 558 #if PLATFORM(IOS) 559 String cookieStorageDirectory = this->cookieStorageDirectory(); 560 if (!cookieStorageDirectory.isEmpty()) 561 SandboxExtension::createHandleForReadWriteDirectory(cookieStorageDirectory, parameters.cookieStorageDirectoryExtensionHandle); 562 563 String containerCachesDirectory = this->webContentCachesDirectory(); 564 if (!containerCachesDirectory.isEmpty()) 565 SandboxExtension::createHandleForReadWriteDirectory(containerCachesDirectory, parameters.containerCachesDirectoryExtensionHandle); 566 567 String containerTemporaryDirectory = this->containerTemporaryDirectory(); 568 if (!containerTemporaryDirectory.isEmpty()) 569 SandboxExtension::createHandleForReadWriteDirectory(containerTemporaryDirectory, parameters.containerTemporaryDirectoryExtensionHandle); 570 #endif 571 572 parameters.mediaKeyStorageDirectory = m_configuration->mediaKeysStorageDirectory(); 569 SandboxExtension::createHandleWithoutResolvingPath(parameters.mediaCacheDirectory, SandboxExtension::ReadWrite, parameters.mediaCacheDirectoryExtensionHandle); 570 571 parameters.mediaKeyStorageDirectory = m_resolvedPaths.mediaKeyStorageDirectory; 573 572 if (!parameters.mediaKeyStorageDirectory.isEmpty()) 574 SandboxExtension::createHandle ForReadWriteDirectory(parameters.mediaKeyStorageDirectory, parameters.mediaKeyStorageDirectoryExtensionHandle);573 SandboxExtension::createHandleWithoutResolvingPath(parameters.mediaKeyStorageDirectory, SandboxExtension::ReadWrite, parameters.mediaKeyStorageDirectoryExtensionHandle); 575 574 576 575 parameters.shouldUseTestingNetworkSession = m_shouldUseTestingNetworkSession; … … 595 594 parameters.shouldUseFontSmoothing = m_shouldUseFontSmoothing; 596 595 597 // FIXME: This leaves UI process and WebProcess disagreeing about the state if the client hasn't set the path.598 // iconDatabasePath is non-empty by default, but m_iconDatabase isn't enabled in UI process unless setDatabasePath is called explicitly.599 596 parameters.iconDatabaseEnabled = !iconDatabasePath().isEmpty(); 600 597 -
trunk/Source/WebKit2/UIProcess/WebProcessPool.h
r208959 r209212 445 445 void setAnyPageGroupMightHavePrivateBrowsingEnabled(bool); 446 446 447 void resolvePathsForSandboxExtensions(); 448 void platformResolvePathsForSandboxExtensions(); 449 447 450 Ref<API::ProcessPoolConfiguration> m_configuration; 448 451 … … 575 578 bool m_cookieStoragePartitioningEnabled { false }; 576 579 #endif 580 581 struct Paths { 582 String injectedBundlePath; 583 String applicationCacheDirectory; 584 String webSQLDatabaseDirectory; 585 String mediaCacheDirectory; 586 String mediaKeyStorageDirectory; 587 String uiProcessBundleResourcePath; 588 589 #if PLATFORM(IOS) 590 String cookieStorageDirectory; 591 String containerCachesDirectory; 592 String containerTemporaryDirectory; 593 #endif 594 }; 595 Paths m_resolvedPaths; 577 596 }; 578 597
Note: See TracChangeset
for help on using the changeset viewer.