Hi jecel,<br><br><div class="gmail_quote">On Wed, May 13, 2009 at 3:46 PM, Jecel Assumpcao Jr <span dir="ltr">&lt;<a href="mailto:jecel@merlintec.com">jecel@merlintec.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>
I have read the description of the stack vm again:<br>
<br>
&gt; <a href="http://www.mirandabanda.org/cogblog/2009/01/14/under-cover-contexts-and-the-big-frame-up/" target="_blank">http://www.mirandabanda.org/cogblog/2009/01/14/under-cover-contexts-and-the-big-frame-up/</a><br>
<br>
It seems to me that it would be possible to keep the arguments and the<br>
remaining temporaries together. This would require keeping the numTemps<br>
in the flags word instead of the numArgs. It would also mean moving the<br>
code to nil out the temps towards the beginning of<br>
#internalActivateNewMethod and #activateNewClosureMethod:numArgs:<br>
(before pushing the IP). The idea is that then #temporary:in: would<br>
become simpler, which is important since it is a very popular operation.</blockquote><div><br></div><div>But the split arguments/temporaries organization is determined by frame build order, and the anticipation of a JIT.</div>
<div>The caller pushes receiver and arguments, and in a JIT then pushes the return pc (as part of the call instruction that makes up the send).  Then a frame is built at the end of which temporaries are initialized.  In the JIT there will always be at least the return pc/caller&#39;s saved instruction pointer between the arguments and the temporaries, and since the offsets to access each can be determined at compile time the cost of separating them is low.</div>
<div><br></div><div>So while one could I don&#39;t see that its worth-while.  Even if one did keep the arguments and temporaries together one would still have the stack contents separate from the arguments and temporaries and temporary access bytecodes can still access those so arguably one would still have to check the index against the temp count.</div>
<div><br></div><div>In practice the cost is not that high in the stack vm, or at least the stack vm is still substantially faster than the context vm with arguments and temporaries split.  And in the JIT it really isn&#39;t a performance issue at all.</div>
<div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">This change would make it a little harder to fix the bug in #marryFrame:<br>
but I don&#39;t see any other changes that would be needed. Is there some<br>
important design issue with keeping the arguments and temps separate<br>
that I am missing? I can imagine a compiler that avoids initially<br>
filling out the temps with nils by creating them lazily on first<br>
assignment and that wouldn&#39;t work with my change. But I don&#39;t know if<br>
this is a planned feature (it complicates reflection a bit since you<br>
have to fake the uninitialized temps in order not to confuse the<br>
debugger).<br>
<br>
I found the use of a one byte flag to indicate that the context pointer<br>
is valid interesting since it seems to me that the same information is<br>
available by looking at the pointer itself (nil or not). Is this just a<br>
performance issue or are there situations where the flag can be zero but<br>
the pointer is not nil?</blockquote><div><br></div><div>It was my original intent to avoid having to write the context pointer field.  It used to be important to avoid unnecessary writes but on current processors with good cache interfaces I don&#39;t think avoiding the write makes any difference and I write it anyway in the current VM (which has moved on a little from the blog posts).  But it is quicker to test the flag than test against nil simply because he reference to nil is an arbitrary 32-bit value, not simply 0 or 1.</div>
<div><br></div><div>In the JIT the flag is a bit in the method reference&#39;s LSBs and is set for free on frame build.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Some small details that seem like errors to me but could be a lack of<br>
understanding on my part:<br>
<br>
- the drawing above the definition of &quot;activateNewClosureMethod:<br>
blockClosure numArgs: numArgs&quot; shows the flag word right after fp but<br>
the code indicates that it should be a method pointer instead.</blockquote><div><br></div><div>You&#39;re right.  I missed out the methods my accident in the left-hand stack page.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
- callersFPOrNull is used in #commonCallerReturn but not assigned to. Ah<br>
- I see that the first definition near the top of the text is<br>
incomplete. The real definition in the discussion about return does have<br>
the assignment.<br>
<br>
Cheers,<br>
<font color="#888888">-- Jecel</font></blockquote><div><br></div><div>Thanks! </div></div><br>