Description
The AsyncContext store is a mapping from AsyncContext.Variable
objects to arbitrary JS values, which cannot be iterated, and whose entries can't be observed unless you have the AsyncContext.Variable
key. This would allow implementing the store as a weak map, where the values need not be kept alive after the key has been GC'd.
As far as the spec is concerned, an object or symbol in an internal field isn't considered to be live if it cannot be returned to JS (and isn't compared by identity with other values). So this allows implementations to treat the store as a weak map. Implementations are also not required to do so, since the spec doesn't require that any particular non-live object is observed as having been GC'd as far as FinalizationRegistry
and WeakRef
are concerned. So the AsyncContext spec text as written allows both options.
This issue has previously been discussed in the biweekly meetings or in the Matrix chatroom for the proposal, with the conclusion being that the AsyncContext store could be implemented as a regular (non-weak) map. I think this was mostly advocated for by @littledan and @legendecas, arguing that in almost every use case the AsyncContext.Variable
keys would be kept alive for the duration of the program.
However, there are no issues opened (or closed) about this, and no mention of this on the readme, so this seems to be a pretty obscure point. In fact, I recently submitted a design doc for the implementation of AsyncContext in V8, which didn't mention anything about GC with respect to the entries of the store, but it seems like reviewers still assumed that it would behave like a weak map.
Since this affects not only memory usage but also GC performance, I think that if we decide that the store should be a strong map, we should have good and documented reasons for it, and set expectations. This would have to be mentioned in the readme and in a note in the spec text, as well as mentioned in plenary.