[iOS] WebKit1 should use shared memory pressure handler code.
authorakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Feb 2017 21:04:50 +0000 (21:04 +0000)
committerakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Feb 2017 21:04:50 +0000 (21:04 +0000)
<https://webkit.org/b/168653>

Reviewed by Antti Koivisto.

Source/WebCore:

Remove iOS WebKit1 specific members and code from MemoryPressureHandler in favor
of using the same code that iOS WebKit2 and macOS WebKit uses.

* page/cocoa/MemoryReleaseCocoa.mm:
(WebCore::platformReleaseMemory): Add two cleanup calls that were only in the iOS WebView code.
* platform/MemoryPressureHandler.h:
(WebCore::MemoryPressureHandler::m_releaseMemoryBlock): Deleted.
* platform/cocoa/MemoryPressureHandlerCocoa.mm:
(WebCore::respondToMemoryPressureCallback): Deleted.
(WebCore::MemoryPressureHandler::installMemoryReleaseBlock): Deleted.
(WebCore::MemoryPressureHandler::setReceivedMemoryPressure): Deleted.
(WebCore::MemoryPressureHandler::clearMemoryPressure): Deleted.
(WebCore::MemoryPressureHandler::shouldWaitForMemoryClearMessage): Deleted.
(WebCore::MemoryPressureHandler::respondToMemoryPressureIfNeeded): Deleted.

Source/WebKit/ios:

* Misc/WebUIKitSupport.mm:
(WebKitInitialize): Don't unconditionally install a memory warning handler just
because the framework is loaded.

Source/WebKit/mac:

Register a WebThread-aware memory callback with the shared MemoryPressureHandler
and get rid of the old iOS WebKit1 specific implementation. Some of it was even
dead code since MobileSafari has been using WebKit2 for quite a while.

* WebView/WebView.h:
* WebView/WebView.mm:
(WebInstallMemoryPressureHandler):
(+[WebView _handleMemoryWarning]): Deleted.
(+[WebView registerForMemoryNotifications]): Deleted.
(+[WebView releaseFastMallocMemoryOnCurrentThread]): Deleted.
(+[WebView garbageCollectNow]): Deleted.
(+[WebView purgeInactiveFontData]): Deleted.
(+[WebView drainLayerPool]): Deleted.
(+[WebView discardAllCompiledCode]): Deleted.
(+[WebView _clearMemoryPressure]): Deleted.
(+[WebView _shouldWaitForMemoryClearMessage]): Deleted.
* WebView/WebViewPrivate.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@212742 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/page/cocoa/MemoryReleaseCocoa.mm
Source/WebCore/platform/MemoryPressureHandler.h
Source/WebCore/platform/cocoa/MemoryPressureHandlerCocoa.mm
Source/WebKit/ios/ChangeLog
Source/WebKit/ios/Misc/WebUIKitSupport.mm
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebView/WebView.h
Source/WebKit/mac/WebView/WebView.mm
Source/WebKit/mac/WebView/WebViewPrivate.h

index ba44b87..b951d7b 100644 (file)
@@ -1,3 +1,25 @@
+2017-02-21  Andreas Kling  <akling@apple.com>
+
+        [iOS] WebKit1 should use shared memory pressure handler code.
+        <https://webkit.org/b/168653>
+
+        Reviewed by Antti Koivisto.
+
+        Remove iOS WebKit1 specific members and code from MemoryPressureHandler in favor
+        of using the same code that iOS WebKit2 and macOS WebKit uses.
+
+        * page/cocoa/MemoryReleaseCocoa.mm:
+        (WebCore::platformReleaseMemory): Add two cleanup calls that were only in the iOS WebView code.
+        * platform/MemoryPressureHandler.h:
+        (WebCore::MemoryPressureHandler::m_releaseMemoryBlock): Deleted.
+        * platform/cocoa/MemoryPressureHandlerCocoa.mm:
+        (WebCore::respondToMemoryPressureCallback): Deleted.
+        (WebCore::MemoryPressureHandler::installMemoryReleaseBlock): Deleted.
+        (WebCore::MemoryPressureHandler::setReceivedMemoryPressure): Deleted.
+        (WebCore::MemoryPressureHandler::clearMemoryPressure): Deleted.
+        (WebCore::MemoryPressureHandler::shouldWaitForMemoryClearMessage): Deleted.
+        (WebCore::MemoryPressureHandler::respondToMemoryPressureIfNeeded): Deleted.
+
 2017-02-21  Anders Carlsson  <andersca@apple.com>
 
         Fix two failing WebKit legacy tests
index 44eccee..495b811 100644 (file)
 #import "LayerPool.h"
 #import <notify.h>
 
+#if PLATFORM(IOS)
+#import "LegacyTileCache.h"
+#import "TileControllerMemoryHandlerIOS.h"
+#endif
+
+
 extern "C" void _sqlite3_purgeEligiblePagerCacheMemory(void);
 
 namespace WebCore {
@@ -47,6 +53,11 @@ void platformReleaseMemory(Critical)
     for (auto& pool : LayerPool::allLayerPools())
         pool->drain();
 
+#if PLATFORM(IOS)
+    LegacyTileCache::drainLayerPool();
+    tileControllerMemoryHandler().trimUnparentedTilesToTarget(0);
+#endif
+
 #if USE(IOSURFACE)
     IOSurfacePool::sharedPool().discardAllSurfaces();
 #endif
index 028ac8c..93cd4d8 100644 (file)
 #include <wtf/Optional.h>
 #include <wtf/RunLoop.h>
 
-#if PLATFORM(IOS)
-#include <wtf/Lock.h>
-#include <wtf/ThreadingPrimitives.h>
-#endif
-
 #if USE(GLIB)
 #include <wtf/glib/GRefPtr.h>
 #endif
 
 namespace WebCore {
 
-#if PLATFORM(IOS)
-enum MemoryPressureReason {
-    MemoryPressureReasonNone = 0 << 0,
-    MemoryPressureReasonVMPressure = 1 << 0,
-    MemoryPressureReasonVMStatus = 1 << 1,
-};
-#endif
-
 enum class MemoryUsagePolicy {
     Unrestricted, // Allocate as much as you want
     Conservative, // Maybe you don't cache every single thing
@@ -95,14 +82,7 @@ public:
     }
     void setUnderMemoryPressure(bool b) { m_underMemoryPressure = b; }
 
-#if PLATFORM(IOS)
-    // FIXME: Can we share more of this with OpenSource?
-    WEBCORE_EXPORT void installMemoryReleaseBlock(void (^releaseMemoryBlock)(), bool clearPressureOnMemoryRelease = true);
-    WEBCORE_EXPORT void setReceivedMemoryPressure(MemoryPressureReason);
-    WEBCORE_EXPORT void clearMemoryPressure();
-    WEBCORE_EXPORT bool shouldWaitForMemoryClearMessage();
-    void respondToMemoryPressureIfNeeded();
-#elif OS(LINUX)
+#if OS(LINUX)
     void setMemoryPressureMonitorHandle(int fd);
 #endif
 
@@ -202,14 +182,7 @@ private:
     WTF::Function<void()> m_memoryKillCallback;
     WTF::Function<bool()> m_processIsEligibleForMemoryKillCallback;
 
-#if PLATFORM(IOS)
-    // FIXME: Can we share more of this with OpenSource?
-    uint32_t m_memoryPressureReason { MemoryPressureReasonNone };
-    bool m_clearPressureOnMemoryRelease { true };
-    void (^m_releaseMemoryBlock)() { nullptr };
-    CFRunLoopObserverRef m_observer { nullptr };
-    Lock m_observerMutex;
-#elif OS(LINUX)
+#if OS(LINUX)
     std::optional<int> m_eventFD;
     std::optional<int> m_pressureLevelFD;
     std::unique_ptr<EventFDPoller> m_eventFDPoller;
index bffdd32..d8dd677 100644 (file)
@@ -197,73 +197,4 @@ std::optional<MemoryPressureHandler::ReliefLogger::MemoryUsage> MemoryPressureHa
     return MemoryUsage {static_cast<size_t>(vmInfo.internal), static_cast<size_t>(vmInfo.phys_footprint)};
 }
 
-#if PLATFORM(IOS)
-static void respondToMemoryPressureCallback(CFRunLoopObserverRef observer, CFRunLoopActivity /*activity*/, void* /*info*/)
-{
-    MemoryPressureHandler::singleton().respondToMemoryPressureIfNeeded();
-    CFRunLoopObserverInvalidate(observer);
-    CFRelease(observer);
-}
-
-void MemoryPressureHandler::installMemoryReleaseBlock(void (^releaseMemoryBlock)(), bool clearPressureOnMemoryRelease)
-{
-    if (m_installed)
-        return;
-    m_releaseMemoryBlock = Block_copy(releaseMemoryBlock);
-    m_clearPressureOnMemoryRelease = clearPressureOnMemoryRelease;
-    m_installed = true;
-}
-
-void MemoryPressureHandler::setReceivedMemoryPressure(MemoryPressureReason reason)
-{
-    m_underMemoryPressure = true;
-
-    {
-        LockHolder locker(m_observerMutex);
-        if (!m_observer) {
-            m_observer = CFRunLoopObserverCreate(NULL, kCFRunLoopBeforeWaiting | kCFRunLoopExit, NO /* don't repeat */,
-                0, WebCore::respondToMemoryPressureCallback, NULL);
-            CFRunLoopAddObserver(WebThreadRunLoop(), m_observer, kCFRunLoopCommonModes);
-            CFRunLoopWakeUp(WebThreadRunLoop());
-        }
-        m_memoryPressureReason |= reason;
-    }
-}
-
-void MemoryPressureHandler::clearMemoryPressure()
-{
-    m_underMemoryPressure = false;
-
-    {
-        LockHolder locker(m_observerMutex);
-        m_memoryPressureReason = MemoryPressureReasonNone;
-    }
-}
-
-bool MemoryPressureHandler::shouldWaitForMemoryClearMessage()
-{
-    LockHolder locker(m_observerMutex);
-    return m_memoryPressureReason & MemoryPressureReasonVMStatus;
-}
-
-void MemoryPressureHandler::respondToMemoryPressureIfNeeded()
-{
-    ASSERT(WebThreadIsLockedOrDisabled());
-
-    {
-        LockHolder locker(m_observerMutex);
-        m_observer = 0;
-    }
-
-    if (isUnderMemoryPressure()) {
-        ASSERT(m_releaseMemoryBlock);
-        LOG(MemoryPressure, "Handle memory pressure at %s", __PRETTY_FUNCTION__);
-        m_releaseMemoryBlock();
-        if (m_clearPressureOnMemoryRelease)
-            clearMemoryPressure();
-    }
-}
-
-#endif
-
 } // namespace WebCore
index af9671a..0a42670 100644 (file)
@@ -1,3 +1,14 @@
+2017-02-21  Andreas Kling  <akling@apple.com>
+
+        [iOS] WebKit1 should use shared memory pressure handler code.
+        <https://webkit.org/b/168653>
+
+        Reviewed by Antti Koivisto.
+
+        * Misc/WebUIKitSupport.mm:
+        (WebKitInitialize): Don't unconditionally install a memory warning handler just
+        because the framework is loaded.
+
 2017-02-20  Alexey Proskuryakov  <ap@apple.com>
 
         List of WebCore symbols to re-export from WebKitLegacy should be built automatically
index 6fc6224..1f25675 100644 (file)
@@ -87,7 +87,6 @@ void WebKitInitialize(void)
     // We'd rather eat this cost at startup than slow down situations that need to be responsive.
     // See <rdar://problem/6776301>.
     LoadWebLocalizedStrings();
-    [WebView registerForMemoryNotifications];
     
     // This needs to be called before any requests are made in the process, <rdar://problem/9691871>
     WebCore::initializeHTTPConnectionSettingsOnStartup();
index c07185a..df71261 100644 (file)
@@ -1,3 +1,28 @@
+2017-02-21  Andreas Kling  <akling@apple.com>
+
+        [iOS] WebKit1 should use shared memory pressure handler code.
+        <https://webkit.org/b/168653>
+
+        Reviewed by Antti Koivisto.
+
+        Register a WebThread-aware memory callback with the shared MemoryPressureHandler
+        and get rid of the old iOS WebKit1 specific implementation. Some of it was even
+        dead code since MobileSafari has been using WebKit2 for quite a while.
+
+        * WebView/WebView.h:
+        * WebView/WebView.mm:
+        (WebInstallMemoryPressureHandler):
+        (+[WebView _handleMemoryWarning]): Deleted.
+        (+[WebView registerForMemoryNotifications]): Deleted.
+        (+[WebView releaseFastMallocMemoryOnCurrentThread]): Deleted.
+        (+[WebView garbageCollectNow]): Deleted.
+        (+[WebView purgeInactiveFontData]): Deleted.
+        (+[WebView drainLayerPool]): Deleted.
+        (+[WebView discardAllCompiledCode]): Deleted.
+        (+[WebView _clearMemoryPressure]): Deleted.
+        (+[WebView _shouldWaitForMemoryClearMessage]): Deleted.
+        * WebView/WebViewPrivate.h:
+
 2017-02-20  Aakash Jain  <aakash_jain@apple.com>
 
         Stop exporting interface WebCoreScrollView on iOS
index e56631c..e089b6c 100644 (file)
@@ -746,12 +746,6 @@ a custom implementation for each.
 
 @interface WebView (WebViewIOS)
 + (void)enableWebThread;
-+ (void)garbageCollectNow;
-+ (void)purgeInactiveFontData;
-+ (void)drainLayerPool;
-+ (void)discardAllCompiledCode;
-+ (void)registerForMemoryNotifications;
-+ (void)releaseFastMallocMemoryOnCurrentThread;
 + (BOOL)isCharacterSmartReplaceExempt:(unichar)character isPreviousCharacter:(BOOL)b;
 
 /*!
index c4667bf..070d035 100644 (file)
@@ -1673,73 +1673,10 @@ static void WebKitInitializeGamepadProviderIfNecessary()
     return self;
 }
 
-+ (void)_handleMemoryWarning
-{
-    ASSERT(WebThreadIsCurrent());
-    WebKit::MemoryMeasure totalMemory("Memory warning: Overall memory change from [WebView _handleMemoryWarning].");
-
-    // Always peform the following.
-    [WebView purgeInactiveFontData];
-
-    // Only perform the remaining if a non-simple document was created.
-    if (!didOneTimeInitialization)
-        return;
-
-    tileControllerMemoryHandler().trimUnparentedTilesToTarget(0);
-
-    [WebStorageManager closeIdleLocalStorageDatabases];
-    StorageThread::releaseFastMallocFreeMemoryInAllThreads();
-
-    [WebView _releaseMemoryNow];
-}
-
-+ (void)registerForMemoryNotifications
-{
-    BOOL shouldAutoClearPressureOnMemoryRelease = !WebCore::IOSApplication::isMobileSafari();
-
-    MemoryPressureHandler::singleton().installMemoryReleaseBlock(^{
-        [WebView _handleMemoryWarning];
-    }, shouldAutoClearPressureOnMemoryRelease);
-
-    static dispatch_source_t memoryNotificationEventSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0, DISPATCH_MEMORYPRESSURE_WARN, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
-    dispatch_source_set_event_handler(memoryNotificationEventSource, ^{
-        // Set memory pressure flag and schedule releasing memory in web thread runloop exit.
-        MemoryPressureHandler::singleton().setReceivedMemoryPressure(WebCore::MemoryPressureReasonVMPressure);
-    });
-
-    dispatch_resume(memoryNotificationEventSource);
-
-    if (!shouldAutoClearPressureOnMemoryRelease) {
-        // Listen to memory status notification to reset the memory pressure flag.
-        static dispatch_source_t memoryStatusEventSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYPRESSURE,
-                                                                                    0,
-                                                                                    DISPATCH_MEMORYPRESSURE_WARN | DISPATCH_MEMORYPRESSURE_NORMAL,
-                                                                                    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
-        dispatch_source_set_event_handler(memoryStatusEventSource, ^{
-            unsigned long currentStatus = dispatch_source_get_data(memoryStatusEventSource);
-            if (currentStatus == DISPATCH_MEMORYPRESSURE_NORMAL)
-                MemoryPressureHandler::singleton().clearMemoryPressure();
-            else if (currentStatus == DISPATCH_MEMORYPRESSURE_WARN)
-                MemoryPressureHandler::singleton().setReceivedMemoryPressure(WebCore::MemoryPressureReasonVMStatus);
-        });
-
-        dispatch_resume(memoryStatusEventSource);
-    }
-}
-
 + (void)_releaseMemoryNow
 {
-    ASSERT(WebThreadIsCurrent());
-    [WebView discardAllCompiledCode];
-    [WebView garbageCollectNow];
-    [WebView purgeInactiveFontData];
-    [WebView drainLayerPool];
-    [WebCache emptyInMemoryResources];
-    [WebView releaseFastMallocMemoryOnCurrentThread];
-
-    dispatch_async(dispatch_get_main_queue(), ^{
-        // Clear the main thread's TCMalloc thread cache.
-        [WebView releaseFastMallocMemoryOnCurrentThread];
+    WebThreadRun(^{
+        WebCore::releaseMemory(Critical::Yes, Synchronous::Yes);
     });
 }
 
@@ -1758,40 +1695,6 @@ static void WebKitInitializeGamepadProviderIfNecessary()
     });
 }
 
-+ (void)releaseFastMallocMemoryOnCurrentThread
-{
-    WebKit::MemoryMeasure measurer("Memory warning: Releasing fast malloc memory to system.");
-    WTF::releaseFastMallocFreeMemory();
-}
-
-+ (void)garbageCollectNow
-{
-    ASSERT(WebThreadIsCurrent());
-    WebKit::MemoryMeasure measurer("Memory warning: Calling JavaScript GC.");
-    WebCore::GCController::singleton().garbageCollectNow();
-}
-
-+ (void)purgeInactiveFontData
-{
-    ASSERT(WebThreadIsCurrent());
-    WebKit::MemoryMeasure measurer("Memory warning: Purging inactive font data.");
-    FontCache::singleton().purgeInactiveFontData();
-}
-
-+ (void)drainLayerPool
-{
-    ASSERT(WebThreadIsCurrent());
-    WebKit::MemoryMeasure measurer("Memory warning: Draining layer pool.");
-    WebCore::LegacyTileCache::drainLayerPool();
-}
-
-+ (void)discardAllCompiledCode
-{
-    ASSERT(WebThreadIsCurrent());
-    WebKit::MemoryMeasure measurer("Memory warning: Discarding JIT'ed code.");
-    WebCore::GCController::singleton().deleteAllCode(PreventCollectionAndDeleteAllCode);
-}
-
 + (BOOL)isCharacterSmartReplaceExempt:(unichar)character isPreviousCharacter:(BOOL)b
 {
     return WebCore::isCharacterSmartReplaceExempt(character, b);
@@ -2043,16 +1946,6 @@ static NSMutableSet *knownPluginMIMETypes()
     return MemoryPressureHandler::singleton().isUnderMemoryPressure();
 }
 
-+ (void)_clearMemoryPressure
-{
-    MemoryPressureHandler::singleton().clearMemoryPressure();
-}
-
-+ (BOOL)_shouldWaitForMemoryClearMessage
-{
-    return MemoryPressureHandler::singleton().shouldWaitForMemoryClearMessage();
-}
-
 #endif // PLATFORM(IOS)
 
 - (void)_closePluginDatabases
@@ -9952,7 +9845,13 @@ void WebInstallMemoryPressureHandler(void)
         std::call_once(onceFlag, [] {
             auto& memoryPressureHandler = MemoryPressureHandler::singleton();
             memoryPressureHandler.setLowMemoryHandler([] (Critical critical, Synchronous synchronous) {
+#if PLATFORM(IOS)
+                WebThreadRun(^{
+#endif
                 WebCore::releaseMemory(critical, synchronous);
+#if PLATFORM(IOS)
+                });
+#endif
             });
             memoryPressureHandler.install();
         });
index b739c3e..5dac4bb 100644 (file)
@@ -441,21 +441,11 @@ Could be worth adding to the API.
 
 - (NSUInteger)_renderTreeSize;
 
-/*!
- * @method _handleMemoryWarning
- * @discussion Try to release memory since we got a memory warning from the system. This method is
- * also used by other internal clients. See <rdar://9582500>.
- */
-+ (void)_handleMemoryWarning;
-
 - (void)_setResourceLoadSchedulerSuspended:(BOOL)suspend;
 + (void)_setTileCacheLayerPoolCapacity:(unsigned)capacity;
 
 + (void)_setAllowCookies:(BOOL)allow;
 + (BOOL)_allowCookies;
-+ (BOOL)_isUnderMemoryPressure;
-+ (void)_clearMemoryPressure;
-+ (BOOL)_shouldWaitForMemoryClearMessage;
 + (void)_releaseMemoryNow;
 
 - (void)_replaceCurrentHistoryItem:(WebHistoryItem *)item;