Diff
Modified: trunk/LayoutTests/ChangeLog (212844 => 212845)
--- trunk/LayoutTests/ChangeLog 2017-02-22 20:06:57 UTC (rev 212844)
+++ trunk/LayoutTests/ChangeLog 2017-02-22 20:44:30 UTC (rev 212845)
@@ -1,3 +1,19 @@
+2017-02-22 Chris Dumez <[email protected]>
+
+ Do not aggressively throttle DOM timers until they've reached their max nesting level
+ https://bugs.webkit.org/show_bug.cgi?id=168700
+ <rdar://problem/29808005>
+
+ Reviewed by Simon Fraser.
+
+ Add layout test coverage.
+
+ * TestExpectations:
+ * fast/dom/timer-throttling-hidden-page-expected.txt:
+ * fast/dom/timer-throttling-hidden-page-non-nested-expected.txt: Added.
+ * fast/dom/timer-throttling-hidden-page-non-nested.html: Added.
+ * fast/dom/timer-throttling-hidden-page.html:
+
2017-02-22 Antti Koivisto <[email protected]>
REGRESSION(r207669): Crash after mutating selector text
Modified: trunk/LayoutTests/TestExpectations (212844 => 212845)
--- trunk/LayoutTests/TestExpectations 2017-02-22 20:06:57 UTC (rev 212844)
+++ trunk/LayoutTests/TestExpectations 2017-02-22 20:44:30 UTC (rev 212845)
@@ -109,8 +109,6 @@
# media/W3C/video/networkState/networkState_during_progress.html is flaky
webkit.org/b/76280 media/W3C/video/networkState/networkState_during_progress.html [ Pass Failure ]
-webkit.org/b/118301 fast/dom/timer-throttling-hidden-page.html [ Skip ]
-
# This test will run slowly in debug mode, but is plenty fast in release.
[ Debug ] js/slow-stress/emscripten-memops.html [ Skip ]
Modified: trunk/LayoutTests/fast/dom/timer-throttling-hidden-page-expected.txt (212844 => 212845)
--- trunk/LayoutTests/fast/dom/timer-throttling-hidden-page-expected.txt 2017-02-22 20:06:57 UTC (rev 212844)
+++ trunk/LayoutTests/fast/dom/timer-throttling-hidden-page-expected.txt 2017-02-22 20:44:30 UTC (rev 212845)
@@ -3,12 +3,14 @@
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-PASS timerIntervalWhilePageVisible is within 20 of 100
-PASS firstTimerIntervalWhilePageHidden is >= 80
-PASS firstTimerIntervalWhilePageHidden <= 1120 is true
-PASS timerIntervalWhilePageHidden is within 20 of 1000
-PASS timerIntervalWhilePageVisible is within 20 of 100
+PASS timerIntervalWhilePageVisible is within 20 of 10
+PASS timerIntervalWhilePageVisible is within 20 of 10
+PASS timerIntervalWhilePageVisible is within 20 of 10
+PASS timerIntervalWhilePageVisible is within 20 of 10
+PASS timerIntervalWhilePageVisible is within 20 of 10
+PASS timerIntervalWhilePageHidden > (timeoutInterval + tolerance) is true
+PASS timerIntervalWhilePageVisible is within 20 of 10
PASS successfullyParsed is true
TEST COMPLETE
-This test measures the time taken to fire a 100ms DOM Timer when the page visibility is set to "visible", "hidden" and then back to "visible". Due to hidden page timer throttling, the timer should fire close to 1s when page is hidden. And it should fire close to 100ms, when the page is visible.
+This test measures the time taken to fire a 10ms DOM Timer when the page visibility is set to "visible", "hidden" and then back to "visible". Due to hidden page timer throttling, the timer should fire close to s when page is hidden. And it should fire close to 10ms, when the page is visible.
Added: trunk/LayoutTests/fast/dom/timer-throttling-hidden-page-non-nested-expected.txt (0 => 212845)
--- trunk/LayoutTests/fast/dom/timer-throttling-hidden-page-non-nested-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/dom/timer-throttling-hidden-page-non-nested-expected.txt 2017-02-22 20:44:30 UTC (rev 212845)
@@ -0,0 +1,13 @@
+Tests that DOM timers on hidden pages that have not reached max nesting level are not throttled.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS timerIntervalWhilePageVisible is within 20 of 10
+PASS timerIntervalWhilePageVisible is within 20 of 10
+PASS timerIntervalWhilePageVisible is within 20 of 10
+PASS timerIntervalWhilePageVisible is within 20 of 10
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/dom/timer-throttling-hidden-page-non-nested.html (0 => 212845)
--- trunk/LayoutTests/fast/dom/timer-throttling-hidden-page-non-nested.html (rev 0)
+++ trunk/LayoutTests/fast/dom/timer-throttling-hidden-page-non-nested.html 2017-02-22 20:44:30 UTC (rev 212845)
@@ -0,0 +1,58 @@
+<html>
+<head>
+ <script src=""
+ <script>
+ description('Tests that DOM timers on hidden pages that have not reached max nesting level are not throttled.');
+
+ var jsTestIsAsync = true;
+ var previousTime = new Date().getTime();
+ var timerCount = 0;
+ var firstTimerWhileHidden = true;
+ var isPageVisible = true;
+ var timeoutInterval = 10;
+ var tolerance = 20;
+
+ function testTimer()
+ {
+ var date = new Date();
+ var time = date.getTime();
+ timerIntervalWhilePageVisible = time - previousTime;
+ shouldBeCloseTo("timerIntervalWhilePageVisible", timeoutInterval, tolerance);
+
+ timerCount++;
+ previousTime = time;
+
+ if (timerCount == 1) {
+ testRunner.setPageVisibility("hidden");
+ isPageVisible = false;
+ } else if (timerCount == 3) {
+ testRunner.resetPageVisibility();
+ isPageVisible = true;
+ } else if (timerCount > 3){
+ finishJSTest();
+ return;
+ }
+ setTimeout(testTimer, timeoutInterval);
+ }
+
+ function runTest()
+ {
+ if (!window.testRunner) {
+ debug('This test requires testRunner');
+ return;
+ }
+ testRunner.overridePreference("WebKitHiddenPageDOMTimerThrottlingEnabled", 1);
+
+ var timeoutIntervalSpans = document.getElementsByClassName('timeoutInterval');
+ for (var i = 0; i < timeoutIntervalSpans.length; i++)
+ timeoutIntervalSpans[i].innerText = timeoutInterval;
+
+ testRunner.dumpAsText();
+ setTimeout(testTimer, timeoutInterval);
+ }
+ </script>
+</head>
+<body _onload_="runTest()">
+ <script src=""
+</body>
+</html>
Modified: trunk/LayoutTests/fast/dom/timer-throttling-hidden-page.html (212844 => 212845)
--- trunk/LayoutTests/fast/dom/timer-throttling-hidden-page.html 2017-02-22 20:06:57 UTC (rev 212844)
+++ trunk/LayoutTests/fast/dom/timer-throttling-hidden-page.html 2017-02-22 20:44:30 UTC (rev 212845)
@@ -9,26 +9,17 @@
var timerCount = 0;
var firstTimerWhileHidden = true;
var isPageVisible = true;
- var timeoutInterval = 100;
+ var timeoutInterval = 10;
var tolerance = 20;
- var timerAlignmentInterval = 1000;
+ var maxNestingLevel = 5;
function testTimer()
{
var date = new Date();
var time = date.getTime();
- if (!isPageVisible) {
- if (firstTimerWhileHidden) {
- firstTimerIntervalWhilePageHidden = time - previousTime;
- var minValue = timeoutInterval - tolerance;
- shouldBeGreaterThanOrEqual("firstTimerIntervalWhilePageHidden", minValue.toString());
- var maxValue = timeoutInterval + timerAlignmentInterval + tolerance;
- shouldBeTrue("firstTimerIntervalWhilePageHidden <= " + maxValue);
- firstTimerWhileHidden = false;
- } else {
- timerIntervalWhilePageHidden = time - previousTime;
- shouldBeCloseTo("timerIntervalWhilePageHidden", timerAlignmentInterval, tolerance);
- }
+ if (!isPageVisible && timerCount >= maxNestingLevel) {
+ timerIntervalWhilePageHidden = time - previousTime;
+ shouldBeTrue("timerIntervalWhilePageHidden > (timeoutInterval + tolerance)");
} else {
timerIntervalWhilePageVisible = time - previousTime;
shouldBeCloseTo("timerIntervalWhilePageVisible", timeoutInterval, tolerance);
@@ -40,10 +31,10 @@
if (timerCount == 1) {
testRunner.setPageVisibility("hidden");
isPageVisible = false;
- } else if (timerCount == 3) {
+ } else if (timerCount == maxNestingLevel + 1) {
testRunner.resetPageVisibility();
isPageVisible = true;
- } else if (timerCount >= 4){
+ } else if (timerCount > maxNestingLevel + 1){
finishJSTest();
return;
}
@@ -62,8 +53,6 @@
for (var i = 0; i < timeoutIntervalSpans.length; i++)
timeoutIntervalSpans[i].innerText = timeoutInterval;
- document.getElementById('alignmentInterval').innerText = timerAlignmentInterval / 1000;
-
testRunner.dumpAsText();
setTimeout(testTimer, timeoutInterval);
}
Modified: trunk/LayoutTests/platform/ios-simulator/TestExpectations (212844 => 212845)
--- trunk/LayoutTests/platform/ios-simulator/TestExpectations 2017-02-22 20:06:57 UTC (rev 212844)
+++ trunk/LayoutTests/platform/ios-simulator/TestExpectations 2017-02-22 20:44:30 UTC (rev 212845)
@@ -300,6 +300,8 @@
fast/events/mouse-force-up.html [ Skip ]
# testRunner.setPageVisibility is not implemented for iOS
+webkit.org/b/165799 fast/dom/timer-throttling-hidden-page.html [ Skip ]
+webkit.org/b/165799 fast/dom/timer-throttling-hidden-page-non-nested.html [ Skip ]
webkit.org/b/165799 fast/events/page-visibility-onvisibilitychange.html [ Skip ]
webkit.org/b/165799 svg/animations/animations-paused-page-non-visible.html [ Skip ]
Modified: trunk/Source/WebCore/ChangeLog (212844 => 212845)
--- trunk/Source/WebCore/ChangeLog 2017-02-22 20:06:57 UTC (rev 212844)
+++ trunk/Source/WebCore/ChangeLog 2017-02-22 20:44:30 UTC (rev 212845)
@@ -1,3 +1,20 @@
+2017-02-22 Chris Dumez <[email protected]>
+
+ Do not aggressively throttle DOM timers until they've reached their max nesting level
+ https://bugs.webkit.org/show_bug.cgi?id=168700
+ <rdar://problem/29808005>
+
+ Reviewed by Simon Fraser.
+
+ Do not aggressively throttle DOM timers until they've actually areached their max
+ nesting level (5). This overly aggressive throttling of non-nested timers is what
+ was causing Google Maps to use 100% CPU in background tabs for several minutes.
+
+ Test: fast/dom/timer-throttling-hidden-page-non-nested.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::timerAlignmentInterval):
+
2017-02-22 Eric Carlson <[email protected]>
[MediaStream iOS] Respond to capture interruptions and notifications
Modified: trunk/Source/WebCore/dom/Document.cpp (212844 => 212845)
--- trunk/Source/WebCore/dom/Document.cpp 2017-02-22 20:06:57 UTC (rev 212844)
+++ trunk/Source/WebCore/dom/Document.cpp 2017-02-22 20:44:30 UTC (rev 212845)
@@ -2847,9 +2847,11 @@
std::chrono::milliseconds Document::timerAlignmentInterval(bool hasReachedMaxNestingLevel) const
{
auto alignmentInterval = ScriptExecutionContext::timerAlignmentInterval(hasReachedMaxNestingLevel);
+ if (!hasReachedMaxNestingLevel)
+ return alignmentInterval;
// Apply Document-level DOMTimer throttling only if timers have reached their maximum nesting level as the Page may still be visible.
- if (m_isTimerThrottlingEnabled && hasReachedMaxNestingLevel)
+ if (m_isTimerThrottlingEnabled)
alignmentInterval = std::max(alignmentInterval, DOMTimer::hiddenPageAlignmentInterval());
if (Page* page = this->page())