Title: [97433] trunk/Source/WebCore
Revision
97433
Author
msab...@apple.com
Date
2011-10-13 18:16:52 -0700 (Thu, 13 Oct 2011)

Log Message

REGRESSION: High frequency memory warnings cause Safari to hog the CPU doing useless garbage collection
https://bugs.webkit.org/show_bug.cgi?id=69774

Throttle the processing of memory pressure events to no more often than once every 5 seconds.

Reviewed by Geoffrey Garen.

No new tests.

* platform/MemoryPressureHandler.cpp:
(WebCore::MemoryPressureHandler::MemoryPressureHandler):
* platform/MemoryPressureHandler.h:
* platform/mac/MemoryPressureHandlerMac.mm:
(WebCore::MemoryPressureHandler::respondToMemoryPressure):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (97432 => 97433)


--- trunk/Source/WebCore/ChangeLog	2011-10-14 01:01:45 UTC (rev 97432)
+++ trunk/Source/WebCore/ChangeLog	2011-10-14 01:16:52 UTC (rev 97433)
@@ -1,3 +1,20 @@
+2011-10-13  Michael Saboff  <msab...@apple.com>
+
+        REGRESSION: High frequency memory warnings cause Safari to hog the CPU doing useless garbage collection
+        https://bugs.webkit.org/show_bug.cgi?id=69774
+
+        Throttle the processing of memory pressure events to no more often than once every 5 seconds.
+
+        Reviewed by Geoffrey Garen.
+
+        No new tests.
+
+        * platform/MemoryPressureHandler.cpp:
+        (WebCore::MemoryPressureHandler::MemoryPressureHandler):
+        * platform/MemoryPressureHandler.h:
+        * platform/mac/MemoryPressureHandlerMac.mm:
+        (WebCore::MemoryPressureHandler::respondToMemoryPressure):
+
 2011-10-13  Kentaro Hara  <hara...@chromium.org>
 
         Implement an OverflowEvent constructor for V8

Modified: trunk/Source/WebCore/platform/MemoryPressureHandler.cpp (97432 => 97433)


--- trunk/Source/WebCore/platform/MemoryPressureHandler.cpp	2011-10-14 01:01:45 UTC (rev 97432)
+++ trunk/Source/WebCore/platform/MemoryPressureHandler.cpp	2011-10-14 01:16:52 UTC (rev 97433)
@@ -38,12 +38,17 @@
 
 MemoryPressureHandler::MemoryPressureHandler() 
     : m_installed(false)
+    , m_lastRespondTime(0)
 {
 }
 
 #if !PLATFORM(MAC) || defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_SNOW_LEOPARD)
 void MemoryPressureHandler::install() { }
 
+void MemoryPressureHandler::uninstall() { }
+
+void MemoryPressureHandler::holdOff(unsigned) { }
+
 void MemoryPressureHandler::respondToMemoryPressure() { }
 #endif
  

Modified: trunk/Source/WebCore/platform/MemoryPressureHandler.h (97432 => 97433)


--- trunk/Source/WebCore/platform/MemoryPressureHandler.h	2011-10-14 01:01:45 UTC (rev 97432)
+++ trunk/Source/WebCore/platform/MemoryPressureHandler.h	2011-10-14 01:16:52 UTC (rev 97433)
@@ -35,7 +35,10 @@
     friend MemoryPressureHandler& memoryPressureHandler();
 
     void install();
+    void uninstall();
 
+    void holdOff(unsigned);
+
 private:
     MemoryPressureHandler();
     ~MemoryPressureHandler();
@@ -43,6 +46,7 @@
     void respondToMemoryPressure();
 
     bool m_installed;
+    time_t m_lastRespondTime;
 };
  
 // Function to obtain the global memory pressure object.

Modified: trunk/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm (97432 => 97433)


--- trunk/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm	2011-10-14 01:01:45 UTC (rev 97432)
+++ trunk/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm	2011-10-14 01:16:52 UTC (rev 97433)
@@ -52,12 +52,17 @@
 #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
 
 static dispatch_source_t _cache_event_source = 0;
+static dispatch_source_t _timer_event_source = 0;
+static int _notifyToken;
 
+// Disable memory event reception for 5 seconds after receiving an event. 
+// This value seems reasonable and testing verifies that it throttles frequent
+// low memory events, greatly reducing CPU usage.
+static const time_t s_secondsBetweenMemoryCleanup = 5;
+
 void MemoryPressureHandler::install()
 {
-    static int notifyToken;
-
-    if (m_installed)
+    if (m_installed || _timer_event_source)
         return;
 
     dispatch_async(dispatch_get_main_queue(), ^{
@@ -69,14 +74,47 @@
         }
     });
 
-    notify_register_dispatch("org.WebKit.lowMemory", &notifyToken,
+    notify_register_dispatch("org.WebKit.lowMemory", &_notifyToken,
          dispatch_get_main_queue(), ^(int) { memoryPressureHandler().respondToMemoryPressure();});
 
     m_installed = true;
 }
 
+void MemoryPressureHandler::uninstall()
+{
+    if (!m_installed)
+        return;
+
+    dispatch_source_cancel(_cache_event_source);
+    _cache_event_source = 0;
+    m_installed = false;
+    
+    notify_cancel(_notifyToken);
+}
+
+void MemoryPressureHandler::holdOff(unsigned seconds)
+{
+    uninstall();
+
+    dispatch_async(dispatch_get_main_queue(), ^{
+        _timer_event_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
+        if (_timer_event_source) {
+            dispatch_set_context(_timer_event_source, this);
+            dispatch_source_set_timer(_timer_event_source, dispatch_time(DISPATCH_TIME_NOW, seconds * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, 1 * s_secondsBetweenMemoryCleanup);
+            dispatch_source_set_event_handler(_timer_event_source, ^{
+                dispatch_source_cancel(_timer_event_source);
+                _timer_event_source = 0;
+                memoryPressureHandler().install();
+            });
+            dispatch_resume(_timer_event_source);
+        }
+    });
+}
+
 void MemoryPressureHandler::respondToMemoryPressure()
 {
+    holdOff(s_secondsBetweenMemoryCleanup);
+
     int savedPageCacheCapacity = pageCache()->capacity();
     pageCache()->setCapacity(pageCache()->pageCount()/2);
     pageCache()->setCapacity(savedPageCacheCapacity);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to