blob: df945d21fa5e6aede0bd6daef23db33ecbab4a5f [file] [edit]
<!DOCTYPE html>
<html>
<head>
<script src="../../resources/js-test.js"></script>
</head>
<body>
<script>
description("A worker serializing FontFace descriptors must not race the main thread on the process-global CSS serialization memoization map (CSSPrimitiveValue).");
jsTestIsAsync = true;
// Each worker hammers customCSSText() off the main thread for ~800ms. It mixes two paths:
// - fractional percentages, which allocate a fresh heap CSSPrimitiveValue per value and, when
// overwritten, destroy it (map.add followed by map.remove) to churn the shared HashTable and
// provoke rehash() of the backing buffer.
// - integer percentages 0..255, which resolve to the shared StaticCSSValuePool objects that are
// also serialized on the main thread (the bit-field hazard).
var workerSource = `
function pump() {
var deadline = performance.now() + 800;
while (performance.now() < deadline) {
var faces = [];
for (var i = 0; i < 256; ++i) {
var fractional = (i + 0.123456).toFixed(6) + "%";
var face = new FontFace("worker-" + i, "url(x)", { sizeAdjust: fractional });
face.sizeAdjust; // map.add(heap value)
faces.push(face);
}
for (var j = 0; j < faces.length; ++j) {
faces[j].sizeAdjust = (j + 0.654321).toFixed(6) + "%"; // destroys previous => map.remove
faces[j].sizeAdjust; // map.add(new heap value)
}
for (var k = 0; k < 256; ++k) {
// Shared static-pool objects, also touched on the main thread.
var shared = new FontFace("shared-" + k, "url(x)", { sizeAdjust: k + "%" });
shared.sizeAdjust;
shared.style;
shared.weight;
shared.width;
}
}
postMessage("done");
}
pump();
`;
var NUM_WORKERS = 4;
var workersDone = 0;
var blobURL = URL.createObjectURL(new Blob([workerSource], { type: "text/javascript" }));
function onWorkerDone() {
if (++workersDone < NUM_WORKERS)
return;
testPassed("Did not crash during concurrent serialization.");
finishJSTest();
}
for (var w = 0; w < NUM_WORKERS; ++w) {
var worker = new Worker(blobURL);
worker.onmessage = onWorkerDone;
}
// Concurrently churn the shared map on the main thread: fractional percentages create and destroy
// heap CSSPrimitiveValues, and integer percentages hit the same shared static-pool objects.
var element = document.documentElement;
var deadline = performance.now() + 800;
while (performance.now() < deadline) {
for (var i = 0; i < 256; ++i) {
element.style.width = (i + 0.7777).toFixed(6) + "%"; // create heap value
element.style.getPropertyValue("width"); // map.add; next overwrite => map.remove
}
element.style.height = "100%";
for (var i = 0; i < 64; ++i)
element.style.getPropertyValue("height"); // shared static-pool object
}
</script>
</body>
</html>