Yusuke SUZUKI (2015-06-17T16:15:11.000Z)
d at domenic.me (2015-07-07T01:39:22.170Z)
On Wed, Jun 17, 2015 at 10:41 PM, Mark Miller <erights at gmail.com> wrote: > 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. > Thanks for your clarification! If the target object is resilient (it can be re-generated without an observable side effects) and immutable, we can inverse strong & weak maps. In this case, strong internal Map is converted into WeakMap and user exposed WeakMap are converted into strong Map. The internal map itself cannot be collected, but, user exposed maps can be collected. So by inverting them, the target objects become collectable. > 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. > I'm planning to discuss about this implementation in JavaScriptCore because I'm an template strings implementor in JavaScriptCore. BTW, by extending the implementation slightly, we can still preserve performance optimization. When generating template site objects at first, generate it, register it to realm's WeakMap and strongly reference it in the JavaScript code site instead of realm. This is the same behavior to that immutable JSStrings are stored and strongly referenced in the JavaScript code itself. When the JavaScript code is discarded, we can collect them. And by slightly modifying the per-object table proposal, we can still support it with this change ;) We can define WeakMap as ```js class WeakMap { constructor(...) { this.privateSymbol = @privateSymbol; this.map = new Map(); } get(object) { if (object is template site object) { return this.map.get(object); } return object[this.privateSymbol]; } set(object, value) { if (object is template site object) { this.map.set(object, value); return this; } object[this.privateSymbol] = value; return this; } } ```