summaryrefslogtreecommitdiffstats
path: root/testing/talos/talos/tests/perf-reftest
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/.eslintrc.json6
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/README13
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/abspos-reflow-1.html26
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/attr-selector-1.html15
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/bidi-resolution-1.html24
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/bloom-basic-2.html21
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/bloom-basic.html20
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/coalesce-1.html25
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/coalesce-2.html25
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/display-none-1.html20
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/external-string-pass.html18
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/getElementById-1.html42
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/id-getter-1.html16
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/id-getter-2.html16
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/id-getter-3.html16
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/id-getter-4.html16
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/id-getter-5.html16
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/id-getter-6.html17
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/id-getter-7.html17
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/inline-style-cache-1.html24
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/line-iterator.html32
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/link-style-cache-1.html26
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/nth-index-1.html24
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/nth-index-2.html24
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/only-children-1.html18
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/parent-basic-singleton.html20
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/perf_reftest_singletons.manifest36
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/scrollbar-styles-1.html16
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/slow-selector-1.html21
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/slow-selector-2.html21
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/style-attr-1.html21
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/style-sharing-style-attr.html21
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/style-sharing.html20
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/svg-text-getExtentOfChar-1.html36
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/svg-text-textLength-1.html31
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/tiny-traversal-singleton.html31
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/util.js106
-rw-r--r--testing/talos/talos/tests/perf-reftest-singletons/window-named-property-get.html19
-rw-r--r--testing/talos/talos/tests/perf-reftest/.eslintrc.json6
-rw-r--r--testing/talos/talos/tests/perf-reftest/bidi-resolution-1-ref.html24
-rw-r--r--testing/talos/talos/tests/perf-reftest/bidi-resolution-1.html24
-rw-r--r--testing/talos/talos/tests/perf-reftest/bloom-basic-2.html21
-rw-r--r--testing/talos/talos/tests/perf-reftest/bloom-basic-ref.html20
-rw-r--r--testing/talos/talos/tests/perf-reftest/bloom-basic.html20
-rw-r--r--testing/talos/talos/tests/perf-reftest/coalesce-1.html25
-rw-r--r--testing/talos/talos/tests/perf-reftest/coalesce-2.html25
-rw-r--r--testing/talos/talos/tests/perf-reftest/coalesce-ref.html17
-rw-r--r--testing/talos/talos/tests/perf-reftest/dep-check-1-ref.html35
-rw-r--r--testing/talos/talos/tests/perf-reftest/dep-check-1.html37
-rw-r--r--testing/talos/talos/tests/perf-reftest/display-none-1-ref.html19
-rw-r--r--testing/talos/talos/tests/perf-reftest/display-none-1.html20
-rw-r--r--testing/talos/talos/tests/perf-reftest/nth-index-1.html24
-rw-r--r--testing/talos/talos/tests/perf-reftest/nth-index-2.html24
-rw-r--r--testing/talos/talos/tests/perf-reftest/nth-index-ref.html24
-rw-r--r--testing/talos/talos/tests/perf-reftest/only-children-1.html18
-rw-r--r--testing/talos/talos/tests/perf-reftest/only-children-ref.html18
-rw-r--r--testing/talos/talos/tests/perf-reftest/perf_reftest.manifest25
-rw-r--r--testing/talos/talos/tests/perf-reftest/recompute-position-horizontal-tb.html9
-rw-r--r--testing/talos/talos/tests/perf-reftest/recompute-position-vertical-lr.html9
-rw-r--r--testing/talos/talos/tests/perf-reftest/recompute-position-vertical-rl.html9
-rw-r--r--testing/talos/talos/tests/perf-reftest/recompute-position.js24
-rw-r--r--testing/talos/talos/tests/perf-reftest/slow-selector-1-ref.html20
-rw-r--r--testing/talos/talos/tests/perf-reftest/slow-selector-1.html21
-rw-r--r--testing/talos/talos/tests/perf-reftest/slow-selector-2-ref.html20
-rw-r--r--testing/talos/talos/tests/perf-reftest/slow-selector-2.html21
-rw-r--r--testing/talos/talos/tests/perf-reftest/some-descendants-1-ref.html29
-rw-r--r--testing/talos/talos/tests/perf-reftest/some-descendants-1.html29
-rw-r--r--testing/talos/talos/tests/perf-reftest/stop-cascade-1.html26
-rw-r--r--testing/talos/talos/tests/perf-reftest/stop-cascade-2.html27
-rw-r--r--testing/talos/talos/tests/perf-reftest/stop-cascade-ref.html25
-rw-r--r--testing/talos/talos/tests/perf-reftest/style-attr-1-ref.html14
-rw-r--r--testing/talos/talos/tests/perf-reftest/style-attr-1.html21
-rw-r--r--testing/talos/talos/tests/perf-reftest/style-sharing-ref.html20
-rw-r--r--testing/talos/talos/tests/perf-reftest/style-sharing-style-attr.html21
-rw-r--r--testing/talos/talos/tests/perf-reftest/style-sharing.html20
-rw-r--r--testing/talos/talos/tests/perf-reftest/util.js106
76 files changed, 1813 insertions, 0 deletions
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/.eslintrc.json b/testing/talos/talos/tests/perf-reftest-singletons/.eslintrc.json
new file mode 100644
index 0000000000..ec8697f4c7
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/.eslintrc.json
@@ -0,0 +1,6 @@
+{
+ "rules": {
+ "no-undef": "off"
+ }
+}
+
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/README b/testing/talos/talos/tests/perf-reftest-singletons/README
new file mode 100644
index 0000000000..e3f3f05c36
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/README
@@ -0,0 +1,13 @@
+This directory is for adding short performance tests that will be tracked in
+Talos and receive regression alerts.
+
+To add a test:
+
+1) Create a test HTML file which includes <script src="util.js"></script>
+2) In that file, have an onload handler which does the following:
+ i) Any pre-test setup needed.
+ ii) A call to perf_start().
+ iii) The test steps.
+ iv) A call to perf_finish().
+3) Add your test to the perf_reftest_singletons.manifest file.
+4) Add your test to the list in build/pgo/index.html.
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/abspos-reflow-1.html b/testing/talos/talos/tests/perf-reftest-singletons/abspos-reflow-1.html
new file mode 100644
index 0000000000..9e13ca9b4d
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/abspos-reflow-1.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ const dom = build_dom(5000, "div", {
+ attributes: {
+ style: "position: absolute; left: 0px; top: 0px;",
+ },
+ });
+
+ document.body.appendChild(dom);
+ flush_layout();
+
+ perf_start();
+ for (const element of dom.querySelectorAll("*")) {
+ if (!element.childElementCount) {
+ flush_layout(element);
+ element.style.left = "auto";
+ }
+ }
+ flush_layout();
+ perf_finish();
+};
+</script>
+<body>
+</body>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/attr-selector-1.html b/testing/talos/talos/tests/perf-reftest-singletons/attr-selector-1.html
new file mode 100644
index 0000000000..46fe9b6d0a
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/attr-selector-1.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<body>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ document.body.appendChild(build_dom(10000, "div", { attributes: { "data-x": "https://example.com/b/abcdefghijklmnopqrstuvwxyz" } }));
+ flush_layout(document.body);
+ document.head.appendChild(build_rule("[data-x^='https://example.com/a']", 500, "{}"));
+ document.head.appendChild(build_rule("[data-x$='abcdefghijklmnopqrstuvwxy.']", 500, "{}"));
+ document.head.appendChild(build_rule("[data-x*='abcdefghijklmnopqrstuvwxy.']", 500, "{}"));
+ perf_start();
+ flush_style(document.body.lastChild);
+ perf_finish();
+};
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/bidi-resolution-1.html b/testing/talos/talos/tests/perf-reftest-singletons/bidi-resolution-1.html
new file mode 100644
index 0000000000..c07899386a
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/bidi-resolution-1.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html style="overflow-y: scroll">
+<head>
+<meta charset="UTF-8">
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ const TEST_WORD = "iqwdzx zzaعظأkvcg rvde";
+ let div = document.getElementById("test");
+
+ div.textContent = TEST_WORD;
+ flush_layout();
+
+ perf_start();
+ div.textContent = build_text(TEST_WORD, 30, 800);
+ flush_layout(div);
+ perf_finish();
+};
+</script>
+</head>
+<body>
+ <div id="test" style="white-space: normal"></div>
+</body>
+</html>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/bloom-basic-2.html b/testing/talos/talos/tests/perf-reftest-singletons/bloom-basic-2.html
new file mode 100644
index 0000000000..56de13dc43
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/bloom-basic-2.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="util.js"></script>
+ <script>
+window.onload = function() {
+ /* Use many rules, instead of one rule with many selectors, to test per-rule overhead. */
+ document.head.appendChild(build_rule("caption div, caption span", 1, "{ color: blue; } ", 20000));
+ let dom = build_dom(5000, "div");
+
+ flush_style();
+ perf_start();
+ document.body.appendChild(dom);
+ flush_style(dom);
+ perf_finish();
+};
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/bloom-basic.html b/testing/talos/talos/tests/perf-reftest-singletons/bloom-basic.html
new file mode 100644
index 0000000000..3ab9379a33
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/bloom-basic.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="util.js"></script>
+ <script>
+window.onload = function() {
+ document.head.appendChild(build_rule("caption div, caption span", 20000, "{ color: blue; } "));
+ let dom = build_dom(5000, "div");
+
+ flush_style();
+ perf_start();
+ document.body.appendChild(dom);
+ flush_style(dom);
+ perf_finish();
+};
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/coalesce-1.html b/testing/talos/talos/tests/perf-reftest-singletons/coalesce-1.html
new file mode 100644
index 0000000000..f80f56ae6b
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/coalesce-1.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<style>
+.x { color: yellow; }
+</style>
+<script src="util.js"></script>
+<script>
+function set_class(n) {
+ n.className = "x";
+ n = n.firstChild;
+ while (n) {
+ set_class(n);
+ n = n.nextSibling;
+ }
+}
+window.onload = function() {
+ let root = build_dom(50000, "div");
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ set_class(root);
+ flush_style(root);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/coalesce-2.html b/testing/talos/talos/tests/perf-reftest-singletons/coalesce-2.html
new file mode 100644
index 0000000000..9ebca25c7c
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/coalesce-2.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<style>
+.x { color: yellow; }
+</style>
+<script src="util.js"></script>
+<script>
+function set_class(n) {
+ let child = n.firstChild;
+ while (child) {
+ set_class(child);
+ child = child.nextSibling;
+ }
+ n.className = "x";
+}
+window.onload = function() {
+ let root = build_dom(50000, "div");
+ document.body.appendChild(root);
+ flush_style(root);
+ set_class(root);
+ perf_start();
+ flush_style(root);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/display-none-1.html b/testing/talos/talos/tests/perf-reftest-singletons/display-none-1.html
new file mode 100644
index 0000000000..00a3cf21ee
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/display-none-1.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<style>
+.root { display: none; }
+.x div { color: blue; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let root = document.createElement("div");
+ root.className = "root";
+ root.appendChild(build_dom(100000, "div"));
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ document.body.className = "x";
+ flush_style(root);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/external-string-pass.html b/testing/talos/talos/tests/perf-reftest-singletons/external-string-pass.html
new file mode 100644
index 0000000000..459dacab0b
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/external-string-pass.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<script src="util.js"></script>
+<script>
+ onload = function() {
+ var str = new Array(1e6).join("a");
+ var div = document.createElement("div");
+ // Round-trip through the DOM to make sure we have an external string.
+ div.setAttribute("x", str);
+ str = div.getAttribute("x");
+ var count = 3e7; // About 1s
+ var t = new DataTransfer();
+ perf_start();
+ for (let i = count; i > 0; --i) {
+ t.dropEffect = str;
+ }
+ perf_finish();
+ };
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/getElementById-1.html b/testing/talos/talos/tests/perf-reftest-singletons/getElementById-1.html
new file mode 100644
index 0000000000..96ed66dbe2
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/getElementById-1.html
@@ -0,0 +1,42 @@
+<!doctype html>
+<script src="util.js"></script>
+<div id="x"></div>
+<div id="y"></div>
+<script>
+ /*
+ * Test the performance of getElementById.
+ */
+ onload = function() {
+ document.getElementById("x").counterProp = 0;
+ document.getElementById("y").counterProp = 0;
+ var count = 1000000; // About 50-60ms
+ var ids = ["x", "y"];
+ perf_start();
+ for (var i = count; i > 0; --i) {
+ /*
+ * We jump through some hoops here, because the JIT knows that
+ * getElementById is side-effect-free. That means we need to prevent it
+ * being dead-code eliminated or loop-hoisted.
+ *
+ * We avoid dead-code elimination by using the return value in a way that
+ * the JIT can't eliminate (i.e. by changing state on it that can be
+ * observed later). The use of += instead of just assigning is to avoid
+ * issues with the JIT detecting that later writes dominate earlier ones
+ * and eliminating the earlier ones by having all writes contribute to the
+ * state.
+ *
+ * We avoid loop-hoisting by making the arg to the getElementById call
+ * depend on the loop variable, which is obviously not loop-invariant.
+ *
+ * A sufficiently smart compiler could probably still figure out that
+ * there are only two possible return values, loop-hoist them both, and
+ * just grab the right thing inside the loop based on the value of the
+ * loop variable, and if that starts happening we'll need to see what we
+ * can do to fool the compiler into actually doing the many getElementById
+ * calls involved.
+ */
+ document.getElementById(ids[i % 2]).counterProp += i;
+ }
+ perf_finish();
+ }
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/id-getter-1.html b/testing/talos/talos/tests/perf-reftest-singletons/id-getter-1.html
new file mode 100644
index 0000000000..5b9430134a
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/id-getter-1.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<script src="util.js"></script>
+<script>
+onload = function() {
+ var count = 20000000;
+ var el = document.createElement("span");
+ // A very short string.
+ el.id = "a";
+ var getter = Object.getOwnPropertyDescriptor(Element.prototype, "id").get;
+ perf_start();
+ for (var i = 0; i < count; ++i) {
+ getter.call(el);
+ }
+ perf_finish();
+};
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/id-getter-2.html b/testing/talos/talos/tests/perf-reftest-singletons/id-getter-2.html
new file mode 100644
index 0000000000..1751f73359
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/id-getter-2.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<script src="util.js"></script>
+<script>
+onload = function() {
+ var count = 20000000;
+ var el = document.createElement("span");
+ // The longest string we can fit in a single-byte inline string (16 chars).
+ el.id = "aaaaaaaaaaaaaaaa";
+ var getter = Object.getOwnPropertyDescriptor(Element.prototype, "id").get;
+ perf_start();
+ for (var i = 0; i < count; ++i) {
+ getter.call(el);
+ }
+ perf_finish();
+};
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/id-getter-3.html b/testing/talos/talos/tests/perf-reftest-singletons/id-getter-3.html
new file mode 100644
index 0000000000..2dd2170bbb
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/id-getter-3.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<script src="util.js"></script>
+<script>
+onload = function() {
+ var count = 20000000;
+ var el = document.createElement("span");
+ // The shortest string we can't fit in a single-byte inline string (17 chars).
+ el.id = "aaaaaaaaaaaaaaaaa";
+ var getter = Object.getOwnPropertyDescriptor(Element.prototype, "id").get;
+ perf_start();
+ for (var i = 0; i < count; ++i) {
+ getter.call(el);
+ }
+ perf_finish();
+};
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/id-getter-4.html b/testing/talos/talos/tests/perf-reftest-singletons/id-getter-4.html
new file mode 100644
index 0000000000..2a6849da30
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/id-getter-4.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<script src="util.js"></script>
+<script>
+onload = function() {
+ var count = 20000000;
+ var el = document.createElement("span");
+ // The longest string we can fit in an autostring buffer (63 chars).
+ el.id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ var getter = Object.getOwnPropertyDescriptor(Element.prototype, "id").get;
+ perf_start();
+ for (var i = 0; i < count; ++i) {
+ getter.call(el);
+ }
+ perf_finish();
+};
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/id-getter-5.html b/testing/talos/talos/tests/perf-reftest-singletons/id-getter-5.html
new file mode 100644
index 0000000000..4677c38e3a
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/id-getter-5.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<script src="util.js"></script>
+<script>
+onload = function() {
+ var count = 20000000;
+ var el = document.createElement("span");
+ // The shortest string we can't fit in an autostring buffer (64 chars).
+ el.id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ var getter = Object.getOwnPropertyDescriptor(Element.prototype, "id").get;
+ perf_start();
+ for (var i = 0; i < count; ++i) {
+ getter.call(el);
+ }
+ perf_finish();
+};
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/id-getter-6.html b/testing/talos/talos/tests/perf-reftest-singletons/id-getter-6.html
new file mode 100644
index 0000000000..5020f6a2da
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/id-getter-6.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<script src="util.js"></script>
+<script>
+onload = function() {
+ var count = 20000000;
+ var el = document.createElement("span");
+ // The longest string we can share via the external string cache after
+ // checking the chars (100 chars).
+ el.id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ var getter = Object.getOwnPropertyDescriptor(Element.prototype, "id").get;
+ perf_start();
+ for (var i = 0; i < count; ++i) {
+ getter.call(el);
+ }
+ perf_finish();
+};
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/id-getter-7.html b/testing/talos/talos/tests/perf-reftest-singletons/id-getter-7.html
new file mode 100644
index 0000000000..5b4e360a58
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/id-getter-7.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<script src="util.js"></script>
+<script>
+onload = function() {
+ var count = 20000000;
+ var el = document.createElement("span");
+ // The shortest string we can't share via the external string cache after
+ // checking the chars (101 chars).
+ el.id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ var getter = Object.getOwnPropertyDescriptor(Element.prototype, "id").get;
+ perf_start();
+ for (var i = 0; i < count; ++i) {
+ getter.call(el);
+ }
+ perf_finish();
+};
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/inline-style-cache-1.html b/testing/talos/talos/tests/perf-reftest-singletons/inline-style-cache-1.html
new file mode 100644
index 0000000000..a02eb8db2f
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/inline-style-cache-1.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<script src="util.js"></script>
+<body>
+<script>
+const styles = `:host { background: red; width: 100px; height: 100px; display: block; }`.repeat(3000);
+customElements.define("custom-element", class CustomElement extends HTMLElement {
+ connectedCallback() {
+ this.attachShadow({ mode: "open" });
+ const style = document.createElement("style");
+ style.textContent = styles;
+ this.shadowRoot.appendChild(style);
+ }
+});
+
+onload = function() {
+ perf_start();
+ for (let i = 0; i < 1000; ++i) {
+ document.body.appendChild(document.createElement("custom-element"));
+ }
+
+ flush_layout(document.body);
+ perf_finish();
+};
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/line-iterator.html b/testing/talos/talos/tests/perf-reftest-singletons/line-iterator.html
new file mode 100644
index 0000000000..6d6e7b87cf
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/line-iterator.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="util.js"></script>
+<body>
+<pre contenteditable id="test">
+</pre>
+<script>
+window.onload = function() {
+ // Create 10000 lines of editable text.
+ let text = "";
+ for (let i = 0; i < 10000; i++) {
+ text += "Line " + i + "\n";
+ }
+ testElem = document.getElementById("test");
+ testElem.textContent = text;
+ testElem.focus(); // FYI: When this runs, the URL bar has focus, thus, this fails to steal focus
+ flush_layout();
+ perf_start();
+ // Move the selection down through 2000 lines...
+ const sel = getSelection();
+ sel.setPosition(testElem.firstChild, 0);
+ for (let i = 0; i < 2000; i++) {
+ sel.modify("move", "forward", "line");
+ }
+ // ...then go to the end, and back up by 2000 lines.
+ sel.setPosition(testElem, 1);
+ for (let i = 0; i < 2000; i++) {
+ sel.modify("move", "backward", "line");
+ }
+ perf_finish();
+}
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/link-style-cache-1.html b/testing/talos/talos/tests/perf-reftest-singletons/link-style-cache-1.html
new file mode 100644
index 0000000000..80351b420a
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/link-style-cache-1.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<script src="util.js"></script>
+<body>
+<script>
+const styles = `:host { background: red; width: 100px; height: 100px; display: block; }`.repeat(3000);
+const blob = URL.createObjectURL(new Blob([styles], { type: 'text/css' }));
+customElements.define("custom-element", class CustomElement extends HTMLElement {
+ connectedCallback() {
+ this.attachShadow({ mode: "open" });
+ const link = document.createElement("link");
+ link.rel = "stylesheet";
+ link.href = blob;
+ this.shadowRoot.appendChild(link);
+ }
+});
+
+perf_start();
+
+for (let i = 0; i < 1000; ++i)
+ document.body.appendChild(document.createElement("custom-element"));
+
+onload = function() {
+ flush_layout(document.body);
+ perf_finish();
+};
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/nth-index-1.html b/testing/talos/talos/tests/perf-reftest-singletons/nth-index-1.html
new file mode 100644
index 0000000000..bf3eebc502
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/nth-index-1.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<style>
+.x:nth-child(200000) { background-color: yellow; }
+.x:nth-child(200000) div, .x:nth-child(200000) span { color: green; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let root = document.createElement("div");
+ root.className = "root";
+ for (let i = 0; i < 200000; i++) {
+ root.appendChild(document.createElement("div"));
+ }
+ let last = root.lastChild;
+ last.appendChild(build_dom(5000, "div"));
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ last.className = "x";
+ flush_style(root);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/nth-index-2.html b/testing/talos/talos/tests/perf-reftest-singletons/nth-index-2.html
new file mode 100644
index 0000000000..f3a7613770
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/nth-index-2.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<style>
+.x:nth-of-type(200000) { background-color: yellow; }
+.x:nth-of-type(200000) div, .x:nth-of-type(200000) span { color: green; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let root = document.createElement("div");
+ root.className = "root";
+ for (let i = 0; i < 200000; i++) {
+ root.appendChild(document.createElement("div"));
+ }
+ let last = root.lastChild;
+ last.appendChild(build_dom(5000, "div"));
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ last.className = "x";
+ flush_style(root);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/only-children-1.html b/testing/talos/talos/tests/perf-reftest-singletons/only-children-1.html
new file mode 100644
index 0000000000..5e6937f2eb
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/only-children-1.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<style>
+.x > div, .x > span { background-color: yellow; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let root = document.createElement("div");
+ root.appendChild(build_dom(100000, "div"));
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ root.className = "x";
+ flush_style(root);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/parent-basic-singleton.html b/testing/talos/talos/tests/perf-reftest-singletons/parent-basic-singleton.html
new file mode 100644
index 0000000000..7a1f642a64
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/parent-basic-singleton.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="util.js"></script>
+ <script>
+window.onload = function() {
+ document.head.appendChild(build_rule("body > .foo > .foo > .foo", 1000, "{ color: blue; } "));
+ let dom = build_dom(5000, "div", { attributes: {"class": "foo" } });
+
+ flush_style();
+ perf_start();
+ document.body.appendChild(dom);
+ flush_style(dom);
+ perf_finish();
+};
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/perf_reftest_singletons.manifest b/testing/talos/talos/tests/perf-reftest-singletons/perf_reftest_singletons.manifest
new file mode 100644
index 0000000000..14243a9444
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/perf_reftest_singletons.manifest
@@ -0,0 +1,36 @@
+# When modifying this list, please also update build/pgo/index.html.
+% http://localhost/tests/perf-reftest-singletons/abspos-reflow-1.html
+% http://localhost/tests/perf-reftest-singletons/attr-selector-1.html
+% http://localhost/tests/perf-reftest-singletons/bidi-resolution-1.html
+% http://localhost/tests/perf-reftest-singletons/bloom-basic-2.html
+% http://localhost/tests/perf-reftest-singletons/bloom-basic.html
+% http://localhost/tests/perf-reftest-singletons/coalesce-1.html
+% http://localhost/tests/perf-reftest-singletons/coalesce-2.html
+% http://localhost/tests/perf-reftest-singletons/display-none-1.html
+% http://localhost/tests/perf-reftest-singletons/external-string-pass.html
+% http://localhost/tests/perf-reftest-singletons/getElementById-1.html
+% http://localhost/tests/perf-reftest-singletons/id-getter-1.html
+% http://localhost/tests/perf-reftest-singletons/id-getter-2.html
+% http://localhost/tests/perf-reftest-singletons/id-getter-3.html
+% http://localhost/tests/perf-reftest-singletons/id-getter-4.html
+% http://localhost/tests/perf-reftest-singletons/id-getter-5.html
+% http://localhost/tests/perf-reftest-singletons/id-getter-6.html
+% http://localhost/tests/perf-reftest-singletons/id-getter-7.html
+% http://localhost/tests/perf-reftest-singletons/inline-style-cache-1.html
+% http://localhost/tests/perf-reftest-singletons/line-iterator.html
+% http://localhost/tests/perf-reftest-singletons/link-style-cache-1.html
+% http://localhost/tests/perf-reftest-singletons/nth-index-1.html
+% http://localhost/tests/perf-reftest-singletons/nth-index-2.html
+% http://localhost/tests/perf-reftest-singletons/only-children-1.html
+% http://localhost/tests/perf-reftest-singletons/parent-basic-singleton.html
+% http://localhost/tests/perf-reftest-singletons/scrollbar-styles-1.html
+% http://localhost/tests/perf-reftest-singletons/slow-selector-1.html
+% http://localhost/tests/perf-reftest-singletons/slow-selector-2.html
+% http://localhost/tests/perf-reftest-singletons/style-attr-1.html
+% http://localhost/tests/perf-reftest-singletons/style-sharing-style-attr.html
+% http://localhost/tests/perf-reftest-singletons/style-sharing.html
+% http://localhost/tests/perf-reftest-singletons/svg-text-textLength-1.html
+% http://localhost/tests/perf-reftest-singletons/svg-text-getExtentOfChar-1.html
+% http://localhost/tests/perf-reftest-singletons/tiny-traversal-singleton.html
+% http://localhost/tests/perf-reftest-singletons/window-named-property-get.html
+# When modifying this list, please also update build/pgo/index.html.
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/scrollbar-styles-1.html b/testing/talos/talos/tests/perf-reftest-singletons/scrollbar-styles-1.html
new file mode 100644
index 0000000000..cc69f3b7c5
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/scrollbar-styles-1.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<style>
+div { overflow: auto; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let root = document.createElement("div");
+ root.appendChild(build_dom(10000, "div"));
+ document.body.appendChild(root);
+ perf_start();
+ flush_layout(root);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/slow-selector-1.html b/testing/talos/talos/tests/perf-reftest-singletons/slow-selector-1.html
new file mode 100644
index 0000000000..8eec4e1dc9
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/slow-selector-1.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<style>
+.first:empty { color: blue; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let root = document.createElement("div");
+ let first = document.createElement("div");
+ first.className = "first";
+ first.appendChild(document.createElement("div"));
+ root.appendChild(first);
+ root.appendChild(build_dom(64000, "div"));
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ first.firstChild.remove();
+ flush_style(root);
+ perf_finish();
+};
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/slow-selector-2.html b/testing/talos/talos/tests/perf-reftest-singletons/slow-selector-2.html
new file mode 100644
index 0000000000..0dd163f5c3
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/slow-selector-2.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<style>
+.first:first-child { color: blue; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let root = document.createElement("div");
+ root.appendChild(document.createElement("div"));
+ let first = document.createElement("div");
+ first.className = "first";
+ root.appendChild(first);
+ root.appendChild(build_dom(64000, "div"));
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ root.firstChild.remove();
+ flush_style(root);
+ perf_finish();
+};
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/style-attr-1.html b/testing/talos/talos/tests/perf-reftest-singletons/style-attr-1.html
new file mode 100644
index 0000000000..c5c7b83f1d
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/style-attr-1.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ document.head.appendChild(build_rule(".x[y~='e500']", 100000, "{ color: blue; }"));
+ var div = document.createElement("div");
+ div.className = "x";
+ let val = "";
+ for (let i = 0; i < 1000; i++) {
+ val += "e" + i + " ";
+ }
+ div.setAttribute("y", val);
+ document.body.appendChild(div);
+ flush_style(div);
+ perf_start();
+ div.style.color = "green";
+ flush_style(div);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/style-sharing-style-attr.html b/testing/talos/talos/tests/perf-reftest-singletons/style-sharing-style-attr.html
new file mode 100644
index 0000000000..ab421bf926
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/style-sharing-style-attr.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="util.js"></script>
+ <script>
+window.onload = function() {
+ document.head.appendChild(build_rule("caption div", 10000, "{ color: blue; } "));
+ let dom = build_dom(5000, "div", { elemNameLeft: "div", elemNameRight: "div",
+ attributes: { style: "background-color: yellow;"} });
+
+ flush_style();
+ perf_start();
+ document.body.appendChild(dom);
+ flush_style(dom);
+ perf_finish();
+};
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/style-sharing.html b/testing/talos/talos/tests/perf-reftest-singletons/style-sharing.html
new file mode 100644
index 0000000000..fb32bde8fd
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/style-sharing.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="util.js"></script>
+ <script>
+window.onload = function() {
+ document.head.appendChild(build_rule("caption div", 10000, "{ color: blue; } "));
+ let dom = build_dom(5000, "div", { elemNameLeft: "div", elemNameRight: "div" });
+
+ flush_style();
+ perf_start();
+ document.body.appendChild(dom);
+ flush_style(dom);
+ perf_finish();
+};
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/svg-text-getExtentOfChar-1.html b/testing/talos/talos/tests/perf-reftest-singletons/svg-text-getExtentOfChar-1.html
new file mode 100644
index 0000000000..4543c6e89e
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/svg-text-getExtentOfChar-1.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="util.js"></script>
+<body>
+<svg width="144130" height="20" style="visibility:hidden">
+<rect width="144130" height="20" fill="#555"/>
+<g fill="#fff" font-family="sans-serif" font-size="110">
+<!-- The use of textLength here forces adjusted positioning of all the glyphs,
+ which may put the SVG layout engine under some strain -->
+<text id="test" x="500" y="140" transform="scale(.1)" textLength="2440730"></text>
+</g>
+</svg>
+<script>
+window.onload = function() {
+ // "word0 word1 word2 ... word99 " -> 690 chars
+ text = "";
+ for (i = 0; i < 100; i++) {
+ text = text + "word" + i + " ";
+ }
+ // 6 doublings -> approx 44k chars
+ for (i = 0; i < 6; i++) {
+ text = text + text;
+ }
+ // set the text and force a reflow
+ testElem = document.getElementById("test");
+ testElem.textContent = text;
+ flush_layout();
+ // try calling getExtentOfChar for some of the characters
+ len = text.length / 2;
+ perf_start();
+ for (i = 0; i < len; i++) {
+ testElem.getExtentOfChar(i);
+ }
+ perf_finish();
+}
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/svg-text-textLength-1.html b/testing/talos/talos/tests/perf-reftest-singletons/svg-text-textLength-1.html
new file mode 100644
index 0000000000..b5e933a0ad
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/svg-text-textLength-1.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="util.js"></script>
+<body>
+<svg width="144130" height="20" style="visibility:hidden">
+<rect width="144130" height="20" fill="#555"/>
+<g fill="#fff" font-family="sans-serif" font-size="110">
+<!-- The use of textLength here forces adjusted positioning of all the glyphs,
+ which may put the SVG layout engine under some strain -->
+<text id="test" x="500" y="140" transform="scale(.1)" textLength="2440730"></text>
+</g>
+</svg>
+<script>
+window.onload = function() {
+ // "word0 word1 word2 ... word99 " -> 690 chars
+ text = "";
+ for (i = 0; i < 100; i++) {
+ text = text + "word" + i + " ";
+ }
+ // 6 doublings -> approx 44k chars
+ for (i = 0; i < 6; i++) {
+ text = text + text;
+ }
+ // set the text and time how long a reflow takes
+ testElem = document.getElementById("test");
+ testElem.textContent = text;
+ perf_start();
+ flush_layout();
+ perf_finish();
+}
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/tiny-traversal-singleton.html b/testing/talos/talos/tests/perf-reftest-singletons/tiny-traversal-singleton.html
new file mode 100644
index 0000000000..89185f682b
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/tiny-traversal-singleton.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="util.js"></script>
+ <script>
+window.onload = function() {
+ document.head.appendChild(build_rule("caption#foo", 1, "{ color: blue; } "));
+ let dom = build_dom(2048, "div");
+ let p = dom;
+ for (var i = 0; i < 5; ++i ) {
+ p = p.firstChild.lastChild;
+ }
+ let elem = document.createElement("caption");
+ p.appendChild(elem);
+ document.body.appendChild(dom);
+ flush_style();
+
+ perf_start();
+ var state = true;
+ for (i = 0; i < 100000; ++i) {
+ elem.setAttribute("id", state ? "" : "foo");
+ state = !state;
+ window.getComputedStyle(elem).color;
+ }
+ perf_finish();
+};
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/util.js b/testing/talos/talos/tests/perf-reftest-singletons/util.js
new file mode 100644
index 0000000000..339f5b13ee
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/util.js
@@ -0,0 +1,106 @@
+var perf_data = {
+ start: null,
+ end: null,
+};
+
+function build_dom(n, elemName, options) {
+ // By default we use different elements in the DOM to defeat the style sharing
+ // cache, otherwise this sythetic DOM is trivially stylable by engines with that
+ // optimization.
+ options = options || {};
+ var elemNameLeft = options.elemNameLeft || "div";
+ var elemNameRight = options.elemNameRight || "span";
+
+ var ours = document.createElement(elemName);
+ for (var attr in options.attributes) {
+ ours.setAttribute(attr, options.attributes[attr]);
+ }
+
+ if (n != 1) {
+ var leftSize = Math.floor(n / 2);
+ var rightSize = Math.floor((n - 1) / 2);
+ ours.appendChild(build_dom(leftSize, elemNameLeft, options));
+ if (rightSize > 0) {
+ ours.appendChild(build_dom(rightSize, elemNameRight, options));
+ }
+ }
+ return ours;
+}
+
+function build_rule(selector, selectorRepeat, declaration, ruleRepeat) {
+ ruleRepeat = ruleRepeat || 1;
+ var s = document.createElement("style");
+ var rule =
+ Array(selectorRepeat)
+ .fill(selector)
+ .join(", ") + declaration;
+ s.textContent = Array(ruleRepeat)
+ .fill(rule)
+ .join("\n\n");
+ return s;
+}
+
+function build_text(word, wordRepeat, paraRepeat) {
+ wordRepeat = wordRepeat || 1;
+ paraRepeat = paraRepeat || 1;
+ let para = Array(wordRepeat)
+ .fill(word)
+ .join(" ");
+ return Array(paraRepeat)
+ .fill(para)
+ .join("\n");
+}
+
+function flush_style(element) {
+ getComputedStyle(element || document.documentElement).color;
+}
+
+function flush_layout(element) {
+ (element || document.documentElement).offsetHeight;
+}
+
+function perf_start() {
+ if (perf_data.start !== null) {
+ throw new Error("already started timing!");
+ }
+
+ perf_data.start = performance.now();
+}
+
+function perf_finish() {
+ var end = performance.now();
+
+ if (perf_data.start === null) {
+ throw new Error("haven't started timing!");
+ }
+
+ if (perf_data.end !== null) {
+ throw new Error("already finished timing!");
+ }
+
+ var start = perf_data.start;
+ perf_data.end = end;
+
+ // when running in talos report results; when running outside talos just alert
+ if (window.tpRecordTime) {
+ // Running in talos.
+ window.tpRecordTime(end - start, start);
+ } else if (window.parent && window.parent.report_perf_reftest_time) {
+ // Running in the perf-reftest runner.
+ window.parent.report_perf_reftest_time({
+ type: "time",
+ value: end - start,
+ });
+ } else {
+ // Running standalone; just alert.
+ console.log(end);
+ console.log(start);
+ alert("Result: " + (end - start).toFixed(2) + " (ms)");
+ }
+}
+
+if (window.parent.report_perf_reftest_time) {
+ window.addEventListener("error", function(e) {
+ window.parent.report_perf_reftest_time({ type: "error", value: e.message });
+ });
+}
diff --git a/testing/talos/talos/tests/perf-reftest-singletons/window-named-property-get.html b/testing/talos/talos/tests/perf-reftest-singletons/window-named-property-get.html
new file mode 100644
index 0000000000..7dfa802f7a
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest-singletons/window-named-property-get.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="util.js"></script>
+<div id="x"></div>
+<script>
+ /*
+ * Test performance of bareword lookup via the Window's named properties
+ * object.
+ */
+ onload = function() {
+ let count = 1000000; // About 700ms
+ perf_start();
+ for (let i = count; i > 0; --i) {
+ // Pretty sure JITs are not smart enough to optimize out this proxy
+ // lookup, so no need to do anything other than perform the get.
+ x;
+ }
+ perf_finish();
+ }
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest/.eslintrc.json b/testing/talos/talos/tests/perf-reftest/.eslintrc.json
new file mode 100644
index 0000000000..ec8697f4c7
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/.eslintrc.json
@@ -0,0 +1,6 @@
+{
+ "rules": {
+ "no-undef": "off"
+ }
+}
+
diff --git a/testing/talos/talos/tests/perf-reftest/bidi-resolution-1-ref.html b/testing/talos/talos/tests/perf-reftest/bidi-resolution-1-ref.html
new file mode 100644
index 0000000000..c992ca428a
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/bidi-resolution-1-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html style="overflow-y: scroll">
+<head>
+<meta charset="UTF-8">
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ const TEST_WORD = "iqwdzx zzaعظأkvcg rvde";
+ let div = document.getElementById("test");
+
+ div.textContent = TEST_WORD;
+ flush_layout();
+
+ perf_start();
+ div.textContent = build_text(TEST_WORD, 30, 800);
+ flush_layout(div);
+ perf_finish();
+};
+</script>
+</head>
+<body>
+ <div id="test" style="white-space: pre-line"></div>
+</body>
+</html>
diff --git a/testing/talos/talos/tests/perf-reftest/bidi-resolution-1.html b/testing/talos/talos/tests/perf-reftest/bidi-resolution-1.html
new file mode 100644
index 0000000000..c07899386a
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/bidi-resolution-1.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html style="overflow-y: scroll">
+<head>
+<meta charset="UTF-8">
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ const TEST_WORD = "iqwdzx zzaعظأkvcg rvde";
+ let div = document.getElementById("test");
+
+ div.textContent = TEST_WORD;
+ flush_layout();
+
+ perf_start();
+ div.textContent = build_text(TEST_WORD, 30, 800);
+ flush_layout(div);
+ perf_finish();
+};
+</script>
+</head>
+<body>
+ <div id="test" style="white-space: normal"></div>
+</body>
+</html>
diff --git a/testing/talos/talos/tests/perf-reftest/bloom-basic-2.html b/testing/talos/talos/tests/perf-reftest/bloom-basic-2.html
new file mode 100644
index 0000000000..56de13dc43
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/bloom-basic-2.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="util.js"></script>
+ <script>
+window.onload = function() {
+ /* Use many rules, instead of one rule with many selectors, to test per-rule overhead. */
+ document.head.appendChild(build_rule("caption div, caption span", 1, "{ color: blue; } ", 20000));
+ let dom = build_dom(5000, "div");
+
+ flush_style();
+ perf_start();
+ document.body.appendChild(dom);
+ flush_style(dom);
+ perf_finish();
+};
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/testing/talos/talos/tests/perf-reftest/bloom-basic-ref.html b/testing/talos/talos/tests/perf-reftest/bloom-basic-ref.html
new file mode 100644
index 0000000000..f15045fe21
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/bloom-basic-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="util.js"></script>
+ <script>
+window.onload = function() {
+ document.head.appendChild(build_rule("caption > div, caption > span", 20000, "{ color: blue; } "));
+ let dom = build_dom(5000, "div");
+
+ flush_style();
+ perf_start();
+ document.body.appendChild(dom);
+ flush_style(dom);
+ perf_finish();
+};
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/testing/talos/talos/tests/perf-reftest/bloom-basic.html b/testing/talos/talos/tests/perf-reftest/bloom-basic.html
new file mode 100644
index 0000000000..3ab9379a33
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/bloom-basic.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="util.js"></script>
+ <script>
+window.onload = function() {
+ document.head.appendChild(build_rule("caption div, caption span", 20000, "{ color: blue; } "));
+ let dom = build_dom(5000, "div");
+
+ flush_style();
+ perf_start();
+ document.body.appendChild(dom);
+ flush_style(dom);
+ perf_finish();
+};
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/testing/talos/talos/tests/perf-reftest/coalesce-1.html b/testing/talos/talos/tests/perf-reftest/coalesce-1.html
new file mode 100644
index 0000000000..f80f56ae6b
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/coalesce-1.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<style>
+.x { color: yellow; }
+</style>
+<script src="util.js"></script>
+<script>
+function set_class(n) {
+ n.className = "x";
+ n = n.firstChild;
+ while (n) {
+ set_class(n);
+ n = n.nextSibling;
+ }
+}
+window.onload = function() {
+ let root = build_dom(50000, "div");
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ set_class(root);
+ flush_style(root);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/coalesce-2.html b/testing/talos/talos/tests/perf-reftest/coalesce-2.html
new file mode 100644
index 0000000000..9ebca25c7c
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/coalesce-2.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<style>
+.x { color: yellow; }
+</style>
+<script src="util.js"></script>
+<script>
+function set_class(n) {
+ let child = n.firstChild;
+ while (child) {
+ set_class(child);
+ child = child.nextSibling;
+ }
+ n.className = "x";
+}
+window.onload = function() {
+ let root = build_dom(50000, "div");
+ document.body.appendChild(root);
+ flush_style(root);
+ set_class(root);
+ perf_start();
+ flush_style(root);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/coalesce-ref.html b/testing/talos/talos/tests/perf-reftest/coalesce-ref.html
new file mode 100644
index 0000000000..8b5692f972
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/coalesce-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<style>
+.x, .x * { color: yellow; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let root = build_dom(50000, "div");
+ document.body.appendChild(root);
+ flush_style(root);
+ root.className = "x";
+ perf_start();
+ flush_style(root);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/dep-check-1-ref.html b/testing/talos/talos/tests/perf-reftest/dep-check-1-ref.html
new file mode 100644
index 0000000000..a0b0083330
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/dep-check-1-ref.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let s = "";
+ s += ".x";
+ for (let j = 0; j < 100; j++) {
+ s += "[y~=v" + j + "]";
+ }
+ s += " { background-color: yellow; }";
+ var style = document.createElement("style");
+ style.textContent = s;
+ document.head.appendChild(style);
+ let els = [];
+ for (let i = 0; i < 1000; i++) {
+ var el = document.createElement("e" + i);
+ el.className = "x";
+ let val = "";
+ for (let j = 0; j < 100; j++) {
+ val += "v" + j + " ";
+ }
+ el.setAttribute("y", val);
+ document.body.appendChild(el);
+ els.push(el);
+ }
+ flush_style(els[0]);
+ perf_start();
+ for (let el of els) {
+ el.className = "";
+ }
+ flush_style(els[0]);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/dep-check-1.html b/testing/talos/talos/tests/perf-reftest/dep-check-1.html
new file mode 100644
index 0000000000..0de2b07567
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/dep-check-1.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let s = "";
+ for (let i = 0; i < 50; i++) {
+ s += ".x";
+ for (let j = 0; j < 100; j++) {
+ s += "[y~=v" + j + "]";
+ }
+ s += " { background-color: yellow; }";
+ }
+ var style = document.createElement("style");
+ style.textContent = s;
+ document.head.appendChild(style);
+ let els = [];
+ for (let i = 0; i < 1000; i++) {
+ var el = document.createElement("e" + i);
+ el.className = "x";
+ let val = "";
+ for (let j = 0; j < 100; j++) {
+ val += "v" + j + " ";
+ }
+ el.setAttribute("y", val);
+ document.body.appendChild(el);
+ els.push(el);
+ }
+ flush_style(els[0]);
+ perf_start();
+ for (let el of els) {
+ el.className = "";
+ }
+ flush_style(els[0]);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/display-none-1-ref.html b/testing/talos/talos/tests/perf-reftest/display-none-1-ref.html
new file mode 100644
index 0000000000..160cf104d3
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/display-none-1-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<style>
+.root { display: none; }
+.x div { color: blue; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let root = document.createElement("div");
+ root.className = "root";
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ document.body.className = "x";
+ flush_style(root);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/display-none-1.html b/testing/talos/talos/tests/perf-reftest/display-none-1.html
new file mode 100644
index 0000000000..00a3cf21ee
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/display-none-1.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<style>
+.root { display: none; }
+.x div { color: blue; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let root = document.createElement("div");
+ root.className = "root";
+ root.appendChild(build_dom(100000, "div"));
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ document.body.className = "x";
+ flush_style(root);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/nth-index-1.html b/testing/talos/talos/tests/perf-reftest/nth-index-1.html
new file mode 100644
index 0000000000..bf3eebc502
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/nth-index-1.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<style>
+.x:nth-child(200000) { background-color: yellow; }
+.x:nth-child(200000) div, .x:nth-child(200000) span { color: green; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let root = document.createElement("div");
+ root.className = "root";
+ for (let i = 0; i < 200000; i++) {
+ root.appendChild(document.createElement("div"));
+ }
+ let last = root.lastChild;
+ last.appendChild(build_dom(5000, "div"));
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ last.className = "x";
+ flush_style(root);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/nth-index-2.html b/testing/talos/talos/tests/perf-reftest/nth-index-2.html
new file mode 100644
index 0000000000..f3a7613770
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/nth-index-2.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<style>
+.x:nth-of-type(200000) { background-color: yellow; }
+.x:nth-of-type(200000) div, .x:nth-of-type(200000) span { color: green; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let root = document.createElement("div");
+ root.className = "root";
+ for (let i = 0; i < 200000; i++) {
+ root.appendChild(document.createElement("div"));
+ }
+ let last = root.lastChild;
+ last.appendChild(build_dom(5000, "div"));
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ last.className = "x";
+ flush_style(root);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/nth-index-ref.html b/testing/talos/talos/tests/perf-reftest/nth-index-ref.html
new file mode 100644
index 0000000000..819f30686c
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/nth-index-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<style>
+.x:nth-child(200000) { background-color: yellow; }
+.x div, .x span { color: green; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let root = document.createElement("div");
+ root.className = "root";
+ for (let i = 0; i < 200000; i++) {
+ root.appendChild(document.createElement("div"));
+ }
+ let last = root.lastChild;
+ last.appendChild(build_dom(5000, "div"));
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ last.className = "x";
+ flush_style(root);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/only-children-1.html b/testing/talos/talos/tests/perf-reftest/only-children-1.html
new file mode 100644
index 0000000000..5e6937f2eb
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/only-children-1.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<style>
+.x > div, .x > span { background-color: yellow; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let root = document.createElement("div");
+ root.appendChild(build_dom(100000, "div"));
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ root.className = "x";
+ flush_style(root);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/only-children-ref.html b/testing/talos/talos/tests/perf-reftest/only-children-ref.html
new file mode 100644
index 0000000000..60bdf0ffd5
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/only-children-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<style>
+.x > div, .x > span { background-color: yellow; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let root = document.createElement("div");
+ root.appendChild(document.createElement("div"));
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ root.firstChild.className = "x";
+ flush_style(root);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/perf_reftest.manifest b/testing/talos/talos/tests/perf-reftest/perf_reftest.manifest
new file mode 100644
index 0000000000..42196d5b1d
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/perf_reftest.manifest
@@ -0,0 +1,25 @@
+# base_vs_ref is set in test.py for this test, so each of these lines is the base vs ref test pag
+# both pages are run and then the results compared, the ultimate reported results are the comparisons.
+# Each line is reported as a subtest like the other talos tests that have multiple lines of URLs.
+& http://localhost/tests/perf-reftest/bloom-basic.html, http://localhost/tests/perf-reftest/bloom-basic-ref.html
+& http://localhost/tests/perf-reftest/bloom-basic-2.html, http://localhost/tests/perf-reftest/bloom-basic-ref.html
+& http://localhost/tests/perf-reftest/coalesce-1.html, http://localhost/tests/perf-reftest/coalesce-ref.html
+& http://localhost/tests/perf-reftest/coalesce-2.html, http://localhost/tests/perf-reftest/coalesce-ref.html
+& http://localhost/tests/perf-reftest/style-sharing.html, http://localhost/tests/perf-reftest/style-sharing-ref.html
+& http://localhost/tests/perf-reftest/style-sharing-style-attr.html, http://localhost/tests/perf-reftest/style-sharing-ref.html
+& http://localhost/tests/perf-reftest/display-none-1.html, http://localhost/tests/perf-reftest/display-none-1-ref.html
+& http://localhost/tests/perf-reftest/nth-index-1.html, http://localhost/tests/perf-reftest/nth-index-ref.html
+& http://localhost/tests/perf-reftest/nth-index-2.html, http://localhost/tests/perf-reftest/nth-index-ref.html
+& http://localhost/tests/perf-reftest/some-descendants-1.html, http://localhost/tests/perf-reftest/some-descendants-1-ref.html
+& http://localhost/tests/perf-reftest/only-children-1.html, http://localhost/tests/perf-reftest/only-children-ref.html
+& http://localhost/tests/perf-reftest/dep-check-1.html, http://localhost/tests/perf-reftest/dep-check-1-ref.html
+& http://localhost/tests/perf-reftest/slow-selector-1.html, http://localhost/tests/perf-reftest/slow-selector-1-ref.html
+& http://localhost/tests/perf-reftest/slow-selector-2.html, http://localhost/tests/perf-reftest/slow-selector-2-ref.html
+& http://localhost/tests/perf-reftest/style-attr-1.html, http://localhost/tests/perf-reftest/style-attr-1-ref.html
+& http://localhost/tests/perf-reftest/stop-cascade-1.html, http://localhost/tests/perf-reftest/stop-cascade-ref.html
+& http://localhost/tests/perf-reftest/stop-cascade-2.html, http://localhost/tests/perf-reftest/stop-cascade-ref.html
+
+& http://localhost/tests/perf-reftest/bidi-resolution-1.html, http://localhost/tests/perf-reftest/bidi-resolution-1-ref.html
+
+& http://localhost/tests/perf-reftest/recompute-position-vertical-lr.html, http://localhost/tests/perf-reftest/recompute-position-horizontal-tb.html
+& http://localhost/tests/perf-reftest/recompute-position-vertical-rl.html, http://localhost/tests/perf-reftest/recompute-position-horizontal-tb.html
diff --git a/testing/talos/talos/tests/perf-reftest/recompute-position-horizontal-tb.html b/testing/talos/talos/tests/perf-reftest/recompute-position-horizontal-tb.html
new file mode 100644
index 0000000000..642dfded77
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/recompute-position-horizontal-tb.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<style>
+html {
+ writing-mode: horizontal-tb;
+}
+</style>
+<script src="util.js"></script>
+<script src="recompute-position.js"></script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/recompute-position-vertical-lr.html b/testing/talos/talos/tests/perf-reftest/recompute-position-vertical-lr.html
new file mode 100644
index 0000000000..1177b83f89
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/recompute-position-vertical-lr.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<style>
+html {
+ writing-mode: vertical-lr;
+}
+</style>
+<script src="util.js"></script>
+<script src="recompute-position.js"></script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/recompute-position-vertical-rl.html b/testing/talos/talos/tests/perf-reftest/recompute-position-vertical-rl.html
new file mode 100644
index 0000000000..5a4f07504a
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/recompute-position-vertical-rl.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<style>
+html {
+ writing-mode: vertical-rl;
+}
+</style>
+<script src="util.js"></script>
+<script src="recompute-position.js"></script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/recompute-position.js b/testing/talos/talos/tests/perf-reftest/recompute-position.js
new file mode 100644
index 0000000000..6f235b6d39
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/recompute-position.js
@@ -0,0 +1,24 @@
+window.addEventListener("load", function() {
+ let str = "さ".repeat(97);
+ for (let i = 0; i < 2000; i++) {
+ let p = document.createElement("p");
+ p.textContent = str;
+ document.body.appendChild(p);
+ }
+ let floating = document.createElement("div");
+ floating.style.position = "absolute";
+ floating.style.top = "5px";
+ floating.style.left = "0px";
+ floating.style.backgroundColor = "white";
+ floating.innerHTML =
+ "あああああああああああ<br>あああああああああああ<br>あああああああああああ<br>あああああああああああ<br>あああああああああああ<br>あああああああああああ";
+ document.body.appendChild(floating);
+
+ flush_layout(floating);
+ perf_start();
+ for (let i = 0; i < 1000; i++) {
+ floating.style.left = i + "px";
+ flush_layout(floating);
+ }
+ perf_finish();
+});
diff --git a/testing/talos/talos/tests/perf-reftest/slow-selector-1-ref.html b/testing/talos/talos/tests/perf-reftest/slow-selector-1-ref.html
new file mode 100644
index 0000000000..8785dd2da1
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/slow-selector-1-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<style>
+.first:empty { color: blue; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let root = document.createElement("div");
+ let first = document.createElement("div");
+ first.className = "first";
+ first.appendChild(document.createElement("div"));
+ root.appendChild(first);
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ first.firstChild.remove();
+ flush_style(root);
+ perf_finish();
+};
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest/slow-selector-1.html b/testing/talos/talos/tests/perf-reftest/slow-selector-1.html
new file mode 100644
index 0000000000..8eec4e1dc9
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/slow-selector-1.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<style>
+.first:empty { color: blue; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let root = document.createElement("div");
+ let first = document.createElement("div");
+ first.className = "first";
+ first.appendChild(document.createElement("div"));
+ root.appendChild(first);
+ root.appendChild(build_dom(64000, "div"));
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ first.firstChild.remove();
+ flush_style(root);
+ perf_finish();
+};
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest/slow-selector-2-ref.html b/testing/talos/talos/tests/perf-reftest/slow-selector-2-ref.html
new file mode 100644
index 0000000000..2044c5676c
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/slow-selector-2-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<style>
+.first:first-child { color: blue; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let root = document.createElement("div");
+ root.appendChild(document.createElement("div"));
+ let first = document.createElement("div");
+ first.className = "first";
+ root.appendChild(first);
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ root.firstChild.remove();
+ flush_style(root);
+ perf_finish();
+};
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest/slow-selector-2.html b/testing/talos/talos/tests/perf-reftest/slow-selector-2.html
new file mode 100644
index 0000000000..0dd163f5c3
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/slow-selector-2.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<style>
+.first:first-child { color: blue; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let root = document.createElement("div");
+ root.appendChild(document.createElement("div"));
+ let first = document.createElement("div");
+ first.className = "first";
+ root.appendChild(first);
+ root.appendChild(build_dom(64000, "div"));
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ root.firstChild.remove();
+ flush_style(root);
+ perf_finish();
+};
+</script>
diff --git a/testing/talos/talos/tests/perf-reftest/some-descendants-1-ref.html b/testing/talos/talos/tests/perf-reftest/some-descendants-1-ref.html
new file mode 100644
index 0000000000..eb024c5504
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/some-descendants-1-ref.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<style>
+.x { color: blue; }
+.y { background-color: green; }
+</style>
+<script src="util.js"></script>
+<script>
+function find_leftmost(e) {
+ while (e.firstChild) {
+ e = e.firstChild;
+ }
+ return e;
+}
+window.onload = function() {
+ document.head.appendChild(build_rule("div", 1, "{ color: blue; }", 100));
+ let root = document.createElement("div");
+ root.className = "root";
+ root.appendChild(build_dom(50000, "div"));
+ let leftmost = find_leftmost(root);
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ document.body.className = "x";
+ leftmost.className = "y";
+ flush_style(root);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/some-descendants-1.html b/testing/talos/talos/tests/perf-reftest/some-descendants-1.html
new file mode 100644
index 0000000000..60f30cebd2
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/some-descendants-1.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<style>
+.x { color: blue; }
+.x .y { background-color: green; }
+</style>
+<script src="util.js"></script>
+<script>
+function find_leftmost(e) {
+ while (e.firstChild) {
+ e = e.firstChild;
+ }
+ return e;
+}
+window.onload = function() {
+ document.head.appendChild(build_rule("div", 1, "{ color: blue; }", 100));
+ let root = document.createElement("div");
+ root.className = "root";
+ root.appendChild(build_dom(50000, "div"));
+ let leftmost = find_leftmost(root);
+ leftmost.className = "y";
+ document.body.appendChild(root);
+ flush_style(root);
+ perf_start();
+ document.body.className = "x";
+ flush_style(root);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/stop-cascade-1.html b/testing/talos/talos/tests/perf-reftest/stop-cascade-1.html
new file mode 100644
index 0000000000..4172c36920
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/stop-cascade-1.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<style>
+.x { background-color: yellow; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let roots = [];
+ for (let i = 0; i < 200; i++) {
+ let root = document.createElement("div");
+ root.appendChild(build_dom(1024, "div"));
+ roots.push(root);
+ document.body.appendChild(root);
+ }
+ flush_style(roots[0]);
+ perf_start();
+ for (x in ["x", "", "x"]) {
+ for (let root of roots) {
+ root.className = x;
+ }
+ }
+ flush_style(roots[0]);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/stop-cascade-2.html b/testing/talos/talos/tests/perf-reftest/stop-cascade-2.html
new file mode 100644
index 0000000000..58623e89c1
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/stop-cascade-2.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<style>
+div, span { border-left-color: inherit; }
+.x { background-color: yellow; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let roots = [];
+ for (let i = 0; i < 200; i++) {
+ let root = document.createElement("div");
+ root.appendChild(build_dom(1024, "div"));
+ roots.push(root);
+ document.body.appendChild(root);
+ }
+ flush_style(roots[0]);
+ perf_start();
+ for (x in ["x", "", "x"]) {
+ for (let root of roots) {
+ root.className = x;
+ }
+ }
+ flush_style(roots[0]);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/stop-cascade-ref.html b/testing/talos/talos/tests/perf-reftest/stop-cascade-ref.html
new file mode 100644
index 0000000000..5d6906c97f
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/stop-cascade-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<style>
+.x { background-color: yellow; }
+</style>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ let roots = [];
+ for (let i = 0; i < 200; i++) {
+ let root = document.createElement("div");
+ roots.push(root);
+ document.body.appendChild(root);
+ }
+ flush_style(roots[0]);
+ perf_start();
+ for (x in ["x", "", "x"]) {
+ for (let root of roots) {
+ root.className = x;
+ }
+ }
+ flush_style(roots[0]);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/style-attr-1-ref.html b/testing/talos/talos/tests/perf-reftest/style-attr-1-ref.html
new file mode 100644
index 0000000000..9812364e91
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/style-attr-1-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ var div = document.createElement("div");
+ document.body.appendChild(div);
+ flush_style(div);
+ perf_start();
+ div.style.color = "green";
+ flush_style(div);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/style-attr-1.html b/testing/talos/talos/tests/perf-reftest/style-attr-1.html
new file mode 100644
index 0000000000..c5c7b83f1d
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/style-attr-1.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<script src="util.js"></script>
+<script>
+window.onload = function() {
+ document.head.appendChild(build_rule(".x[y~='e500']", 100000, "{ color: blue; }"));
+ var div = document.createElement("div");
+ div.className = "x";
+ let val = "";
+ for (let i = 0; i < 1000; i++) {
+ val += "e" + i + " ";
+ }
+ div.setAttribute("y", val);
+ document.body.appendChild(div);
+ flush_style(div);
+ perf_start();
+ div.style.color = "green";
+ flush_style(div);
+ perf_finish();
+};
+</script>
+<body></body>
diff --git a/testing/talos/talos/tests/perf-reftest/style-sharing-ref.html b/testing/talos/talos/tests/perf-reftest/style-sharing-ref.html
new file mode 100644
index 0000000000..e47ddc3c6f
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/style-sharing-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="util.js"></script>
+ <script>
+window.onload = function() {
+ document.head.appendChild(build_rule("div", 1, "{ color: blue; } "));
+ let dom = build_dom(2000, "div");
+
+ flush_style();
+ perf_start();
+ document.body.appendChild(dom);
+ flush_style(dom);
+ perf_finish();
+};
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/testing/talos/talos/tests/perf-reftest/style-sharing-style-attr.html b/testing/talos/talos/tests/perf-reftest/style-sharing-style-attr.html
new file mode 100644
index 0000000000..ab421bf926
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/style-sharing-style-attr.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="util.js"></script>
+ <script>
+window.onload = function() {
+ document.head.appendChild(build_rule("caption div", 10000, "{ color: blue; } "));
+ let dom = build_dom(5000, "div", { elemNameLeft: "div", elemNameRight: "div",
+ attributes: { style: "background-color: yellow;"} });
+
+ flush_style();
+ perf_start();
+ document.body.appendChild(dom);
+ flush_style(dom);
+ perf_finish();
+};
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/testing/talos/talos/tests/perf-reftest/style-sharing.html b/testing/talos/talos/tests/perf-reftest/style-sharing.html
new file mode 100644
index 0000000000..fb32bde8fd
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/style-sharing.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="util.js"></script>
+ <script>
+window.onload = function() {
+ document.head.appendChild(build_rule("caption div", 10000, "{ color: blue; } "));
+ let dom = build_dom(5000, "div", { elemNameLeft: "div", elemNameRight: "div" });
+
+ flush_style();
+ perf_start();
+ document.body.appendChild(dom);
+ flush_style(dom);
+ perf_finish();
+};
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/testing/talos/talos/tests/perf-reftest/util.js b/testing/talos/talos/tests/perf-reftest/util.js
new file mode 100644
index 0000000000..339f5b13ee
--- /dev/null
+++ b/testing/talos/talos/tests/perf-reftest/util.js
@@ -0,0 +1,106 @@
+var perf_data = {
+ start: null,
+ end: null,
+};
+
+function build_dom(n, elemName, options) {
+ // By default we use different elements in the DOM to defeat the style sharing
+ // cache, otherwise this sythetic DOM is trivially stylable by engines with that
+ // optimization.
+ options = options || {};
+ var elemNameLeft = options.elemNameLeft || "div";
+ var elemNameRight = options.elemNameRight || "span";
+
+ var ours = document.createElement(elemName);
+ for (var attr in options.attributes) {
+ ours.setAttribute(attr, options.attributes[attr]);
+ }
+
+ if (n != 1) {
+ var leftSize = Math.floor(n / 2);
+ var rightSize = Math.floor((n - 1) / 2);
+ ours.appendChild(build_dom(leftSize, elemNameLeft, options));
+ if (rightSize > 0) {
+ ours.appendChild(build_dom(rightSize, elemNameRight, options));
+ }
+ }
+ return ours;
+}
+
+function build_rule(selector, selectorRepeat, declaration, ruleRepeat) {
+ ruleRepeat = ruleRepeat || 1;
+ var s = document.createElement("style");
+ var rule =
+ Array(selectorRepeat)
+ .fill(selector)
+ .join(", ") + declaration;
+ s.textContent = Array(ruleRepeat)
+ .fill(rule)
+ .join("\n\n");
+ return s;
+}
+
+function build_text(word, wordRepeat, paraRepeat) {
+ wordRepeat = wordRepeat || 1;
+ paraRepeat = paraRepeat || 1;
+ let para = Array(wordRepeat)
+ .fill(word)
+ .join(" ");
+ return Array(paraRepeat)
+ .fill(para)
+ .join("\n");
+}
+
+function flush_style(element) {
+ getComputedStyle(element || document.documentElement).color;
+}
+
+function flush_layout(element) {
+ (element || document.documentElement).offsetHeight;
+}
+
+function perf_start() {
+ if (perf_data.start !== null) {
+ throw new Error("already started timing!");
+ }
+
+ perf_data.start = performance.now();
+}
+
+function perf_finish() {
+ var end = performance.now();
+
+ if (perf_data.start === null) {
+ throw new Error("haven't started timing!");
+ }
+
+ if (perf_data.end !== null) {
+ throw new Error("already finished timing!");
+ }
+
+ var start = perf_data.start;
+ perf_data.end = end;
+
+ // when running in talos report results; when running outside talos just alert
+ if (window.tpRecordTime) {
+ // Running in talos.
+ window.tpRecordTime(end - start, start);
+ } else if (window.parent && window.parent.report_perf_reftest_time) {
+ // Running in the perf-reftest runner.
+ window.parent.report_perf_reftest_time({
+ type: "time",
+ value: end - start,
+ });
+ } else {
+ // Running standalone; just alert.
+ console.log(end);
+ console.log(start);
+ alert("Result: " + (end - start).toFixed(2) + " (ms)");
+ }
+}
+
+if (window.parent.report_perf_reftest_time) {
+ window.addEventListener("error", function(e) {
+ window.parent.report_perf_reftest_time({ type: "error", value: e.message });
+ });
+}