Title: [295475] trunk
Revision
295475
Author
rn...@webkit.org
Date
2022-06-11 15:32:52 -0700 (Sat, 11 Jun 2022)

Log Message

ValidityState object should be the same on each access (JS object getting GC'd incorrectly)
https://bugs.webkit.org/show_bug.cgi?id=33733

Reviewed by Darin Adler.

Fixed the bug by making the form associated element an opaque root of ValidityState.

* LayoutTests/fast/forms/ValidityState-gc-expected.txt: Added.
* LayoutTests/fast/forms/ValidityState-gc.html: Added.
* Source/WebCore/html/HTMLFormControlElement.h:
* Source/WebCore/html/HTMLObjectElement.h:
* Source/WebCore/html/ValidityState.h:
(WebCore::ValidityState::element):
(WebCore::ValidityState::opaqueRootConcurrently):
* Source/WebCore/html/ValidityState.idl:

Canonical link: https://commits.webkit.org/251480@main

Modified Paths

Added Paths

Diff

Added: trunk/LayoutTests/fast/forms/ValidityState-gc-expected.txt (0 => 295475)


--- trunk/LayoutTests/fast/forms/ValidityState-gc-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/forms/ValidityState-gc-expected.txt	2022-06-11 22:32:52 UTC (rev 295475)
@@ -0,0 +1,12 @@
+This tests that ValidityState survives garbage collection.
+
+<button></button>: PASS
+<fieldset></fieldset>: PASS
+<input type="text">: PASS
+<input type="radio">: PASS
+<input type="checkbox">: PASS
+<object></object>: PASS
+<output></output>: PASS
+<select></select>: PASS
+<textarea></textarea>: PASS
+

Added: trunk/LayoutTests/fast/forms/ValidityState-gc.html (0 => 295475)


--- trunk/LayoutTests/fast/forms/ValidityState-gc.html	                        (rev 0)
+++ trunk/LayoutTests/fast/forms/ValidityState-gc.html	2022-06-11 22:32:52 UTC (rev 295475)
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This tests that ValidityState survives garbage collection.</p>
+<div id="test-cases">
+<button></button>
+<fieldset></fieldset>
+<input type="text">
+<input type="radio">
+<input type="checkbox">
+<object></object>
+<output></output>
+<select></select>
+<textarea></textarea>
+</div>
+<pre id="result"></pre>
+<script>
+function gc()
+{
+    if (window.GCController)
+        return GCController.collect();
+
+    for (var i = 0; i < 1000000; i++) // > force garbage collection (FF requires about 9K allocations before a collect)
+        var s = new String('');
+}
+
+const testCases = Array.from(document.getElementById('test-cases').children);
+for (const child of testCases)
+    child.validity.foo = 'PASS';
+
+gc();
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+
+setTimeout(function () {
+    gc();
+    setTimeout(function () {
+        gc();
+        for (const child of testCases)
+            result.textContent += `${child.outerHTML}: ${child.validity.foo || 'FAIL'}\n`;
+        document.getElementById('test-cases').style.display = 'none';
+        if (window.testRunner)
+            testRunner.notifyDone();
+    }, 0);
+}, 0);
+
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/html/HTMLFormControlElement.h (295474 => 295475)


--- trunk/Source/WebCore/html/HTMLFormControlElement.h	2022-06-11 15:11:57 UTC (rev 295474)
+++ trunk/Source/WebCore/html/HTMLFormControlElement.h	2022-06-11 22:32:52 UTC (rev 295475)
@@ -181,8 +181,10 @@
     void startDelayingUpdateValidity() { ++m_delayedUpdateValidityCount; }
     void endDelayingUpdateValidity();
 
+    // These functions can be called concurrently for ValidityState.
     HTMLElement& asHTMLElement() final { return *this; }
     const HTMLFormControlElement& asHTMLElement() const final { return *this; }
+
     FormNamedItem* asFormNamedItem() final { return this; }
     FormAssociatedElement* asFormAssociatedElement() final { return this; }
 

Modified: trunk/Source/WebCore/html/HTMLObjectElement.h (295474 => 295475)


--- trunk/Source/WebCore/html/HTMLObjectElement.h	2022-06-11 15:11:57 UTC (rev 295474)
+++ trunk/Source/WebCore/html/HTMLObjectElement.h	2022-06-11 22:32:52 UTC (rev 295475)
@@ -93,6 +93,8 @@
 
     FormNamedItem* asFormNamedItem() final { return this; }
     FormAssociatedElement* asFormAssociatedElement() final { return this; }
+
+    // These functions can be called concurrently for ValidityState.
     HTMLObjectElement& asHTMLElement() final { return *this; }
     const HTMLObjectElement& asHTMLElement() const final { return *this; }
 

Modified: trunk/Source/WebCore/html/ValidityState.h (295474 => 295475)


--- trunk/Source/WebCore/html/ValidityState.h	2022-06-11 15:11:57 UTC (rev 295474)
+++ trunk/Source/WebCore/html/ValidityState.h	2022-06-11 22:32:52 UTC (rev 295475)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the WebKit project.
  *
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2022 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -31,6 +31,9 @@
 // but that would have a small runtime cost, and no significant benefit. We'd prefer to implement this
 // as a typedef of FormAssociatedElement, but that would require changes to bindings generation.
 class ValidityState : public FormAssociatedElement {
+public:
+    Element* element() { return &asHTMLElement(); }
+    Node* opaqueRootConcurrently() { return &asHTMLElement(); }
 };
 
 inline ValidityState* FormAssociatedElement::validity()

Modified: trunk/Source/WebCore/html/ValidityState.idl (295474 => 295475)


--- trunk/Source/WebCore/html/ValidityState.idl	2022-06-11 15:11:57 UTC (rev 295474)
+++ trunk/Source/WebCore/html/ValidityState.idl	2022-06-11 22:32:52 UTC (rev 295475)
@@ -2,6 +2,7 @@
  * This file is part of the WebKit project.
  *
  * Copyright (C) 2009 Michelangelo De Simone <micde...@gmail.com>
+ * Copyright (C) 2013-2022 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -22,7 +23,9 @@
 
 [
     SkipVTableValidation,
-    Exposed=Window
+    Exposed=Window,
+    GenerateIsReachable=ImplElementRoot,
+    GenerateAddOpaqueRoot=opaqueRootConcurrently
 ] interface ValidityState {
     readonly attribute boolean         valueMissing;
     readonly attribute boolean         typeMismatch;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to