<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"><<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>></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>
> On Mar 24, 2016, at 1:53 AM, Nicolai Hess <<a href="mailto:nicolaihess@gmail.com">nicolaihess@gmail.com</a>> wrote:<br>
><br>
> Hello,<br>
><br>
> we have a failing test (OCClosureCompilerTest>>#testDebuggerTempAccess)<br>
> (fails since spur, but not related - I think).<br>
><br>
> A simple example to reproduce the behavior:<br>
> | local1 remote1|<br>
> remote1:=4.<br>
> local1 :=3.<br>
> [:i | |c|<br>
> c := local1.<br>
> remote1 := i.<br>
> i halt.<br>
> "local1:=25. <-- evaluate during debugging"<br>
> ] value:1.<br>
> Transcript show:local1;cr.<br>
> Transcript show:remote1;cr.<br>
> (Executing this code and evaluating "local:=25" after the debugger halts for<br>
> "i halt" will modify the var "remote1" instead of "local1", as this is a vector tempvar , proceeding<br>
> the execution will crash at accessing the remote1 value).<br>
><br>
><br>
> The purpose of the testDebuggerTempAccess test case is, evaluating code<br>
> that changes the value of a copied temp var *does not* change the value of<br>
> this var in the outer context. (see comment in the test case:<br>
> "this is not 25 as the var is a local, non escaping variable that was copied into the block,<br>
> If the compiler would have known about the write, it would have made the var escaping".<br>
> )<br>
><br>
> But the implementation (OCCopyingTempVariable>>#writeFromContext: aContext scope: contextScope value: aValue)<br>
> explicitly iterates through all outer context(s) and changes the vars as well.<br>
><br>
> 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 "the variable being updated" because there isn'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'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> "remote:=20"<br> "local:=10"<br> "outerContext tempAt:1 put:30"<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 "i halt" and you evaluate the code<br><br> "remote:=20"<br>the remote value changes for t he block context and for its outer context - OK<br> "local:=10"<br>the local value changes for the block context but not for its outer context - OK<br> "outerContext tempAt:1 put:30"<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>
> But the reason why the test actually fails is different. It is because evaluating<br>
> the code that modifies the var "local1:=25" ends up to a call<br>
> aContext tempAt: self indexFromIR put: aValue<br>
> but the index (indexFromIR) can be different for every context (method context / inner block<br>
> context(s)).<br>
<br>
</span>Right.<br>
<span class=""><br>
><br>
> 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'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>
><br>
> thanks inadvance<br>
><br>
> Nicolai<br>
><br>
><br>
> ps: since spur (resp. compiler changes that were done for new spur images), the index of tempvars can be different.<br>
> In pre-spur, this testcase modifies an outer context var, but one that isn't checked (the argument "two"), therefore<br>
> the test succeed. In spur, this testcase modifes a different outer context var "remote1", and the test<br>
> fails.<br>
<br>
<br>
</span>Since Sour hasn'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'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'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>