<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">2016-03-25 6:26 GMT+01:00 Eliot Miranda <span dir="ltr">&lt;<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi Nicolai,<br>
<div><div class="h5"><br>
&gt; On Mar 24, 2016, at 1:53 AM, Nicolai Hess &lt;<a href="mailto:nicolaihess@gmail.com">nicolaihess@gmail.com</a>&gt; wrote:<br>
&gt;<br>
&gt; Hello,<br>
&gt;<br>
&gt; we have a failing test (OCClosureCompilerTest&gt;&gt;#testDebuggerTempAccess)<br>
&gt; (fails since spur, but not related - I think).<br>
&gt;<br>
&gt; A simple example to reproduce the behavior:<br>
&gt; | local1 remote1|<br>
&gt; remote1:=4.<br>
&gt; local1 :=3.<br>
&gt; [:i | |c|<br>
&gt;     c := local1.<br>
&gt;     remote1 := i.<br>
&gt;     i halt.<br>
&gt;     &quot;local1:=25.  &lt;-- evaluate during debugging&quot;<br>
&gt;      ] value:1.<br>
&gt; Transcript show:local1;cr.<br>
&gt; Transcript show:remote1;cr.<br>
&gt; (Executing this code and evaluating &quot;local:=25&quot; after the debugger halts for<br>
&gt; &quot;i halt&quot; will modify the var &quot;remote1&quot; instead of &quot;local1&quot;, as this is a vector tempvar , proceeding<br>
&gt; the execution will crash at accessing the remote1 value).<br>
&gt;<br>
&gt;<br>
&gt; The purpose of the testDebuggerTempAccess test case is, evaluating code<br>
&gt; that changes the value of a copied temp var *does not* change the value of<br>
&gt; this var in the outer context. (see comment in the test case:<br>
&gt; &quot;this is not 25 as the var is a local, non escaping variable that was copied into the block,<br>
&gt;     If the compiler would have known about the write, it would have made the var escaping&quot;.<br>
&gt; )<br>
&gt;<br>
&gt; But the implementation (OCCopyingTempVariable&gt;&gt;#writeFromContext: aContext scope: contextScope value: aValue)<br>
&gt; explicitly iterates through all outer context(s) and changes the vars as well.<br>
&gt;<br>
&gt; 1. Question: Who is right?<br>
<br>
</div></div>What do you mean?  Because the closure model is as it is (for very good reason) the computer copies temporaries whose values cannot change during the execution of a block into that block if the block references the variable.  If the debugger is to support updating such copied variables then it must create the illusion of &quot;the variable being updated&quot; because there isn&#39;t just one variable.<br></blockquote><div><br></div><div>I know that it only operates on a copy of this var (if the var is only read (in the original code)), but you *can* evaluate code<br></div><div>during debugging, that can modify the var.<br></div><div>I don&#39;t know why or if we want to support that. I just see a failing test case that tries to do exactly that.<br></div><div>And the supposed behavior is, that the outer context variable value does not change. But this test fails.<br><br></div><div>I tried similar code in squeak, and there the outer context var does not change:<br><br>|local remote outerContext|<br>local :=1.<br>remote:=2.<br>outerContext := thisContext.<br>(1 to:1) do:[:i |<br>    remote := i.<br>    Transcript show:local;cr.<br>    i halt.<br>    &quot;remote:=20&quot;<br>    &quot;local:=10&quot;<br>    &quot;outerContext tempAt:1 put:30&quot;<br>    Transcript show:local;cr.<br>    ].<br>Transcript show:local;cr.<br>Transcript show:remote;cr.<br><br><br></div><div>If the debugger halts at &quot;i halt&quot; and you evaluate the code<br><br>    &quot;remote:=20&quot;<br>the remote value changes for t he block context and for its outer context - OK<br>    &quot;local:=10&quot;<br>the local value changes for the block context but not for its outer context - OK<br>    &quot;outerContext tempAt:1 put:30&quot;<br></div><div>the local value only changes for the outer context - OK<br><br></div><div>Is this right?<br></div><div><br></div><div><br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span class=""><br>
<br>
&gt; But the reason why the test actually fails is different. It is because evaluating<br>
&gt; the code that modifies the var &quot;local1:=25&quot; ends up to a call<br>
&gt; aContext tempAt: self indexFromIR put: aValue<br>
&gt; but the index (indexFromIR) can be different for every context (method context / inner block<br>
&gt; context(s)).<br>
<br>
</span>Right.<br>
<span class=""><br>
&gt;<br>
&gt; 2. Question: should the index be always the same?<br>
<br>
</span>How can it be?  If, for example, a nullary block makes use of a copied variable and has no local temps then that variable will end up with index 0, no matter its indices in outer scopes.  Surely you&#39;re not proposing padding the block with unused variables just so copied variables can have the same index?<br></blockquote><div><br></div><div>Yes, makes sense.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span class=""><br>
&gt;<br>
&gt; thanks inadvance<br>
&gt;<br>
&gt; Nicolai<br>
&gt;<br>
&gt;<br>
&gt; ps: since spur (resp. compiler changes that were done for new spur images), the index of tempvars can be different.<br>
&gt; In pre-spur, this testcase modifies an outer context var, but one that isn&#39;t checked (the argument &quot;two&quot;), therefore<br>
&gt; the test succeed. In spur, this testcase modifes a different outer context var &quot;remote1&quot;, and the test<br>
&gt; fails.<br>
<br>
<br>
</span>Since Sour hasn&#39;t changed the compiler there looks to be a bug.  Sour has changed the identityHash size a lot from IIRC 11 bits to 22.  So hashed collections can end up with different enumerations.  But that shouldn&#39;t affect the ordering assigned to temps in the compiler.  I suggest tracking down why the code is different in Spur is a very important thing to do.<br></blockquote><div><br></div><div>Yes, we merged some code for spur support (opals compiler code) and lost some intermediate changes that were made for opal. Debugging this bugs was a mess.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
HTH<br>
<br>
Eliot<br></blockquote><div><br></div><div>thanks<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
_,,,^..^,,,_ (phone)<br>
<br>
PS if you want to understand why copied variables are so important in the closure model you need to understand context-to-stack mapping and the overhead that not copying temps adds to returns in a context-to-stack mapping VM.  It&#39;s not obvious but I hope my blog does an ok job of explaining something alas complex but extremely important for performance.<br></blockquote><div><br></div><div>I read your blog <br></div></div><br></div></div>