Modified: branches/safari-534.52-branch/Source/WebCore/ChangeLog (98144 => 98145)
--- branches/safari-534.52-branch/Source/WebCore/ChangeLog 2011-10-21 21:04:43 UTC (rev 98144)
+++ branches/safari-534.52-branch/Source/WebCore/ChangeLog 2011-10-21 21:06:33 UTC (rev 98145)
@@ -1,5 +1,26 @@
2011-10-21 Lucas Forschler <[email protected]>
+ Merge 97433
+
+ 2011-10-13 Michael Saboff <[email protected]>
+
+ 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-21 Lucas Forschler <[email protected]>
+
Merge 96874
2011-10-06 Dan Bernstein <[email protected]>
Modified: branches/safari-534.52-branch/Source/WebCore/platform/MemoryPressureHandler.cpp (98144 => 98145)
--- branches/safari-534.52-branch/Source/WebCore/platform/MemoryPressureHandler.cpp 2011-10-21 21:04:43 UTC (rev 98144)
+++ branches/safari-534.52-branch/Source/WebCore/platform/MemoryPressureHandler.cpp 2011-10-21 21:06:33 UTC (rev 98145)
@@ -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: branches/safari-534.52-branch/Source/WebCore/platform/MemoryPressureHandler.h (98144 => 98145)
--- branches/safari-534.52-branch/Source/WebCore/platform/MemoryPressureHandler.h 2011-10-21 21:04:43 UTC (rev 98144)
+++ branches/safari-534.52-branch/Source/WebCore/platform/MemoryPressureHandler.h 2011-10-21 21:06:33 UTC (rev 98145)
@@ -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: branches/safari-534.52-branch/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm (98144 => 98145)
--- branches/safari-534.52-branch/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm 2011-10-21 21:04:43 UTC (rev 98144)
+++ branches/safari-534.52-branch/Source/WebCore/platform/mac/MemoryPressureHandlerMac.mm 2011-10-21 21:06:33 UTC (rev 98145)
@@ -54,12 +54,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(), ^{
@@ -71,14 +76,47 @@
}
});
- notify_register_dispatch("org.WebKit.lowMemory", ¬ifyToken,
+ 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);