Re: [squeak-dev] Trying to understand thisContext

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Trying to understand thisContext

Eliot Miranda-2
 
Hi Matthias,

    cc'ing vm-dev, because this is more of a VM question

On Mon, Jun 8, 2015 at 6:45 AM, matthias.springer <[hidden email]> wrote:
Hi there,

I am trying to understand what the meaning and implementation of
"thisContext" is.

On a recent COG VM, "[ |a b| a:=b:=1. thisContext basicSize ] value" returns
3. Adding more temp vars increases that value.

That's correct.  thisContext basicSize effectively answers the value of the stack pointer of a context.  In Squeak (as opposed to, say, the BLueBook) the Interpreter was optimized by changing the garbage collector to never look at fields in a context past the stack pointer.  In the blue book, thisContext basicSize answers the number of stack slots in the context, rather than the stack pointer, and the garbage collector might look beyond the stack pointer for reachable object references, but if pop nils out the top of stack, there should only ever be nils beyond the stack pointer.

IMO, this difference could have been hidden in the VM and thisCOntext basicSize could have always answered a constant, but that's the current definition in Squeak/Pharo.
 

On a Cocoa VM (http://squeakvm.org/mac/release/Squeak%205.7.4.1.zip), the
same code always returns 0. Also, "thisContext at: 1" etc. is out of bounds.

This is not a closure VM right?  So while the code reads the same, the bytecode and implementation is quite different.  In this VM, which has blue-book blocks, block arguments are popped into temporary variables in the home context by the block prolog, so that by the time thisCOntext is sent basicSize its stack is empty.  So given the compilayion of blocks, this answer is also correct.

What I suggest is that you write the following and examine the differences in the bytecode:

{ [ |a b| a:=b:=1. thisContext basicSize ] value. thisContext method symbolic }
 

Which one is correct? Any ideas?

Both.  They differ because they implement blocks quite differently.  You can read more on the difference in the implementations in http://www.mirandabanda.org/cogblog/2008/06/07/closures-part-i/ et al.

 

The reason why I am asking is because there is code that seems to rely on
this (e.g. SystemTracer2>>writeContext:) and I am trying to get it running
on RSqueak.

Again, let me instead suggest that you adapt the code in SpurBootstrap in the Cog package at http://source.squeak.org/VMMaker, instead of using SystemTracer.  It is a lot more direct, and less hairy than an image tracing itself.

--
best,
Eliot
Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Trying to understand thisContext

Tobias Pape


On 08.06.2015, at 21:57, Eliot Miranda <[hidden email]> wrote:

> Hi Matthias,
>
>     cc'ing vm-dev, because this is more of a VM question
>
> On Mon, Jun 8, 2015 at 6:45 AM, matthias.springer <[hidden email]> wrote:
> Hi there,
>
> I am trying to understand what the meaning and implementation of
> "thisContext" is.
>
> On a recent COG VM, "[ |a b| a:=b:=1. thisContext basicSize ] value" returns
> 3. Adding more temp vars increases that value.
>
> That's correct.  thisContext basicSize effectively answers the value of the stack pointer of a context.  In Squeak (as opposed to, say, the BLueBook) the Interpreter was optimized by changing the garbage collector to never look at fields in a context past the stack pointer.  In the blue book, thisContext basicSize answers the number of stack slots in the context, rather than the stack pointer, and the garbage collector might look beyond the stack pointer for reachable object references, but if pop nils out the top of stack, there should only ever be nils beyond the stack pointer.
>
> IMO, this difference could have been hidden in the VM and thisCOntext basicSize could have always answered a constant, but that's the current definition in Squeak/Pharo.
>  
>
> On a Cocoa VM (http://squeakvm.org/mac/release/Squeak%205.7.4.1.zip), the
> same code always returns 0. Also, "thisContext at: 1" etc. is out of bounds.
>
> This is not a closure VM right?  So while the code reads the same, the bytecode and implementation is quite different.  In this VM, which has blue-book blocks, block arguments are popped into temporary variables in the home context by the block prolog, so that by the time thisCOntext is sent basicSize its stack is empty.  So given the compilayion of blocks, this answer is also correct.
>
> What I suggest is that you write the following and examine the differences in the bytecode:
>
> { [ |a b| a:=b:=1. thisContext basicSize ] value. thisContext method symbolic }
>  
>
> Which one is correct? Any ideas?
>
> Both.  They differ because they implement blocks quite differently.  You can read more on the difference in the implementations in http://www.mirandabanda.org/cogblog/2008/06/07/closures-part-i/ et al.
>
>  
>
> The reason why I am asking is because there is code that seems to rely on
> this (e.g. SystemTracer2>>writeContext:) and I am trying to get it running
> on RSqueak.
>
> Again, let me instead suggest that you adapt the code in SpurBootstrap in the Cog package at http://source.squeak.org/VMMaker, instead of using SystemTracer.  It is a lot more direct, and less hairy than an image tracing itself.

:(
That always has been one of the most interesting if not intriguing parts of Squeak

Best regards
        -Tobias
Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Trying to understand thisContext

matthias.springer
Hi Eliot,

OK, so "thisContext basicSize" should return the value of the stack pointer. Thank you for the explanation. I think I got it working now and have a better understanding of how thisContext works.

What I am still wondering is how "ContextPart>>stackPtr" works and what its purpose is (why not just call the primitive). The method comment says that it should only be used in the inspector etc.

Also, interestingly, I ran the previously mentioned code in the same image (Squeak 4.5 or so...) but with different underlying VMs, so the bytecode is actually the same; still the VMs behave differently. I was expecting that "thisContext" behaves the same on all VMs, but that does not seem to be the case.

Still need to look into the Spur bootstrapping...

Best,
Matthias
Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Trying to understand thisContext

Eliot Miranda-2
 
Hi Matthias,

On Tue, Jun 9, 2015 at 8:40 AM, matthias.springer <[hidden email]> wrote:

Hi Eliot,

OK, so "thisContext basicSize" should return the value of the stack pointer.
Thank you for the explanation. I think I got it working now and have a
better understanding of how thisContext works.

What I am still wondering is how "ContextPart>>stackPtr" works and what its
purpose is (why not just call the primitive). The method comment says that
it should only be used in the inspector etc.

So I *think* that in an Interpreter VM, stackPtr simply answers the stackp inst var and that gets written back to a context on send, so given that stackPtr is sent, even to thisContext, stackp will reflect the relevant value.  i.e. in an Interpreter VM there's nothing magic about the stackp inst var.

But in a StackInterpreter or CoInterpreter stackp is indeed handled specially.  A context may or may not be "married", i.e. having an associated stack frame which it is a proxy for.  If it isn't married, then stackp holds the actual value.  If the context /is/ married then the VM needs to compute stackp from the stack frame.  You can read my blog post on context-to-stack mapping for details.  So the VM needs to handle sender, pc and stackp inst var access in context specially, and these are inst vars 0, 1 & 2.

For efficiency the VM /must/ avoid checking on every 0, 1 or 2 offset inst var access whether the receiver is a context.  It would kill performance.  The bytecode set has at least two forms of inst var fetch bytecode, a short form, typically for inst vars 0 through 15, and a long form, typically for offsets > 15.  The bytecode compiler arranges to generate the long form for all ContextPart inst vars.  So the VM can assume it doesn't need to check in the short form bytecodes, and the check in the kong form bytecodes is cheap, because a) it checks if the index is <= 2 (a very cheap check) before checking for a context receiver, and b) the long form will only be used for index < 15 for contexts and subclasses, so the expensive check for the receiver being a context is only performed on contexts and subinstances.

In the long-form inst var access then, if the index is found to be <= 2 and the receiver is a married context then
a) on fetch the value of the inst var is computed from the context's stack frame
b) on store the context will typically be divorced and converted into a vanilla context

Does this make sense?


Also, interestingly, I ran the previously mentioned code in the same image
(Squeak 4.5 or so...) but with different underlying VMs, so the bytecode is
actually the same; still the VMs behave differently. I was expecting that
"thisContext" behaves the same on all VMs, but that does not seem to be the
case.

Hmmm, then I guess that the bug is that in the Interpreter VM the the stack pointer is not written back into the context object on sending stackPtr?

Still need to look into the Spur bootstrapping...

and remember I'm very happy to give you a tour of the code, e.g. using Skype, if you'd like it.  Welcome!
--
best,
Eliot
Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Trying to understand thisContext

Tobias Pape
 
Hi 
On 09.06.2015, at 20:39, Eliot Miranda <[hidden email]> wrote:

Hi Matthias,

On Tue, Jun 9, 2015 at 8:40 AM, matthias.springer <[hidden email]> wrote:

Hi Eliot,

OK, so "thisContext basicSize" should return the value of the stack pointer.
Thank you for the explanation. I think I got it working now and have a
better understanding of how thisContext works.

What I am still wondering is how "ContextPart>>stackPtr" works and what its
purpose is (why not just call the primitive). The method comment says that
it should only be used in the inspector etc.

So I *think* that in an Interpreter VM, stackPtr simply answers the stackp inst var and that gets written back to a context on send, so given that stackPtr is sent, even to thisContext, stackp will reflect the relevant value.  i.e. in an Interpreter VM there's nothing magic about the stackp inst var.

But in a StackInterpreter or CoInterpreter stackp is indeed handled specially.  A context may or may not be "married", i.e. having an associated stack frame which it is a proxy for.  If it isn't married, then stackp holds the actual value.  If the context /is/ married then the VM needs to compute stackp from the stack frame.  You can read my blog post on context-to-stack mapping for details.  So the VM needs to handle sender, pc and stackp inst var access in context specially, and these are inst vars 0, 1 & 2.

For efficiency the VM /must/ avoid checking on every 0, 1 or 2 offset inst var access whether the receiver is a context.  It would kill performance.  The bytecode set has at least two forms of inst var fetch bytecode, a short form, typically for inst vars 0 through 15, and a long form, typically for offsets > 15.  The bytecode compiler arranges to generate the long form for all ContextPart inst vars.  So the VM can assume it doesn't need to check in the short form bytecodes, and the check in the kong form bytecodes is cheap, because a) it checks if the index is <= 2 (a very cheap check) before checking for a context receiver, and b) the long form will only be used for index < 15 for contexts and subclasses, so the expensive check for the receiver being a context is only performed on contexts and subinstances.

In the long-form inst var access then, if the index is found to be <= 2 and the receiver is a married context then
a) on fetch the value of the inst var is computed from the context's stack frame
b) on store the context will typically be divorced and converted into a vanilla context

Does this make sense?

This makes sense. It's how I once also implemented it in SqueakMaxine (with all the wedding, too)
and it worked neatly.



Also, interestingly, I ran the previously mentioned code in the same image
(Squeak 4.5 or so...) but with different underlying VMs, so the bytecode is
actually the same; still the VMs behave differently. I was expecting that
"thisContext" behaves the same on all VMs, but that does not seem to be the
case.

Hmmm, then I guess that the bug is that in the Interpreter VM the the stack pointer is not written back into the context object on sending stackPtr?

It was #basicSize in his previous code :)


Still need to look into the Spur bootstrapping...

and remember I'm very happy to give you a tour of the code, e.g. using Skype, if you'd like it.  Welcome!

Best regards
-Tobias
Reply | Threaded
Open this post in threaded view
|

re: tour de Spur (was "Trying to understand thisContext")

ccrraaiigg
In reply to this post by Eliot Miranda-2
 

Hi Eliot--

     Matthias writes:

> Still need to look into the Spur bootstrapping...

     You respond:

> ...I'm very happy to give a tour of the code, e.g. using Skype...

     Cool! If you record it (e.g., with Skype Call Recorder plugin for
Skype, or if I may join you and record it), I'd be happy to edit it into
a screencast.


-C

--
Craig Latta
netjam.org
+31   6 2757 7177 (SMS ok)
+ 1 415  287 3547 (no SMS)

Reply | Threaded
Open this post in threaded view
|

re: tour de Spur (was "Trying to understand thisContext")

David T. Lewis
 
On Thu, Jun 11, 2015 at 11:24:40AM +0200, Craig Latta wrote:

>  
>
> Hi Eliot--
>
>      Matthias writes:
>
> > Still need to look into the Spur bootstrapping...
>
>      You respond:
>
> > ...I'm very happy to give a tour of the code, e.g. using Skype...
>
>      Cool! If you record it (e.g., with Skype Call Recorder plugin for
> Skype, or if I may join you and record it), I'd be happy to edit it into
> a screencast.
>

Yes please! That would be great.

Dave
 
Reply | Threaded
Open this post in threaded view
|

re: tour de Spur (was "Trying to understand thisContext")

Eliot Miranda-2
In reply to this post by ccrraaiigg

Hi Craig,

    if it's on with Matthias I'm happy to let you join.  But editing may be necessary ;-)

Eliot (phone)

On Jun 11, 2015, at 2:24 AM, Craig Latta <[hidden email]> wrote:

>
>
> Hi Eliot--
>
>     Matthias writes:
>
>> Still need to look into the Spur bootstrapping...
>
>     You respond:
>
>> ...I'm very happy to give a tour of the code, e.g. using Skype...
>
>     Cool! If you record it (e.g., with Skype Call Recorder plugin for
> Skype, or if I may join you and record it), I'd be happy to edit it into
> a screencast.
>
>
> -C
>
> --
> Craig Latta
> netjam.org
> +31   6 2757 7177 (SMS ok)
> + 1 415  287 3547 (no SMS)
>
Reply | Threaded
Open this post in threaded view
|

re: tour de Spur (was "Trying to understand thisContext")

Karl Ramberg
 
This will be interesting to watch :-)
I'm looking forward to it

Karl

On Fri, Jun 12, 2015 at 9:11 AM, Eliot Miranda <[hidden email]> wrote:

Hi Craig,

    if it's on with Matthias I'm happy to let you join.  But editing may be necessary ;-)

Eliot (phone)

On Jun 11, 2015, at 2:24 AM, Craig Latta <[hidden email]> wrote:

>
>
> Hi Eliot--
>
>     Matthias writes:
>
>> Still need to look into the Spur bootstrapping...
>
>     You respond:
>
>> ...I'm very happy to give a tour of the code, e.g. using Skype...
>
>     Cool! If you record it (e.g., with Skype Call Recorder plugin for
> Skype, or if I may join you and record it), I'd be happy to edit it into
> a screencast.
>
>
> -C
>
> --
> Craig Latta
> netjam.org
> <a href="tel:%2B31%20%20%206%202757%207177" value="+31627577177">+31 6 2757 7177 (SMS ok)
> <a href="tel:%2B%201%20415%20%20287%203547" value="+14152873547">+ 1 415 287 3547 (no SMS)
>

Reply | Threaded
Open this post in threaded view
|

Re: re: tour de Spur (was "Trying to understand thisContext")

matthias.springer
In reply to this post by Eliot Miranda-2
Hi there,

Sure, no problem! We're having the call on Wednesday morning (9am PST).

Craig, just send me your Skype account name by email if that time works for you. Otherwise, I can record it.

Best,
Matthias