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