Changeset 176496 in webkit
- Timestamp:
- Nov 21, 2014, 7:29:58 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 10 edited
- 1 moved
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/fast/dom/resources/frame-with-throttled-timer-animating-element-other-document.html (moved) (moved from trunk/LayoutTests/fast/dom/resources/frame-with-throttled-timer.html ) (1 diff)
-
LayoutTests/fast/dom/resources/frame-with-throttled-timer-animating-element-same-document.html (added)
-
LayoutTests/fast/dom/throttled-timer-running-on-document-destruction.html (modified) (2 diffs)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/dom/Element.cpp (modified) (1 diff)
-
Source/WebCore/dom/Element.h (modified) (1 diff)
-
Source/WebCore/dom/ElementRareData.cpp (modified) (1 diff)
-
Source/WebCore/dom/ElementRareData.h (modified) (5 diffs)
-
Source/WebCore/dom/Node.cpp (modified) (1 diff)
-
Source/WebCore/page/DOMTimer.cpp (modified) (2 diffs)
-
Source/WebCore/page/DOMTimer.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r176490 r176496 1 2014-11-21 Chris Dumez <cdumez@apple.com> 2 3 Throttled DOMTimers can prevent their document from being garbage collected 4 https://bugs.webkit.org/show_bug.cgi?id=138915 5 6 Reviewed by Andreas Kling. 7 8 Improve fast/dom/throttled-timer-running-on-document-destruction.html 9 layout test to cover the case where the throttled timer is changing the 10 style of an element on the *same* document when the document is 11 destroyed. 12 13 * fast/dom/resources/frame-with-throttled-timer-animating-element-other-document.html: Renamed from LayoutTests/fast/dom/resources/frame-with-throttled-timer.html. 14 * fast/dom/resources/frame-with-throttled-timer-animating-element-same-document.html: Added. 15 * fast/dom/throttled-timer-running-on-document-destruction.html: 16 1 17 2014-11-21 Chris Dumez <cdumez@apple.com> 2 18 -
trunk/LayoutTests/fast/dom/resources/frame-with-throttled-timer-animating-element-other-document.html
r176495 r176496 10 10 var testElement = testFrame.contentDocument.getElementById("testElement"); 11 11 testElement.style["left"] = "" + Math.floor((Math.random() * 10) + 1) + "px"; 12 }, 5);12 }, 0); 13 13 </script> 14 14 </body> -
trunk/LayoutTests/fast/dom/throttled-timer-running-on-document-destruction.html
r176402 r176496 2 2 <body> 3 3 <script src="../../resources/js-test-pre.js"></script> 4 <iframe id="testFrame" src="resources/frame-with-throttled-timer.html"></iframe>5 6 4 <script> 7 5 description("Test that we don't crash if a throttled timer is still running when the document is destroyed."); 8 6 jsTestIsAsync = true; 9 7 10 function removeFrame() 8 var frameLoadedCount = 0; 9 10 function removeFrames() 11 11 { 12 document.body.removeChild(document.getElementById("testFrame")); 12 document.body.removeChild(document.getElementById("testFrame1")); 13 document.body.removeChild(document.getElementById("testFrame2")); 13 14 gc(); 14 15 testPassed("Did not crash."); … … 16 17 } 17 18 18 setTimeout(removeFrame, 300); 19 function frameLoaded() 20 { 21 ++frameLoadedCount; 22 if (frameLoadedCount == 2) 23 setTimeout(removeFrames, 100); 24 } 19 25 20 26 </script> 27 <iframe id="testFrame1" src="resources/frame-with-throttled-timer-animating-element-same-document.html" onload="frameLoaded()"></iframe> 28 <iframe id="testFrame2" src="resources/frame-with-throttled-timer-animating-element-other-document.html" onload="frameLoaded()"></iframe> 29 21 30 <script src="../../resources/js-test-post.js"></script> 22 31 </body> -
trunk/Source/WebCore/ChangeLog
r176495 r176496 1 2014-11-21 Chris Dumez <cdumez@apple.com> 2 3 Throttled DOMTimers can prevent their document from being garbage collected 4 https://bugs.webkit.org/show_bug.cgi?id=138915 5 6 Reviewed by Andreas Kling. 7 8 Throttled DOMTimers whose interval depend on viewport changes would 9 keep a Vector of elements outside viewport causing them to be throttled 10 so that we could check later on (upon scroll or layout) if those 11 elements are still outside viewport. The issue is that these elements 12 could potentially be removed from the document (and destroyed) after 13 the timer has fired. To handle this, DOMTimer was ref'ing the 14 elements. Unfortunately, this was causing us to leak the document 15 as the elements in the Vector would keep the document alive. 16 17 To handle this issue, this patch updates the DOMTimer Vector to use 18 weak pointers. The WeakPtrFactory is stored in ElementRareData to 19 avoid wasting memory for all kinds of Elements (it is a fair assumption 20 that the number of elements whose style is animated via timers is low). 21 22 Test: fast/dom/throttled-timer-running-on-document-destruction.html 23 24 * dom/Element.cpp: 25 (WebCore::Element::createWeakPtr): 26 * dom/Element.h: 27 * dom/ElementRareData.cpp: 28 * dom/ElementRareData.h: 29 (WebCore::ElementRareData::weakPtrFactory): 30 * page/DOMTimer.cpp: 31 (WebCore::DOMTimerFireState::elementsChangedOutsideViewport): 32 (WebCore::DOMTimer::updateThrottlingStateAfterViewportChange): 33 * page/DOMTimer.h: 34 1 35 2014-11-21 Gyuyoung Kim <gyuyoung.kim@samsung.com> 2 36 -
trunk/Source/WebCore/dom/Element.cpp
r176212 r176496 1196 1196 } 1197 1197 1198 WeakPtr<Element> Element::createWeakPtr() 1199 { 1200 return ensureElementRareData().weakPtrFactory().createWeakPtr(); 1201 } 1202 1198 1203 // Returns true is the given attribute is an event handler. 1199 1204 // We consider an event handler any attribute that begins with "on". -
trunk/Source/WebCore/dom/Element.h
r176212 r176496 552 552 553 553 WEBCORE_EXPORT URL absoluteLinkURL() const; 554 WeakPtr<Element> createWeakPtr(); 554 555 555 556 protected: -
trunk/Source/WebCore/dom/ElementRareData.cpp
r173234 r176496 40 40 LayoutSize sizeForResizing; 41 41 IntSize scrollOffset; 42 void* pointers[ 7];42 void* pointers[8]; 43 43 }; 44 44 -
trunk/Source/WebCore/dom/ElementRareData.h
r176084 r176496 37 37 class ElementRareData : public NodeRareData { 38 38 public: 39 explicit ElementRareData(RenderElement*);39 ElementRareData(Element&, RenderElement*); 40 40 ~ElementRareData(); 41 41 … … 114 114 bool hasPendingResources() const { return m_hasPendingResources; } 115 115 void setHasPendingResources(bool has) { m_hasPendingResources = has; } 116 117 WeakPtrFactory<Element>& weakPtrFactory() { return m_weakPtrFactory; } 116 118 117 119 private: … … 148 150 RefPtr<PseudoElement> m_beforePseudoElement; 149 151 RefPtr<PseudoElement> m_afterPseudoElement; 152 WeakPtrFactory<Element> m_weakPtrFactory; 150 153 151 154 void releasePseudoElement(PseudoElement*); … … 157 160 } 158 161 159 inline ElementRareData::ElementRareData( RenderElement* renderer)162 inline ElementRareData::ElementRareData(Element& element, RenderElement* renderer) 160 163 : NodeRareData(renderer) 161 164 , m_tabIndex(0) … … 176 179 , m_regionOversetState(RegionUndefined) 177 180 , m_minimumSizeForResizing(defaultMinimumSizeForResizing()) 181 , m_weakPtrFactory(&element) 178 182 { 179 183 } -
trunk/Source/WebCore/dom/Node.cpp
r176084 r176496 351 351 NodeRareData* data; 352 352 if (is<Element>(*this)) 353 data = std::make_unique<ElementRareData>(downcast< RenderElement>(m_data.m_renderer)).release();353 data = std::make_unique<ElementRareData>(downcast<Element>(*this), downcast<RenderElement>(m_data.m_renderer)).release(); 354 354 else 355 355 data = std::make_unique<NodeRareData>(m_data.m_renderer).release(); -
trunk/Source/WebCore/page/DOMTimer.cpp
r176402 r176496 100 100 } 101 101 102 void elementsChangedOutsideViewport(Vector<RefPtr<StyledElement>>& elements) const 103 { 104 copyToVector(m_elementsChangedOutsideViewport, elements); 102 void elementsChangedOutsideViewport(Vector<WeakPtr<Element>>& elements) const 103 { 104 ASSERT(elements.isEmpty()); 105 elements.reserveCapacity(m_elementsChangedOutsideViewport.size()); 106 for (auto& element : m_elementsChangedOutsideViewport) 107 elements.uncheckedAppend(element->createWeakPtr()); 105 108 } 106 109 … … 472 475 ASSERT(isIntervalDependentOnViewport()); 473 476 // Check if the elements that caused this timer to be throttled are still outside the viewport. 474 for (auto& element : m_elementsCausingThrottling) { 477 for (auto& weakElementPtr : m_elementsCausingThrottling) { 478 Element* element = weakElementPtr.get(); 475 479 // Skip elements that were removed from the document. 476 if (!element ->inDocument())480 if (!element || !element->inDocument()) 477 481 continue; 478 482 -
trunk/Source/WebCore/page/DOMTimer.h
r176297 r176496 32 32 #include <wtf/HashSet.h> 33 33 #include <wtf/RefCounted.h> 34 #include <wtf/WeakPtr.h> 34 35 35 36 namespace WebCore { … … 37 38 class DOMTimerFireState; 38 39 class Document; 40 class Element; 39 41 class HTMLPlugInElement; 40 42 class IntRect; … … 92 94 double m_currentTimerInterval; 93 95 bool m_shouldForwardUserGesture; 94 // Hold a reference to the elements in case they get removed from the 95 // Document after the timer is throttled. 96 Vector<RefPtr<StyledElement>> m_elementsCausingThrottling; 96 // Use WeakPtrs because we don't want to keep the elements alive but we 97 // still need to handle cases where the elements get destroyed after 98 // the timer has fired. 99 Vector<WeakPtr<Element>> m_elementsCausingThrottling; 97 100 }; 98 101
Note:
See TracChangeset
for help on using the changeset viewer.