<div dir="ltr">Hi Ryan,<div><br></div><div>   just one small thing to add to your description...</div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Aug 14, 2015 at 6:43 PM, Ryan Macnak <span dir="ltr">&lt;<a href="mailto:rmacnak@gmail.com" target="_blank">rmacnak@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> <br><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Aug 14, 2015 at 1:53 AM, Clément Bera <span dir="ltr">&lt;<a href="mailto:bera.clement@gmail.com" target="_blank">bera.clement@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> <br><div dir="ltr"><div>Hello Stefan, Ryan and all,</div><div><br></div><div>I checked the paper where I read it (unfortunately it was rejected) and the exact sentence was:<br></div><br><i>In some implementations (e.g. Dart [22] and PyPy [3]), object header and attribute storage can be separated, so the attribute storage can be relocated in order to grow. </i><br><i>[3]C. F. Bolz. <a href="http://morepypy.blogspot.fr/2010/11/efficiently-implementing-python-objects.html" target="_blank">Efficiently implementing objects with maps</a>, 2010. <br>[22]F. Schneider. <a href="https://www.dartlang.org/slides/2013/04/compiling-dart-to-efficient-machine-code.pdf" target="_blank">Compiling dart to efficient machine code</a>, 2012.</i><div><br></div><div>When I read F. Boltz. post, it looks like to me that in Pypy each instance of a class has a pointer to its map and its storage. The storage seems to be at a different location than the object&#39;s header and holds the instance variable values. To me it sounds very much like the object is &#39;split&#39; to be able to grow the storage if a new instance variable is added for a specific instance. Accessing an object instance variable requires an extra indirection through the storage pointer. Is there something I miss there ? It looks like the paper we wrote with Eliot could definitely apply there in order to speed up instance variable access by removing the indirection to the storage.</div><div><br></div><div>In the talk compiling dart to efficient machine code, one section deals about Javascript and V8. Objects are described in V8 (slide 29) as having a pointer to their Map, their properties and their elements, which to me sounds similar to Cincom Smalltalk design (the object header is separated from the value of the instance variables). However the talk then discusses the Dart implementation and it&#39;s not the case there. I guess I got confused as the talk is about Dart but this part of the talk is about Javascript.</div></div></blockquote><div><br></div><div>The split in V8 isn&#39;t between an object&#39;s header and its properties. It is between the header + the fast properties the hidden-class machinery could figure out ahead of allocation and the slow properties it could not. </div></div></div></div></blockquote><div><br></div><div>Talking with members of the V8 team at ISMM I was told that V8 also has a split between an array&#39;s header and its elements.  So at least for arrays there is always an indirection.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>For instance, if I write well-behaved code like</div><div><br></div><div>function Point(x, y) {</div><div>  this.x = x;</div><div>  this.y = y;</div><div>}</div><div><br></div><div>var p = new Point(3, 4);</div><div><br></div><div>p would in one block have a reference to its hidden-class, the properties &#39;x&#39; and &#39;y&#39;, a bit of speculative space for properties that might be added later, and space to hang a properties overflow array. Access to x or y is a simple direct load and we&#39;re happy.</div><div><br></div><div>However, if I start treating objects like dictionaries as Javascript allows, and later I do,</div><div><br></div><div>p.someNewIdentifier = 5;</div><div><br></div><div>enough times or,</div><div><br></div><div>p[&quot;not an identifier&quot;] = 6;</div><div><br></div><div>the new properties go into the overflow array, and they are more costly to access.</div><div><br></div><div>The actual mechanics are bit more complicated than this depending on the property name and value and the size of the object. Adding a function property may create a new hidden-class but leave the object&#39;s layout unchanged. Adding a property whose name isn&#39;t an identifier or too many properties may transition the object to dictionary-mode, where all the properties are indirect. Adding a property whose name is an identifier may try to use some of the left-over inline slots first and try give objects that add the same properties the same hidden class. So if something like</div><div><br></div><div>var p = new Point(3, 4);</div><div>p.z = 6;</div><div><br></div><div>happens often, all these objects share a hidden-class and we reduce polymorphism.</div><div><br></div><div>If I do, &#39;delete p.x;&#39; the slot where x was is filled in with a special value indicating the property no longer exists (&#39;the hole&#39;).</div><div><br></div><div>The Spur model might be interesting in the Javascript context if it is used to avoid the memory overhead of allocating with extra space to deal with overflow.</div></div></div></div>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>