On Mon, Jun 30, 2014 at 4:41 PM, Boris Zbarsky <[email protected]> wrote:
> On 6/30/14, 5:37 AM, Jussi Kalliokoski wrote: > >> However, the key thing is that it could be applied to any given object, >> not just >> instances of the host object. >> > > The problem with this is that it requires either allocating the hidden > state outside the object itself somewhere or requiring all objects to have > space for this hidden space or both (e.g. allocating some amount of space > for hidden state in all objects but spilling out into out-of-line slots > when you want more hidden state than that). > > So this fails one of the primary design criteria for @@create: being able > to explain the existing builtins (both ES and DOM), which allocate hidden > state inline for efficiency's sake. > > I realize you consider this an irrelevant implementation detail, but it > _is_ important. No, I don't consider potential to optimize an irrelevant implementation detail, especially when it comes to DOM. However, my knowledge in engine-level DOM optimization is relatively poor, so I'm glad to have any flaws in the idea pointed out. > As an example, here's how you could self-host Map in these terms: >> https://gist.github.com/jussi-kalliokoski/5ef02ef90c6cbb8c1a70 . In the >> example, the uninitialized state is never revealed. >> > > Right, at the cost of requiring the symbol thing, which costs both > performance and memory. > The host environment needs not use actual symbols, but I see your point. > DocumentFragment.prototype.appendChild.call(this, value); >> > > This is an interesting example. How do you expect the appendChild code to > perform the check that its this value is a Node (not necessarily > DocumentFragment, note, appendChild needs to work on any node) in this > case? Your time budget for this is 20 machine instructions as an absolute > limit, 10 preferred and your space budget is "as small as possible". > There are various approaches to that, all cost something, but the current approach is not free either. One heavy-handed optimization for the poor performance common case is to have Object's struct contain a pointer to a Node's host object, then if that's null, the object doesn't represent a Node. Depending on what you count in, that's around 4 instructions per check (I'm surprised if the current implementations do better than that). Memory footprint is 32bits on ARM and x86, and 64 bits on 64bit environments, per every Object, so pretty damn high. Performance often lies in tradeoffs, however, so an implementation might spend some extra cycles on having its own memory map of DOM nodes instead and enforce 32bit, or if they're sadistic towards developers of massive table sites, 24 bits. This can also be implemented as a binary flag where the layout is expanded if the flag is active to take the non-Node object memory footprint addition to 1 bit. Another, more general, approach that's less memory-greedy for DOM-light applications is to store that pointer (or the whole state) in the layout of objects that are "naturally" instances of Node, then even possibly use the symbol space (or something less expensive) for the state if it's not. That doesn't change the current situation's best-case performance (i.e. only instances of Node are attempted to be appended to the DOM, where you have to do the instance checks in the current situation as well), adds one check to the case of erroring out for appending a non-Node, and leaves the performance cost on the doorstep of the thing that wasn't even possible before. Aside, out of curiosity, which is more problematic in DOM currently: creation or appending of nodes? My guess is appending, but when it comes to performance I'd take data over instinct any day. > (This is not even worrying about the fact that in practice we want > different in-memory layouts for different DOM objects, These different in-memory layouts can be applied to the state behind the pointer. > that Object.prototype.toString needs to return different values for > different sorts of DOM objects Depending on how the internal layout problem is solved, that can be looked up from the internal state just as now, or the prototype chain (latter being a slight compatibility hazard). After all, no code is currently using @@initialize today so we can't break the behavior of plain object - DOM node mixins. > , or that some DOM objects need different internal hooks (akin to proxies) > from normal objects.) > The internals can again be in the internal state. However, this internal state is now explainable in terms of the spec language. For all the implementation cares, the spec may describe that the implementation uses private symbols to store the internal state, and then the implementation stores the state inline anyway, because there's no test can prove that it doesn't internally use private symbols for it. Cheers, Jussi > -Boris > _______________________________________________ > es-discuss mailing list > [email protected] > https://mail.mozilla.org/listinfo/es-discuss >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

