haikuwebkit/LayoutTests/resources/gc.js

58 lines
1.8 KiB
JavaScript
Raw Permalink Normal View History

// If there is no window.gc() already defined, define one using the best
// method we can find.
// The slow fallback should not hit in the actual test environment.
if (!window.gc)
{
window.gc = function()
{
if (window.GCController)
return GCController.collect();
[Streams API] Sync tests with spec https://bugs.webkit.org/show_bug.cgi?id=145839 Reviewed by Darin Adler. Considered all changes in the spec tests and brought them to WebKit. Some of those changes were related to spec changes, like the strategy or some of the algorithms. Some like the tee ones were newly added as they will be implemented soon. There are also some tests that shuffled around because they were just moved at the spec or integrated from the changes we submitted, which was substantially important as it allowed us to remove some of our custom tests that are now covered by the spec ones. * resources/gc.js: Added warning about using gcRec, results might not be reliable. * streams/readable-stream-controller-error-expected.txt: * streams/readable-stream-controller-error.html: New failing test due to discrepancies with the reference implementation. Something we will address. * streams/readable-stream-expected.txt: Removed. * streams/readable-stream-gc.html: Renumbered. * streams/readable-stream-reader-expected.txt: Removed. * streams/readable-stream-reader-read.html: Renumbered. * streams/readable-stream-reader.html: Removed. * streams/readable-stream.html: Removed. * streams/reference-implementation/bad-strategies-expected.txt: Added. * streams/reference-implementation/bad-strategies.html: Added. * streams/reference-implementation/bad-underlying-sources-expected.txt: * streams/reference-implementation/bad-underlying-sources.html: Updated from spec and expectations. * streams/reference-implementation/brand-checks-expected.txt: * streams/reference-implementation/brand-checks.html: Updated from spec and expectations. * streams/reference-implementation/byte-length-queuing-strategy-expected.txt: Added. * streams/reference-implementation/byte-length-queuing-strategy.html: Added. * streams/reference-implementation/count-queuing-strategy-expected.txt: * streams/reference-implementation/count-queuing-strategy.html: Updated from spec and expectations. * streams/reference-implementation/readable-stream-cancel-expected.txt: * streams/reference-implementation/readable-stream-cancel.html: Updated from spec and expectations and corrected timeouts to try to overcome problems in slower bots. * streams/reference-implementation/readable-stream-expected.txt: * streams/reference-implementation/readable-stream-reader-expected.txt: * streams/reference-implementation/readable-stream-reader.html: Updated from spec and expectations. * streams/reference-implementation/readable-stream-tee-expected.txt: Added. * streams/reference-implementation/readable-stream-tee.html: Added. * streams/reference-implementation/readable-stream-templated-expected.txt: * streams/reference-implementation/readable-stream-templated.html: Updated from spec and expectations. * streams/reference-implementation/readable-stream.html: Updated from spec and expectations. * streams/reference-implementation/resources/byte-length-queuing-strategy.js: (ByteLengthQueuingStrategy): Updated from spec. (typeIsObject): Deleted. (ByteLengthQueuingStrategy.prototype.shouldApplyBackpressure): Deleted. * streams/reference-implementation/resources/count-queuing-strategy.js: (CountQueuingStrategy): Updated from spec. (typeIsObject): Deleted. (CountQueuingStrategy.prototype.shouldApplyBackpressure): Deleted. * streams/reference-implementation/resources/streams-utils.js: (RandomPushSource.prototype.readStart.writeChunk): (RandomPushSource.prototype.readStart): Renamed stream as source (.stream.new.ReadableStream): (sequentialReadableStream): Updated from spec. (typeIsObject): Added. (createDataProperty): Added. Canonical link: https://commits.webkit.org/164046@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@185586 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2015-06-16 08:19:04 +00:00
console.warn('Tests are running without the ability to do manual garbage collection. They will still work, but coverage will be suboptimal.');
function gcRec(n) {
if (n < 1)
return {};
var temp = {i: "ab" + i + (i / 100000)};
temp += "foo";
gcRec(n-1);
}
for (var i = 0; i < 10000; i++)
gcRec(10);
}
}
Code pattern in GC tests in LayoutTests is broken https://bugs.webkit.org/show_bug.cgi?id=211595 Reviewed by Saam Barati. LayoutTests have several tests which attempt to ensure that document is not leaked. But they are broken since these tests are not correctly handling conservative GC of JavaScriptCore. These tests are taking a following approach. 1. Allocate *one* iframe doing something inside it. 2. Remove iframe from the parent document to make it released. 3. Repeatedly invoke GC and test whether (1)'s document gets collected. This is not the right approach. Since JavaScriptCore has conservative GC, it is easily possible that (1)'s pointer value remains in some of conservative roots: CPU registers, stack etc. And JavaScriptCore conservative GC scans it and keeps it alive. The above approach makes the test super flaky and any unrelated changes in JavaScriptCore and C compiler can make this test failed. This is not a problem in practice. Web pages are executing various kind of code and they clobber conservative roots. However, tests in LayoutTests are too simple to keep it alive accidentally. The right approach for conservative GC is the following. 1. Allocate *many* iframes doing something inside them with loop. By creating iframes with loop, for every iteration, it is likely that the same CPU registers and stack locations are overwritten by the last created iframe reference. This dramatically reduces the possibility for GC to find these addresses in conservative roots. 2. Remove iframes from the parent document to make them released. 3. Repeatedly invoke GC and test whether *one of (1) iframes* gets collected at least. Theoretically this is still possible that completely unrelated integer value in conservative roots can point to the reference of (1). By allocating many iframes in (1) and testing one of them, we can reduce the possibility of this conflict. This patch adds testDocumentIsNotLeaked helper function to enforce this pattern. And rewrite broken tests with this helper to make it less-flaky. * highlight/highlight-world-leak.html: * http/tests/IndexedDB/collect-IDB-objects.https.html: * http/tests/media/clearkey/collect-webkit-media-session.html: * http/tests/media/media-stream/collect-media-devices.https.html: * http/tests/resources/gc.js: Added. (window.gc.gcRec): (window.gc.window.gc): (nukeArray): (async testDocumentIsNotLeaked): * intersection-observer/no-document-leak.html: * performance-api/performance-observer-no-document-leak.html: * resources/gc.js: (nukeArray): (async testDocumentIsNotLeaked): * webanimations/leak-document-with-web-animation.html: Canonical link: https://commits.webkit.org/224541@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@261391 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-05-08 17:14:15 +00:00
// Fill array with null to avoid potential GC reachability. frames = null can be enough in 99.9% cases,
// but we are extra careful to make tests non-flaky: considering about the case that array is captured
// somewhere (like DFG constants).
function nukeArray(array)
{
for (let index = 0; index < array.length; ++index)
array[index] = null;
array.length = 0;
}
async function testDocumentIsNotLeaked(init, options = {})
{
let gcCount = options.gcCount ?? 50;
let documentCount = options.documentCount ?? 20;
let additionalCheck = options.additionalCheck ?? function () { return true; };
function waitFor(duration)
{
return new Promise((resolve) => setTimeout(resolve, duration));
}
let frameIdentifiers = await init(documentCount);
for (let counter = 0; counter < gcCount; ++counter) {
for (let i = 0; i < documentCount; ++i) {
let frameIdentifier = frameIdentifiers[i];
if (!internals.isDocumentAlive(frameIdentifier) && additionalCheck())
return "Document did not leak";
}
gc();
await waitFor(50);
}
throw new Error("Document is leaked");
}