[Newcompiler] Implementing bytecode for closur
Marcus Denker
denker at iam.unibe.ch
Thu Apr 26 13:46:40 UTC 2007
On 26.04.2007, at 15:04, Mathieu Suen wrote:
> I don't really understand what a method/closure activation consist on?
>
> Is it a context switching?
>
No. not that simple to explain via mail....
So think about what happens when a message is send.
someObject doIt.
The bytecode looks like this:
pushLiteral someObject
send #doIt
1) we go to the class of someObject and look in the method
Dictionarty for
the entry #doIt. If it's not there, we go to the superclass. At
soem point, we find
an entry with the key #doit. This is a compiledMethod.
2) Now the VM has a compiledMethod, and wants to execute it. For
executing it,
we need space for the temps *and* we need, very important, to
remember where
to return to afterwards.
This is not that simple to solve, as we do want to support recursion
and parallel
multiple execution threads... and looking at CS history it took a
while until it was figures out.
The way this is done is that there is a so called frame, one per
method to be
executed, every method that gets executed gets a new one, and they
are chained: every
frame remembers the caller. So the frames themselves form a Stack,
with an newly executed
method added on top, then the method returns, which means this stack
frame is not needed
anymore (normally... but that's exactly which is the problem with
closures...).
In Squeak, stack frames are Objects, chained by the "sender" ivar.
When you inspect "thisContext"
you can see this in action. The debugger just shows the stack, too.
Now creating a new stack Object *every* time we do a method execution
is very
costly: The frame needs to be created, and later it needs to be GCed.
But it is very cool
for all sorts of things, e.g. debugging, or hacking (Seaside
Continuations...) to have this
high-level view.
The same thing we have for Methods, we have for Blocks: ececuting a
block needs a context,
too.
There have been lots of clever ways invented to not have to do a new
object per method
activivation. In Squeak, for methods, there are two: 1) Primitives do
not need an activation.
The vm looks at the header of the cm, sees the primitive, an knows
what to do. 2) Same
for "Quick" methods, simple methods that return i-variables or
constants (^true).
So with the Closures, it has one method per Closure that is called
normally like a method,
which means it needs to create a context for that method everytime
when you send #value. The scheme
for BlockContext is faster, as it can re-use existing contexts... the
class of a Block is "BlockContext",
so a Block is already it's own stack frame (context).
Marcus
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 3947 bytes
Desc: not available
Url : http://lists.squeakfoundation.org/pipermail/newcompiler/attachments/20070426/d10ec9b6/smime-0001.bin
More information about the Newcompiler
mailing list