[Newcompiler] Implementing bytecode for closur

bryce at kampjes.demon.co.uk bryce at kampjes.demon.co.uk
Fri Apr 27 20:42:06 UTC 2007


Marcus Denker writes:
 > 
 > On 26.04.2007, at 23:25, <bryce at kampjes.demon.co.uk>  
 > <bryce at kampjes.demon.co.uk> wrote:
 > 
 > >
 > > Context recycling has been used by the interpreter for many years. It
 > > definately works.
 > 
 > Ok, I looked at the code a bit... and it is, too, used already when  
 > executing
 > BlockClosures, as primitiveExecuteMethod uses the normal method  
 > execution
 > logic.
 > 
 > So then recycling context can not make closure activiation much  
 > faster, as
 > it already is done right now.

The catch is pushThisContext stops recycling. 

    Interpreter>>pushActiveContextBytecode
	"Puts reclaimability of this context in question."

	self fetchNextBytecode.
	reclaimableContextCount := 0.
	self internalPush: activeContext.

The reclaimableContextCount tracks how many MethodContexts may be
recycled. Every time a MethodContext is created it's
incremented. Every time a context is recycled during a normal return
it's decremented. Every time the interpreter does something that would
stop a context being safely recycled it's set to 0. The interpreter
will only recycle the top of the stack, everything after a
un-recyclable context is not recycled.

In the old world creating a BlockContext stops recycling of all
contexts before it. Reading thisContext must stop recycling because
the interpreter does not know what will happen to the context
afterwards. The context must not be recycled if it might live after it
has returned. If it is directly accessed, then the interpreter must
assume that it will be referenced by a longer living object. 1)

With the closure compilers environments, it should be possible to make
all MethodContexts recyclable except for explicit uses of thisContext.
That should allow some new style closures to be faster than the
current ones. Sure, creating a closure involves a new but it doesn't
need to stop any contexts from being recycled and BlockContexts are
not recycled at the moment. Contexts with environments will be faster
to create than they are now. 

The other option for performance would be to fold the Environment
objects into the closures. Environments are not needed with proper
object contexts. Having both and disabling the context recycling is
the worst of both worlds.Getting rid of Environments would provide
performance roughly similar to the current scheme. Every Closure
creation would need to stop context recycling in case the Closure
(which pointed to it's surrounding context) was long lived and made
it's surrounding context long lived.

My guess is Anthony originally created the ClosureEnvironments when he
was implementing contexts on his stack objects. That provided faster
message sends but "broke" the meta-language as contexts were no longer
objects that could be freely manipulated. Environments are required if
you don't have proper context objects.

The ClosureEnvironments could be used to work with Squeak's context
recycling or could be removed. My guess is keeping and fixing the
ClosureEnvironments will run faster than removing them. I don't know
how each option will effect tool integration.

Bryce

1) The bugs caused by recycling a context that shouldn't be recycled
are nasty. I've created those too.


More information about the Newcompiler mailing list