Source/WebCore/ChangeLog

 12018-08-03 Ryosuke Niwa <rniwa@webkit.org>
 2
 3 Properties set on window.customElements can disappear due to GC
 4 https://bugs.webkit.org/show_bug.cgi?id=172575
 5 <rdar://problem/32440668>
 6
 7 Reviewed by NOBODY (OOPS!).
 8
 9 Fixed the bug that JS wrapper of CustomElementsRegistry can erroneously get collected during GC
 10 by keeping it alive as long as the global object is alive.
 11
 12 Test: fast/custom-elements/custom-element-registry-wrapper-should-stay-alive.html
 13
 14 * dom/CustomElementRegistry.cpp:
 15 (WebCore::CustomElementRegistry::create):
 16 (WebCore::CustomElementRegistry::CustomElementRegistry):
 17 * dom/CustomElementRegistry.h:
 18 (WebCore::CustomElementRegistry): Make this inherited from ContextDestructionObserver.
 19 * dom/CustomElementRegistry.idl: Set GenerateIsReachable=ImplScriptExecutionContext in IDL. This will
 20 make CustomElementRegistry reachable from the global object.
 21 * page/DOMWindow.cpp:
 22 (WebCore::DOMWindow::ensureCustomElementRegistry):
 23
1242018-08-03 Ben Richards <benton_richards@apple.com>
225
326 We should cache the compiled sandbox profile in a data vault
234575

Source/WebCore/dom/CustomElementRegistry.cpp

4141
4242namespace WebCore {
4343
44 Ref<CustomElementRegistry> CustomElementRegistry::create(DOMWindow& window)
 44Ref<CustomElementRegistry> CustomElementRegistry::create(DOMWindow& window, ScriptExecutionContext* scriptExecutionContext)
4545{
46  return adoptRef(*new CustomElementRegistry(window));
 46 return adoptRef(*new CustomElementRegistry(window, scriptExecutionContext));
4747}
4848
49 CustomElementRegistry::CustomElementRegistry(DOMWindow& window)
50  : m_window(window)
 49CustomElementRegistry::CustomElementRegistry(DOMWindow& window, ScriptExecutionContext* scriptExecutionContext)
 50 : ContextDestructionObserver(scriptExecutionContext)
 51 , m_window(window)
5152{
5253}
5354
234575

Source/WebCore/dom/CustomElementRegistry.h

2525
2626#pragma once
2727
 28#include "ContextDestructionObserver.h"
2829#include "QualifiedName.h"
2930#include <wtf/HashMap.h>
3031#include <wtf/text/AtomicString.h>

@@class JSCustomElementInterface;
4748class Node;
4849class QualifiedName;
4950
50 class CustomElementRegistry : public RefCounted<CustomElementRegistry> {
 51class CustomElementRegistry : public RefCounted<CustomElementRegistry>, public ContextDestructionObserver {
5152public:
52  static Ref<CustomElementRegistry> create(DOMWindow&);
 53 static Ref<CustomElementRegistry> create(DOMWindow&, ScriptExecutionContext*);
5354 ~CustomElementRegistry();
5455
5556 void addElementDefinition(Ref<JSCustomElementInterface>&&);

@@public:
6869 HashMap<AtomicString, Ref<DeferredPromise>>& promiseMap() { return m_promiseMap; }
6970
7071private:
71  CustomElementRegistry(DOMWindow&);
 72 CustomElementRegistry(DOMWindow&, ScriptExecutionContext*);
7273
7374 DOMWindow& m_window;
7475 HashMap<AtomicString, Ref<JSCustomElementInterface>> m_nameMap;
234575

Source/WebCore/dom/CustomElementRegistry.idl

2525
2626[
2727 EnabledAtRuntime=CustomElements,
28  ImplementationLacksVTable,
2928 JSGenerateToNativeObject,
 29 GenerateIsReachable=ImplScriptExecutionContext
3030] interface CustomElementRegistry {
3131 [CEReactions, Custom] void define(DOMString name, Function constructor);
3232 any get(DOMString name);
234575

Source/WebCore/page/DOMWindow.cpp

@@bool DOMWindow::isCurrentlyDisplayedInFr
610610CustomElementRegistry& DOMWindow::ensureCustomElementRegistry()
611611{
612612 if (!m_customElementRegistry)
613  m_customElementRegistry = CustomElementRegistry::create(*this);
 613 m_customElementRegistry = CustomElementRegistry::create(*this, scriptExecutionContext());
614614 return *m_customElementRegistry;
615615}
616616
234575

LayoutTests/ChangeLog

 12018-08-03 Ryosuke Niwa <rniwa@webkit.org>
 2
 3 Properties set on window.customElements can disappear due to GC
 4 https://bugs.webkit.org/show_bug.cgi?id=172575
 5 <rdar://problem/32440668>
 6
 7 Reviewed by NOBODY (OOPS!).
 8
 9 Added a regression test.
 10
 11 * fast/custom-elements/custom-element-registry-wrapper-should-stay-alive-expected.txt: Added.
 12 * fast/custom-elements/custom-element-registry-wrapper-should-stay-alive.html: Added.
 13
1142018-08-03 Justin Fan <justin_fan@apple.com>
215
316 WebGL 2 conformance: vertex_arrays/vertex_array_object.html
234575

LayoutTests/fast/custom-elements/custom-element-registry-wrapper-should-stay-alive-expected.txt

 1This tests that the property added on window.customElements persist after a lot of memory allocation
 2
 3On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 4
 5
 6PASS The property was present - the JS wrapper of customElements was not collected
 7PASS The property was present - the JS wrapper of customElements was not collected
 8PASS The property was present - the JS wrapper of customElements was not collected
 9PASS The property was present - the JS wrapper of customElements was not collected
 10PASS The property was present - the JS wrapper of customElements was not collected
 11PASS The property was present - the JS wrapper of customElements was not collected
 12PASS The property was present - the JS wrapper of customElements was not collected
 13PASS The property was present - the JS wrapper of customElements was not collected
 14PASS The property was present - the JS wrapper of customElements was not collected
 15PASS The property was present - the JS wrapper of customElements was not collected
 16PASS successfullyParsed is true
 17
 18TEST COMPLETE
 19
nonexistent

LayoutTests/fast/custom-elements/custom-element-registry-wrapper-should-stay-alive.html

 1<!DOCTYPE html>
 2<html>
 3<body>
 4<script src="../../resources/js-test.js"></script>
 5<script>
 6
 7description('This tests that the property added on window.customElements persist after a lot of memory allocation');
 8
 9for (let i = 0; i < 10; i++) {
 10 // Using iframe makes this test more reliable.
 11 const iframe = document.createElement('iframe');
 12 document.body.appendChild(iframe);
 13 iframe.contentWindow.eval(`
 14 window.customElements.someProperty = 'storedValue';
 15 const a = [];
 16 for (let i = 0; i < 1000000; i++)
 17 a.push({});
 18 if (window.GCController)
 19 GCController.collect();
 20 top.check(window.customElements.someProperty);`);
 21 iframe.remove();
 22}
 23
 24function check(value) {
 25 if (value == 'storedValue')
 26 testPassed('The property was present - the JS wrapper of customElements was not collected');
 27 else
 28 testFailed('The property was not present - the JS wrapper of customElements was erroneously collected');
 29}
 30
 31</script>
 32</body>
 33</html>
nonexistent