Yusuke SUZUKI (2015-06-17T05:29:41.000Z)
d at domenic.me (2015-07-07T01:38:46.445Z)
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? 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. ```js // 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. ```js 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. >> ```js 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). >> ```js 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(); ```
d at domenic.me (2015-07-07T01:37:59.100Z)
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? 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. ```js // 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. ```js 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. >> ```js 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). >> ```js 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. ```