Changeset 236376 in webkit
- Timestamp:
- Sep 21, 2018, 5:17:17 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 7 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/fast/custom-elements/custom-elements-reaction-queue-retains-js-wrapper-expected.txt (added)
-
LayoutTests/fast/custom-elements/custom-elements-reaction-queue-retains-js-wrapper.html (added)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/Sources.txt (modified) (1 diff)
-
Source/WebCore/WebCore.xcodeproj/project.pbxproj (modified) (4 diffs)
-
Source/WebCore/bindings/js/JSNodeCustom.cpp (modified) (2 diffs)
-
Source/WebCore/dom/CustomElementReactionQueue.cpp (modified) (1 diff)
-
Source/WebCore/dom/CustomElementReactionQueue.h (modified) (2 diffs)
-
Source/WebCore/dom/GCReachableRef.cpp (added)
-
Source/WebCore/dom/GCReachableRef.h (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r236370 r236376 1 2018-09-21 Ryosuke Niwa <rniwa@webkit.org> 2 3 Custom elements in a reaction queue can lose its JS wrapper and become HTMLUnknownElement 4 https://bugs.webkit.org/show_bug.cgi?id=184307 5 6 Reviewed by Keith Miller. 7 8 Added a test for enqueuing a lot of custom elements into the reaction queue via innerHTML setter. 9 WebKit should retain the JS wrappers of all custom elements. 10 11 * fast/custom-elements/custom-elements-reaction-queue-retains-js-wrapper-expected.txt: Added. 12 * fast/custom-elements/custom-elements-reaction-queue-retains-js-wrapper.html: Added. 13 1 14 2018-09-21 Chris Dumez <cdumez@apple.com> 2 15 -
trunk/Source/WebCore/ChangeLog
r236365 r236376 1 2018-09-21 Ryosuke Niwa <rniwa@webkit.org> 2 3 Custom elements in a reaction queue can lose its JS wrapper and become HTMLUnknownElement 4 https://bugs.webkit.org/show_bug.cgi?id=184307 5 6 Reviewed by Keith Miller. 7 8 The bug was caused by the custom elements reaction queue not reporting its content to GC during marking. 9 10 When there is no JS reference to the JS wrappers of those custom element, and if those custom elements 11 are disconnected, GC would happily collect those the wrappers. Unfortunately, the same bug exists for 12 any asynchronous events and other WebCore code which keeps elements alive for a later use but doesn't 13 report them to GC (e.g. during visitChildren). 14 15 This patch, therefore, introduces a generic mechanism to keep these elements' wrappers alive. Namely, 16 we introduce GCReachableRef, a new smart pointer type for Node's subclasses, which keeps element as well 17 as its wrappers alive. GCReachableRef works by adding its Node to a global hash counted set when it's 18 created and making JSNodeOwner::isReachableFromOpaqueRoots return true when the node is in the set. 19 20 Test: fast/custom-elements/custom-elements-reaction-queue-retains-js-wrapper.html 21 22 * Sources.txt: 23 * WebCore.xcodeproj/project.pbxproj: 24 * bindings/js/JSNodeCustom.cpp: 25 (WebCore::isReachableFromDOM): 26 * dom/CustomElementReactionQueue.cpp: 27 (WebCore::CustomElementReactionQueue::ElementQueue::invokeAll): Don't swap the vector of elements in 28 in the queue. Assuming each DOM API has an appropriate CustomElementsReactionStack, we should never 29 append a new element to this queue while invoking custom element reactions. 30 * dom/CustomElementReactionQueue.h: 31 * dom/GCReachableRef.cpp: Added. 32 * dom/GCReachableRef.h: Added. 33 (WebCore::GCReachableRefMap::contains): Added. 34 (WebCore::GCReachableRefMap::add): Added. 35 (WebCore::GCReachableRefMap::remove): Added. 36 (WebCore::GCReachableRef::GCReachableRef): Added. We need isNull() check since WTFMove may have been 37 called on the source GCReachableRef. 38 (WebCore::GCReachableRef::~GCReachableRef): Ditto. 39 (WebCore::GCReachableRef::operator-> const): Added. 40 (WebCore::GCReachableRef::get const): Added. 41 (WebCore::GCReachableRef::operator T& const): Added. 42 (WebCore::GCReachableRef::operator! const): Added. 43 (WebCore::GCReachableRef::isNull const): Added. Returns true if WTFMove had been called on Ref. 44 1 45 2018-09-21 Alex Christensen <achristensen@webkit.org> 2 46 -
trunk/Source/WebCore/Sources.txt
r236273 r236376 816 816 dom/StaticRange.cpp 817 817 dom/StringCallback.cpp 818 dom/GCReachableRef.cpp 818 819 dom/StyledElement.cpp 819 820 dom/TagCollection.cpp -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r236339 r236376 2843 2843 9B714E211C91166900AC0E92 /* EventPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B714E1F1C91166900AC0E92 /* EventPath.h */; }; 2844 2844 9BA273F4172206BB0097CE47 /* LogicalSelectionOffsetCaches.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BA273F3172206BB0097CE47 /* LogicalSelectionOffsetCaches.h */; }; 2845 9BAAC45C21520128003D4A98 /* GCReachableRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BAAC4562151E39E003D4A98 /* GCReachableRef.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2845 2846 9BAB6C6C12550631001626D4 /* EditingStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BAB6C6A12550631001626D4 /* EditingStyle.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2846 2847 9BAF3B2412C1A39800014BF1 /* WritingDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = 9BAF3B2312C1A39800014BF1 /* WritingDirection.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 10872 10873 9BA273F3172206BB0097CE47 /* LogicalSelectionOffsetCaches.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LogicalSelectionOffsetCaches.h; sourceTree = "<group>"; }; 10873 10874 9BA827781F06156500F71E75 /* NavigationDisabler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NavigationDisabler.h; sourceTree = "<group>"; }; 10875 9BAAC4562151E39E003D4A98 /* GCReachableRef.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GCReachableRef.h; sourceTree = "<group>"; }; 10876 9BAAC4582151E77A003D4A98 /* GCReachableRef.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GCReachableRef.cpp; sourceTree = "<group>"; }; 10874 10877 9BAB6C6A12550631001626D4 /* EditingStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditingStyle.h; sourceTree = "<group>"; }; 10875 10878 9BAB6C6B12550631001626D4 /* EditingStyle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EditingStyle.cpp; sourceTree = "<group>"; }; … … 26591 26594 81AC6C35131C57D30009A7E0 /* StringCallback.h */, 26592 26595 81AC6C34131C57C20009A7E0 /* StringCallback.idl */, 26596 9BAAC4582151E77A003D4A98 /* GCReachableRef.cpp */, 26597 9BAAC4562151E39E003D4A98 /* GCReachableRef.h */, 26593 26598 A8C4A7EC09D563270003AC8D /* StyledElement.cpp */, 26594 26599 A8C4A7EB09D563270003AC8D /* StyledElement.h */, … … 30426 30431 9B6C41531344949000085B62 /* StringWithDirection.h in Headers */, 30427 30432 849F77760EFEC6200090849D /* StrokeStyleApplier.h in Headers */, 30433 9BAAC45C21520128003D4A98 /* GCReachableRef.h in Headers */, 30428 30434 414B82051D6DF0E50077EBE3 /* StructuredClone.h in Headers */, 30429 30435 BC5EB6A30E81DC4F00B25965 /* StyleBackgroundData.h in Headers */, -
trunk/Source/WebCore/bindings/js/JSNodeCustom.cpp
r235271 r236376 62 62 #include "ScriptState.h" 63 63 #include "ShadowRoot.h" 64 #include "GCReachableRef.h" 64 65 #include "StyleSheet.h" 65 66 #include "StyledElement.h" … … 108 109 return true; 109 110 } 111 if (GCReachableRefMap::contains(*node)) { 112 if (UNLIKELY(reason)) 113 *reason = "Node is scheduled to be used in an async script invocation)"; 114 return true; 115 } 110 116 } 111 117 -
trunk/Source/WebCore/dom/CustomElementReactionQueue.cpp
r234636 r236376 235 235 RELEASE_ASSERT(!m_invoking); 236 236 SetForScope<bool> invoking(m_invoking, true); 237 Vector<Ref<Element>> elements; 238 elements.swap(m_elements); 239 RELEASE_ASSERT(m_elements.isEmpty()); 240 for (auto& element : elements) { 237 auto originalSize = m_elements.size(); 238 for (auto& element : m_elements) { 241 239 auto* queue = element->reactionQueue(); 242 240 ASSERT(queue); 243 241 queue->invokeAll(element.get()); 244 242 } 245 RELEASE_ASSERT(m_elements.isEmpty()); 243 RELEASE_ASSERT(m_elements.size() == originalSize); 244 m_elements.clear(); 246 245 } 247 246 -
trunk/Source/WebCore/dom/CustomElementReactionQueue.h
r234636 r236376 26 26 #pragma once 27 27 28 #include "GCReachableRef.h" 28 29 #include <wtf/Forward.h> 29 30 #include <wtf/Noncopyable.h> … … 72 73 void invokeAll(); 73 74 74 Vector< Ref<Element>> m_elements;75 Vector<GCReachableRef<Element>> m_elements; 75 76 bool m_invoking { false }; 76 77 };
Note:
See TracChangeset
for help on using the changeset viewer.