diff --git a/spec.html b/spec.html index 7dd4868c0d6..c3ccce1ede6 100644 --- a/spec.html +++ b/spec.html @@ -7839,6 +7839,11 @@
This, along with the liveness guarantee in the memory model, ensures that all ~SeqCst~ writes eventually become observable to all agents.
+ +This specification does not make any guarantees that any object will be garbage collected. Objects which are not live may be released after long periods of time, or never at all. For this reason, this specification uses the term "may" when describing behaviour triggered by garbage collection.
+ +The semantics of WeakRef and FinalizationRegistry objects is based on two operations which happen at particular points in time:
+ +Neither of these actions (ClearKeptObjects or CleanupFinalizationRegistry) may interrupt synchronous ECMAScript execution. Because hosts may assemble longer, synchronous ECMAScript execution runs, this specification defers the scheduling of ClearKeptObjects and CleanupFinalizationRegistry to the host environment.
+ +Some ECMAScript implementations include garbage collector implementations which run in the background, including when ECMAScript is idle. Letting the host environment schedule CleanupFinalizationRegistry allows it to resume ECMAScript execution in order to run finalizer work, which may free up held values, reducing overall memory usage.
+For some set of objects _S_, a hypothetical WeakRef-oblivious execution with respect to _S_ is an execution whereby the abstract operation WeakRefDeref of a WeakRef whose referent is an element of _S_ always returns *undefined*.
+ +At any point during evaluation, a set of objects _S_ is considered live if either of the following conditions is met:
+ +Presence of an object in a field, an internal slot, or a property does not imply that the object is live. For example if the object in question is never passed back to the program, then it cannot be observed.
+ +This is the case for keys in a WeakMap, members of a WeakSet, as well as the [[WeakRefTarget]] and [[UnregisterToken]] fields of a FinalizationRegistry Cell record.
+ +The above definition implies that, if a key in a WeakMap is not live, then its corresponding value is not necessarily live either.
+At any time, if a set of objects _S_ is not live, an ECMAScript implementation may perform the following steps atomically:
+ +Together with the definition of liveness, this clause prescribes legal optimizations that an implementation may apply regarding WeakRefs.
+ +It is possible to access an object without observing its identity. Optimizations such as dead variable elimination and scalar replacement on properties of non-escaping objects whose identity is not observed are allowed. These optimizations are thus allowed to observably empty WeakRefs that point to such objects.
+ +On the other hand, if an object's identity is observable, and that object is in the [[WeakRefTarget]] internal slot of a WeakRef, optimizations such as rematerialization that observably empty the WeakRef are prohibited.
+ +Because calling HostEnqueueFinalizationRegistryCleanupJob is optional, registered objects in a FinalizationRegistry do not necessarily hold that FinalizationRegistry live. Implementations may omit FinalizationRegistry callbacks for any reason, e.g., if the FinalizationRegistry itself becomes dead, or if the application is shutting down.
+Implementations are not obligated to empty WeakRefs for maximal sets of non-live objects.
+If an implementation chooses a non-live set _S_ in which to empty WeakRefs, it must empty WeakRefs for all objects in _S_ simultaneously. In other words, an implementation must not empty a WeakRef pointing to an object _obj_ without emptying out other WeakRefs that, if not emptied, could result in an execution that observes the Object value of _obj_.
+The abstract operation HostEnqueueFinalizationRegistryCleanupJob takes argument _finalizationRegistry_ (a FinalizationRegistry). HostEnqueueFinalizationRegistryCleanupJob is an implementation-defined abstract operation that is expected to call CleanupFinalizationRegistry(_finalizationRegistry_) at some point in the future, if possible. The host's responsibility is to make this call at a time which does not interrupt synchronous ECMAScript code execution.
+The abstract operation ClearKeptObjects takes no arguments. ECMAScript implementations are expected to call ClearKeptObjects when a synchronous sequence of ECMAScript executions completes. It performs the following steps when called:
+The abstract operation AddToKeptObjects takes argument _object_ (an Object). It performs the following steps when called:
+The abstract operation CleanupFinalizationRegistry takes argument _finalizationRegistry_ (a finalization registry object). It performs the following steps when called:
+See
See
See
See
See
See
WeakMap objects are collections of key/value pairs where the keys are objects and values may be arbitrary ECMAScript language values. A WeakMap may be queried to see if it contains a key/value pair with a specific key, but no mechanism is provided for enumerating the objects it holds as keys. If an object that is being used as the key of a WeakMap key/value pair is only reachable by following a chain of references that start within that WeakMap, then that key/value pair is inaccessible and is automatically removed from the WeakMap. WeakMap implementations must detect and remove such key/value pairs and any associated resources.
+WeakMap objects are collections of key/value pairs where the keys are objects and values may be arbitrary ECMAScript language values. A WeakMap may be queried to see if it contains a key/value pair with a specific key, but no mechanism is provided for enumerating the objects it holds as keys. In certain conditions, objects which are not live are removed as WeakMap keys, as described in
An implementation may impose an arbitrarily determined latency between the time a key/value pair of a WeakMap becomes inaccessible and the time when the key/value pair is removed from the WeakMap. If this latency was observable to ECMAScript program, it would be a source of indeterminacy that could impact program execution. For that reason, an ECMAScript implementation must not provide any means to observe a key of a WeakMap that does not require the observer to present the observed key.
WeakMap objects must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of key/value pairs in the collection. The data structure used in this WeakMap objects specification are only intended to describe the required observable semantics of WeakMap objects. It is not intended to be a viable implementation model.
WeakSet objects are collections of objects. A distinct object may only occur once as an element of a WeakSet's collection. A WeakSet may be queried to see if it contains a specific object, but no mechanism is provided for enumerating the objects it holds. If an object that is contained by a WeakSet is only reachable by following a chain of references that start within that WeakSet, then that object is inaccessible and is automatically removed from the WeakSet. WeakSet implementations must detect and remove such objects and any associated resources.
+WeakSet objects are collections of objects. A distinct object may only occur once as an element of a WeakSet's collection. A WeakSet may be queried to see if it contains a specific object, but no mechanism is provided for enumerating the objects it holds. In certain conditions, objects which are not live are removed as WeakSet elements, as described in
An implementation may impose an arbitrarily determined latency between the time an object contained in a WeakSet becomes inaccessible and the time when the object is removed from the WeakSet. If this latency was observable to ECMAScript program, it would be a source of indeterminacy that could impact program execution. For that reason, an ECMAScript implementation must not provide any means to determine if a WeakSet contains a particular object that does not require the observer to present the observed object.
WeakSet objects must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of elements in the collection. The data structure used in this WeakSet objects specification is only intended to describe the required observable semantics of WeakSet objects. It is not intended to be a viable implementation model.
A WeakRef is an object that is used to refer to a target object without preserving it from garbage collection. WeakRefs can be dereferenced to allow access to the target object, if the target object hasn't been reclaimed by garbage collection.
+ +The WeakRef constructor:
+When the `WeakRef` function is called with argument _target_, the following steps are taken:
+The WeakRef constructor:
+The initial value of `WeakRef.prototype` is the intrinsic %WeakRef.prototype% object.
+This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.
+The WeakRef prototype object:
+The initial value of `WeakRef.prototype.constructor` is the intrinsic object %WeakRef%.
+ +This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.
+The following steps are taken:
+If the WeakRef returns a _target_ Object that is not *undefined*, then this _target_ object should not be garbage collected until the current execution of ECMAScript code has completed. The AddToKeptObjects operation makes sure read consistency is maintained.
+ +
+ target = { foo: function() {} };
+ let weakRef = new WeakRef(target);
+
+ ... later ...
+
+ if (weakRef.deref()) {
+ weakRef.deref().foo();
+ }
+
+
+ In the above example, if the first deref does not evaluate to *undefined* then the second deref cannot either.
+The initial value of the @@toStringTag property is the String value *"WeakRef"*.
+This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.
+The abstract operation WeakRefDeref takes argument _weakRef_ (a WeakRef). It performs the following steps when called:
+This abstract operation is defined separately from WeakRef.prototype.deref strictly to make it possible to succinctly define liveness.
+WeakRef instances are ordinary objects that inherit properties from the WeakRef prototype. WeakRef instances also have a [[WeakRefTarget]] internal slot.
+A FinalizationRegistry is an object that manages registration and unregistration of cleanup operations that are performed when target objects are garbage collected.
+ +The FinalizationRegistry constructor:
+When the `FinalizationRegistry` function is called with argument _cleanupCallback_, the following steps are taken:
+The FinalizationRegistry constructor:
+The initial value of `FinalizationRegistry.prototype` is the intrinsic %FinalizationRegistry.prototype% object.
+This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.
+The FinalizationRegistry prototype object:
+The initial value of `FinalizationRegistry.prototype.constructor` is the intrinsic object %FinalizationRegistry%.
+The following steps are taken:
+Based on the algorithms and definitions in this specification, _cell_.[[HeldValue]] is live when _cell_ is in _finalizationRegistry_.[[Cells]]; however, this does not necessarily mean that _cell_.[[UnregisterToken]] or _cell_.[[Target]] are live. For example, registering an object with itself as its unregister token would not keep the object alive forever.
+The following steps are taken:
+The initial value of the @@toStringTag property is the String value *"FinalizationRegistry"*.
+This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.
+FinalizationRegistry instances are ordinary objects that inherit properties from the FinalizationRegistry prototype. FinalizationRegistry instances also have [[Cells]] and [[CleanupCallback]] internal slots.
+See
HostEnqueueFinalizationRegistryCleanupJob(...)
HostEnqueuePromiseJob(...)
HostEnsureCanCompileStrings(...)
HostFinalizeImportMeta(...)