Removal of WeakMap/WeakSet clear

Allen Wirfs-Brock allen at wirfs-brock.com
Wed Nov 26 11:09:40 PST 2014


On Nov 26, 2014, at 10:22 AM, Claude Pache wrote:

> 
> The root of the issue, is that WeakMaps are thought as a tool for two unrelated use cases. Quoting [1]:
> 
>> (...) WeakMaps were motivate[d] by two distinct use cases.  Soft fields and object-keyed caches.
> 
> Now, in short, for the "soft fields" use case, a `.clear()` method is unwanted, but for the "object-keyed caches" use case, a `.clear()` method is welcome.
> 
> —Claude
> 
> [1]: https://esdiscuss.org/topic/weakmap-clear-and-inverted-implementations

Let's ignore security for  the moment.

If  WeakMaps/WeakSets are not inspectable (via iteration) and do not have a clear operation, then the inverted implementation technique can be use used.  This technique eliminates significant GS complexity.

The ability to iterate over the elements of a WeakMap/Set would make implementation specific (and probably non-deterministic) GC timing observable to ES programs.  Non-deterministic and observable implementation specific behavior is bad for interoperability.  That reason alone is enough for TC39 to choose to not make WeakMaps/Sets non-iterable as interoperability is one of our highest priorities. 

That said, there are use cases for iterable weak collections if you are willing to tolerate the non-determinism and observability of the GC.  Implementations supporting situation where those use cases are important might choose to provide a non-standard IterableWeakMap/Set implementation and there would be no particular reason for not including a 'clear' method.   If there of evidence of enough utility for such collections TC39 might even decide to standardize them.  In which case we would probably but them into a standard module that needs to be explicitly imported.  Use of the module would be a flag that the program may have non-deterministic behavior.

Allen


> 
> 
>> Le 26 nov. 2014 à 18:33, Katelyn Gadd <kg at luminance.org> a écrit :
>> 
>> Is there a detailed rationale for this somewhere? Making typical
>> applications pay the cost here for a specific security scenario seems
>> really bizarre to me. Clearing standard library data structures is an
>> incredibly common operation. If you want to ensure that someone can't
>> clear the map/set, shouldn't you be handing them an encapsulated
>> version of the data structure? This seems like a corner case that
>> shouldn't justify removing an important primitive.
>> 
>> If you have a clear method, the security problem seems solved by
>> wrapping it in an object or using a proxy to deny the ability to clear
>> (you hide the actual map/set, so it can't be cleared - you expose only
>> the operations you want to expose).
>> 
>> If you don't have a clear method, anyone wanting to clear the data
>> structure has to throw it away and allocate a new one. This has
>> significant disadvantages:
>> The new structure starts empty at a default size, so repopulating it
>> will have to grow the buffer multiple times - this is undesirable for
>> cases where you are reusing a single data structure to store state for
>> a long-running application.
>> The allocation adds to GC and memory pressure for a long-running
>> application that needs to clear data structures frequently. Were it a
>> lightweight data type this would matter less, but a typical map
>> instance with data in it can occupy a considerable amount of space in
>> the heap.
>> Being able to clear the structure now requires that all consumers have
>> support for replacing their reference(s) to the old map with the new
>> one. This makes it harder to maintain encapsulation because you may
>> have saved a reference to the map in a private property or within a
>> closure. Now you need to add accessibility points to everything that
>> might retain the map so that you can update the reference. Or, you
>> have to encapsulate maps and sets just to recreate the clear operation
>> that should have been there to begin with.
>> 
>> In either case, encapsulation or shielding the container behind a
>> proxy is necessary. I insist that the common case is the one that
>> shouldn't have to encapsulate, because optimizing for that case will
>> benefit the vast majority of web applications that use it and the
>> penalty to security-sensitive cases is small.
>> 
>> -kg
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
> 
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20141126/1c2801c5/attachment.html>


More information about the es-discuss mailing list