Mark Miller (2015-06-17T13:41:06.000Z)
Hi Yusuke, congratulations and THANK YOU! I learned something important
reading your messages. The notion that we can preserve non-observability
when making one thing a WeakMap iff we make all other WeakMaps be strong
for those same objects is true, novel, and very surprising. I have been
working on such concepts for decades and never come across anything like it.

In this case, I suspect that implementers will continue to choose the
memory leak rather than make WeakMap more complex in this way. But you have
now given them a choice, which is great! The spec does not need to change
to enable this choice. The spec is only about observable differences, and
the space optimization you suggest would be unobservable.

Your observation, being general, may find other applications even if it is
not used to optimize this one. This observation is not language specific;
it may well find application in other memory safe languages including those
yet to be invented. You have added another tool to our toolbox. You have
deepened our understanding of what is possible.




On Tue, Jun 16, 2015 at 10:45 PM, Yusuke SUZUKI <utatane.tea at gmail.com>
wrote:

> On Wed, Jun 17, 2015 at 2:29 PM, Yusuke SUZUKI <utatane.tea at gmail.com>
> wrote:
>
>> Thanks. And sorry for the late reply.
>>
>> On Wed, Jun 17, 2015 at 11:31 AM, Mark S. Miller <erights at google.com>
>> wrote:
>>
>>> Hi Yusuke, I am not sure I understood your message. Could you show some
>>> example code that would observe the observable difference you have in mind?
>>>
>>>
>>>
>>> On Tue, Jun 16, 2015 at 7:25 PM, Yusuke SUZUKI <utatane.tea at gmail.com>
>>> wrote:
>>>
>>>> Hi forks,
>>>>
>>>> In ES6 spec, template site objects are strongly referenced by the
>>>> realm.[[templateMap]].
>>>> So naive implementation leaks memory because it keeps all the site
>>>> objects in the realm.
>>>>
>>>
>> To lookup the identical template site objects, template site objects are
>> stored in the realm.[[templateMap]].
>> So they are strongly referenced and the naive implementation leaks memory.
>>
>> // By writing the following code, we can leak memory that GC cannot
>> collect.
>>
>> function tag(siteObject)
>> {
>>     return siteObject;
>> }
>>
>> for (var i = 0;; ++i) {
>>     eval("tag`" + i + "`");
>> }
>>
>>
>>>> However, we can alleviate this situation.
>>>> Because template site objects are frozen completely, it behaves as if
>>>> it's a primitive value.
>>>> It enables the implementation to reference it from the realm weakly.
>>>> When all disclosed site objects are not referenced, we can GC them because
>>>> nobody knows the given site object is once collected (& re-generated).
>>>>
>>>
>> By implementing the realm.[[templateMap]] as WeakMap, we can alleviate
>> this situation.
>>
>> function tag(siteObject) {
>>     // Since siteObject is frozen, we cannot attach a property to it.
>>     // So if nobody has the reference to the siteObject, we can collect
>> this siteObject since identity can not be tested across already collected &
>> newly created site object.
>> }
>>
>>
>>>
>>>> But, even if the object is frozen, we can bind the property with it
>>>> indirectly by using WeakMap.
>>>> As a result, if the site objects are referenced by the realm weakly,
>>>> users can observe it by using WeakMap.
>>>>
>>>
>> var map = new WeakMap();
>> function tag(siteObject) {
>>     return siteObject;
>> }
>>
>> var siteObject = tag`hello`;
>> map.set(siteObject, true);
>>
>> gc();  // If realm.[[templateMap]] is implemente by the WeakMap,
>> siteObject will be collected.
>>
>> var siteObject = tag`hello`;
>>
>> map.get(siteObject);  // false, but should be true.
>>
>>
>>
>>>
>>>> To avoid this situation, we need to specially handle template site
>>>> objects in WeakMap; WeakMap refers template site objects strongly (if we
>>>> choose the weak reference implementation for realm.[[templateMap]]).
>>>> But this may complicate the implementation and it may prevent
>>>> implementing WeakMap as per-object table (it can be done, but it is no
>>>> longer simple private symbols).
>>>>
>>>
>> var map = new WeakMap();
>> function tag(siteObject) {
>>     return siteObject;
>> }
>>
>> tag`hello`;
>>
>> gc();  // siteObject can be collected because there's no reference to it
>> if the [[templateMap]] is implemented as WeakMap.
>>
>> var siteObject = tag`hello`;
>>
>> map.set(siteObject, true);  // To avoid the previously described
>> situation, WeakMap specially handles the siteObject. It is now refereneced
>> strongly by the WeakMap.
>>
>> gc();
>>
>> var siteObject = tag`hello`;
>>
>> map.get(siteObject);  // true
>>
>> // And if WeakMap is collected, siteObject can be collected.
>>
>
> Fix.
>
>
> var map = new WeakMap();
> function tag(siteObject) {
>     return siteObject;
> }
>
> tag`hello`;
>
> gc();  // siteObject can be collected because there's no reference to it
> if the [[templateMap]] is implemented as WeakMap.
>
> (function () {
>     var siteObject = tag`hello`;
>     map.set(siteObject, true);  // To avoid the previously described
> situation, WeakMap specially handles the siteObject. It is now refereneced
> strongly by the WeakMap.
> }());
>
> gc();
>
> (function () {
>     var siteObject = tag`hello`;
>     map.get(siteObject);  // true
> }());
>
> // And if WeakMap is collected, siteObject can be collected.
> map = null;
> gc();
>
>
>
>
>>
>>
>>>
>>>> Is it intentional semantics? I'd like to hear about this.
>>>> (And please point it if I misunderstood)
>>>>
>>>> Best Regards,
>>>> Yusuke Suzuki
>>>>
>>>> _______________________________________________
>>>> es-discuss mailing list
>>>> es-discuss at mozilla.org
>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>
>>>>
>>>
>>>
>>> --
>>>     Cheers,
>>>     --MarkM
>>>
>>
>>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>


-- 
Text by me above is hereby placed in the public domain

  Cheers,
  --MarkM
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150617/f7fcb775/attachment.html>
d at domenic.me (2015-07-07T01:39:05.868Z)
congratulations and THANK YOU! I learned something important
reading your messages. The notion that we can preserve non-observability
when making one thing a WeakMap iff we make all other WeakMaps be strong
for those same objects is true, novel, and very surprising. I have been
working on such concepts for decades and never come across anything like it.

In this case, I suspect that implementers will continue to choose the
memory leak rather than make WeakMap more complex in this way. But you have
now given them a choice, which is great! The spec does not need to change
to enable this choice. The spec is only about observable differences, and
the space optimization you suggest would be unobservable.

Your observation, being general, may find other applications even if it is
not used to optimize this one. This observation is not language specific;
it may well find application in other memory safe languages including those
yet to be invented. You have added another tool to our toolbox. You have
deepened our understanding of what is possible.