mirror of https://github.com/tc39/test262.git
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:
parent
77b1c787e8
commit
f225229f85
|
@ -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);
|
|
@ -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);
|
Loading…
Reference in New Issue