<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><pre class="" style="widows: 1; background-color: rgb(255, 255, 255);">On 12/08/15 05:23, Chris Muller wrote:

&gt;<i class=""> [1] -- A Partial Read Barrier for Efficient Support of Live
</i>&gt;<i class=""> Object-oriented Programming
</i>&gt;<i class=""> <a href="http://conf.researchr.org/event/ismm-2015/ismm-2015-papers-a-partial-read-barrier-for-efficient-support-of-live-object-oriented-programming" class="">http://conf.researchr.org/event/ismm-2015/ismm-2015-papers-a-partial-read-barrier-for-efficient-support-of-live-object-oriented-programming</a>
</i>
&gt;For the paywall-free version:
&gt;<a href="https://hal.inria.fr/hal-01152610" class="">https://hal.inria.fr/hal-01152610</a>

&gt;Stephan
</pre></div><div class=""><br class=""></div>I’m going to take a stab at explaining what I just read (as far as I read it).&nbsp;<div class=""><br class=""></div><div class="">You’re an instance of Rectangle. You have an ivar with a Point in it. The point has ivars x and y.&nbsp;</div><div class="">This great because you can get the values of the instance of Point’s x and y when you need to.&nbsp;</div><div class="">Funny thing, though, Point was just recompiled to add methods or change ivars. Now all the instances, including yours, are junk.&nbsp;</div><div class="">Not to worry, the system has a plan and two tools to deal with it: two primitives fronted by #allInstances and #become:.&nbsp;</div><div class="">The system will find all the instances of Point with #allInstances. It will then find each and apply #become: to switch the old version with the new.&nbsp;</div><div class=""><br class=""></div><div class="">In Rectangle we get a new number in our ivar slot for the Point instance. And things are caught up. But how does that actually work? The #become: part?&nbsp;</div><div class="">I think that’s the story of three approaches to the problem with the last one being Spur.&nbsp;</div><div class=""><br class=""></div><div class="">The first way is the way used by Cincom’s VisualWorks now. It’s a two step process. To get from Rectangle to the value of x in an instance of Point we need to make two object pointer calls.&nbsp;</div><div class="">The first goes to the head object of the class Point. A second goes from there to the “body” which is a basket of slots, which in our case includes x an y. The beauty of this is that it gives #become: a focal point.&nbsp;</div><div class="">a become: b at the location of the header object and you’ve neatly swapped the address from Rectangle’s ivar to where the x and y values are.&nbsp;</div><div class=""><br class=""></div><div class="">There’s a problem. There’s trouble in paradise. We are not happy. It could be faster. We don’t want two steps. We don’t want a bridge between Rectangle and the “body” of values with the header object as the cornerstone.&nbsp;</div><div class="">We want one step, not two. That’s faster. To do that, the first thing we do is fuse the header object with the “body”. They are no longer in separate places. One word for the header and the next word is slot 1, which is for us x. The next word will have y.&nbsp;</div><div class=""><br class=""></div><div class="">The system is faster, but we have a problem. Where are all those references we need to renumber? We no longer have a neat nexus in the header object that #become: can use. No problem, we’ll sweep all of memory (aka “the heap”) to find them again. We’re getting such a boost from one step instead of two that we can afford to brute force the problem with a sweep.&nbsp;</div><div class=""><br class=""></div><div class="">And we’re happy. For a while. And then we’re not. This does not scale. We find that the larger the memory gets, then the closer we get to where sweeping the heap becomes more expensive than the gains we’re getting. There’s a plateau point, a location on the graph beyond which the memory sweep is so costly it’s eating our gains.&nbsp;</div><div class=""><br class=""></div><div class="">What to do? We want the speed of the one-step process, but we want it to scale. We create a solution called Spur.&nbsp;</div><div class=""><br class=""></div><div class="">The salient passage here in the paper is:&nbsp;</div><div class=""><br class=""></div><div class="">"This paper describes the design and implementation of efficient schema migration using direct pointers [That’s the&nbsp;“one step” business I’ve been talking about above], which consists mainly in hiding the cost of checking for forwarding pointers behind other checking operations that the system performs as part of its normal processing.”</div><div class=""><br class=""></div><div class="">Did you get that part? Let’s repeat it:&nbsp;</div><div class=""><br class=""></div><div class="">"hiding the cost of checking for forwarding pointers behind other checking operations that the system performs as part of its normal processing.”</div><div class=""><br class=""></div><div class="">Normal processing. We want to be prepared. We want to do as much as we can in anticipation of the requirement that slows things down when the memory gets big. Anticipate. Do as much as you can beforehand.&nbsp;</div><div class=""><br class=""></div><div class="">A little vague? OK, I’ll try again. Read this:&nbsp;</div><div class=""><span class="" style="font-size: 10pt; font-family: NimbusMonL;"><br class=""></span></div><div class="">"Become is therefore implemented lazily; copies of the pair of objects are created, and each original is forwarded to the matching copy; the forwarding pointer is followed when the object is encountered.”</div><div class=""><br class=""></div><div class="">I don’t understand all of that, but I did catch “lazily”. In the first of our three systems, the system is preparing all possible avenues. In Spur, I think, it is only opening avenues that need to be opened when they need to be opened. They are being opened “lazily.”&nbsp;</div><div class=""><br class=""></div><div class="">There seems to me a commonality to Spur, Cog and Sista. Don’t set the table for ten people. Wait to see how many show up. Don’t do unnecessary work. I think that’s what “lazily” means. These three also like to pay attention to what is happening over and over again and cache it for speed.&nbsp;</div><div class=""><br class=""></div><div class="">One last thing. It seems to me the reason Spur and 64-bit are related has to do with fusing the header object with the “body” object. By definition that requires a new object format, does it not?&nbsp;</div><div class=""><br class=""></div><div class="">That’s as far as I could make out. I’m sort of a big picture guy, so the details of “forwarding objects” and “partial read barriers” doesn’t interest me all that much. I like it more as a story of three versions with the last one being Spur.&nbsp;</div><div class=""><br class=""></div><div class="">FWIW,&nbsp;</div><div class="">Chris&nbsp;</div></body></html>