Remove FinalizationRegistry tests that depend on nondeterministic GC

In these tests, cleanupSome() would have optionally emptied the
FinalizationRegistry synchronously and called the finalization callbacks.
Without cleanupSome(), there is no way to observe a FinalizationRegistry
being emptied using "pure" ECMAScript: FinalizationRegistry doesn't get
cleaned up until the microtask queue is empty, and without external APIs
such as setTimeout() there is no way to pause execution until after the
microtask queue is empty.

Non-deterministic tests are not that useful anyway; these tests are
probably better left to implementations' internal testing strategies.
This commit is contained in:
Philip Chimento 2024-09-25 09:43:10 -07:00 committed by Philip Chimento
parent 77b1c787e8
commit f225229f85
2 changed files with 0 additions and 159 deletions

View File

@ -1,96 +0,0 @@
// Copyright (C) 2019 Leo Balter. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-finalization-registry-target
description: >
cleanupCallback has only one optional chance to be called for a GC that cleans
up a registered Object target.
info: |
FinalizationRegistry.prototype.cleanupSome ( [ _callback_ ] )
3. If _callback_ is present and IsCallable(_callback_) is *false*, throw a
*TypeError* exception.
4. Perform ? CleanupFinalizationRegistry(_finalizationRegistry_, _callback_).
5. Return *undefined*.
Execution
At any time, if a set of objects and/or symbols _S_ is not live, an ECMAScript
implementation may perform the following steps atomically:
1. For each element _value_ of _S_, do
...
b. For each FinalizationRegistry _fg_ such that _fg_.[[Cells]] contains a
Record _cell_ such that _cell_.[[WeakRefTarget]] is _value_,
i. Set _cell_.[[WeakRefTarget]] to ~empty~.
ii. Optionally, perform HostEnqueueFinalizationRegistryCleanupJob(_fg_).
features: [FinalizationRegistry.prototype.cleanupSome, FinalizationRegistry, async-functions, host-gc-required]
flags: [async, non-deterministic]
includes: [async-gc.js, compareArray.js]
---*/
let cleanupCallback = 0;
let holdings = [];
function cb(holding) {
holdings.push(holding);
}
let finalizationRegistry = new FinalizationRegistry(function() {
cleanupCallback += 1;
});
function emptyCells() {
let target = {};
finalizationRegistry.register(target, 'a');
let prom = asyncGC(target);
target = null;
return prom;
}
emptyCells().then(async function() {
await Promise.resolve(1);
finalizationRegistry.cleanupSome(cb);
// cleanupSome will be invoked if there are empty cells left. If the
// cleanupCallback already ran, then cb won't be called.
let expectedCalled = cleanupCallback === 1 ? 0 : 1;
// This asserts the registered object was emptied in the previous GC.
assert.sameValue(holdings.length, expectedCalled, 'cleanupSome callback for the first time');
// At this point, we can't assert if cleanupCallback was called, because it's
// optional. Although, we can finally assert it's not gonna be called anymore
// for the other executions of the Garbage Collector.
// The chance of having it called only happens right after the
// cell.[[WeakRefTarget]] is set to empty.
assert(cleanupCallback >= 0, 'cleanupCallback might be 0');
assert(cleanupCallback <= 1, 'cleanupCallback might be 1');
// Restoring the cleanupCallback variable to 0 will help us asserting the
// finalizationRegistry callback is not called again.
cleanupCallback = 0;
await $262.gc();
await Promise.resolve(2); // tick
finalizationRegistry.cleanupSome(cb);
assert.sameValue(holdings.length, expectedCalled, 'cleanupSome callback is not called anymore, no empty cells');
assert.sameValue(cleanupCallback, 0, 'cleanupCallback is not called again #1');
await $262.gc();
await Promise.resolve(3); // tick
finalizationRegistry.cleanupSome(cb);
assert.sameValue(holdings.length, expectedCalled, 'cleanupSome callback is not called again #2');
assert.sameValue(cleanupCallback, 0, 'cleanupCallback is not called again #2');
if (holdings.length) {
assert.compareArray(holdings, ['a']);
}
await $262.gc();
}).then($DONE, resolveAsyncGC);

View File

@ -1,63 +0,0 @@
// Copyright (C) 2019 Mathieu Hofman. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-finalization-registry.prototype.unregister
description: >
Cannot unregister a cell referring to an Object that has been cleaned up
info: |
FinalizationRegistry.prototype.cleanupSome ( [ _callback_ ] )
4. Perform ? CleanupFinalizationRegistry(_finalizationRegistry_, _callback_).
CleanupFinalizationRegistry ( _finalizationRegistry_ ):
3. While _finalizationRegistry_.[[Cells]] contains a Record _cell_ such that
_cell_.[[WeakRefTarget]] is ~empty~, then an implementation may perform the
following steps:
a. Choose any such _cell_.
b. Remove _cell_ from _finalizationRegistry_.[[Cells]].
c. Perform ? HostCallJobCallback(_callback_, *undefined*,
« _cell_.[[HeldValue]] »).
FinalizationRegistry.prototype.unregister ( _unregisterToken_ )
4. Let _removed_ be *false*.
5. For each Record { [[WeakRefTarget]], [[HeldValue]], [[UnregisterToken]] }
_cell_ of _finalizationRegistry_.[[Cells]], do
a. If _cell_.[[UnregisterToken]] is not ~empty~ and
SameValue(_cell_.[[UnregisterToken]], _unregisterToken_) is *true*, then
i. Remove _cell_ from _finalizationRegistry_.[[Cells]].
ii. Set _removed_ to *true*.
6. Return _removed_.
features: [FinalizationRegistry.prototype.cleanupSome, FinalizationRegistry, host-gc-required]
includes: [async-gc.js]
flags: [async, non-deterministic]
---*/
var value = 'target!';
var token = {};
var finalizationRegistry = new FinalizationRegistry(function() {});
function emptyCells() {
var target = {};
finalizationRegistry.register(target, value, token);
var prom = asyncGC(target);
target = null;
return prom;
}
emptyCells().then(function() {
var called = 0;
var holdings = [];
finalizationRegistry.cleanupSome(function cb(holding) {
called += 1;
holdings.push(holding);
});
assert.sameValue(called, 1);
assert.sameValue(holdings.length, 1);
assert.sameValue(holdings[0], value);
var res = finalizationRegistry.unregister(token);
assert.sameValue(res, false, 'unregister after iterating over it in cleanup');
}).then($DONE, resolveAsyncGC);