[squeak-dev] modifying copied context vars

Nicolai Hess nicolaihess at gmail.com
Fri Mar 25 09:51:40 UTC 2016


2016-03-25 6:26 GMT+01:00 Eliot Miranda <eliot.miranda at gmail.com>:

> Hi Nicolai,
>
> > On Mar 24, 2016, at 1:53 AM, Nicolai Hess <nicolaihess at gmail.com> wrote:
> >
> > Hello,
> >
> > we have a failing test (OCClosureCompilerTest>>#testDebuggerTempAccess)
> > (fails since spur, but not related - I think).
> >
> > A simple example to reproduce the behavior:
> > | local1 remote1|
> > remote1:=4.
> > local1 :=3.
> > [:i | |c|
> >     c := local1.
> >     remote1 := i.
> >     i halt.
> >     "local1:=25.  <-- evaluate during debugging"
> >      ] value:1.
> > Transcript show:local1;cr.
> > Transcript show:remote1;cr.
> > (Executing this code and evaluating "local:=25" after the debugger halts
> for
> > "i halt" will modify the var "remote1" instead of "local1", as this is a
> vector tempvar , proceeding
> > the execution will crash at accessing the remote1 value).
> >
> >
> > The purpose of the testDebuggerTempAccess test case is, evaluating code
> > that changes the value of a copied temp var *does not* change the value
> of
> > this var in the outer context. (see comment in the test case:
> > "this is not 25 as the var is a local, non escaping variable that was
> copied into the block,
> >     If the compiler would have known about the write, it would have made
> the var escaping".
> > )
> >
> > But the implementation (OCCopyingTempVariable>>#writeFromContext:
> aContext scope: contextScope value: aValue)
> > explicitly iterates through all outer context(s) and changes the vars as
> well.
> >
> > 1. Question: Who is right?
>
> 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.
>

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
during debugging, that can modify the var.
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.
And the supposed behavior is, that the outer context variable value does
not change. But this test fails.

I tried similar code in squeak, and there the outer context var does not
change:

|local remote outerContext|
local :=1.
remote:=2.
outerContext := thisContext.
(1 to:1) do:[:i |
    remote := i.
    Transcript show:local;cr.
    i halt.
    "remote:=20"
    "local:=10"
    "outerContext tempAt:1 put:30"
    Transcript show:local;cr.
    ].
Transcript show:local;cr.
Transcript show:remote;cr.


If the debugger halts at "i halt" and you evaluate the code

    "remote:=20"
the remote value changes for t he block context and for its outer context -
OK
    "local:=10"
the local value changes for the block context but not for its outer context
- OK
    "outerContext tempAt:1 put:30"
the local value only changes for the outer context - OK

Is this right?




>
>
> > But the reason why the test actually fails is different. It is because
> evaluating
> > the code that modifies the var "local1:=25" ends up to a call
> > aContext tempAt: self indexFromIR put: aValue
> > but the index (indexFromIR) can be different for every context (method
> context / inner block
> > context(s)).
>
> Right.
>
> >
> > 2. Question: should the index be always the same?
>
> 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?
>

Yes, makes sense.


>
> >
> > thanks inadvance
> >
> > Nicolai
> >
> >
> > ps: since spur (resp. compiler changes that were done for new spur
> images), the index of tempvars can be different.
> > In pre-spur, this testcase modifies an outer context var, but one that
> isn't checked (the argument "two"), therefore
> > the test succeed. In spur, this testcase modifes a different outer
> context var "remote1", and the test
> > fails.
>
>
> 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.
>

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.


>
> HTH
>
> Eliot
>

thanks


> _,,,^..^,,,_ (phone)
>
> 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.
>

I read your blog
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20160325/642d05d6/attachment.htm


More information about the Squeak-dev mailing list