[ANN] Closure Compiler

Anthony Hannan ajh18 at cornell.edu
Wed Feb 5 05:50:30 UTC 2003


Hello fellow Squeakers,

At http://minnow.cc.gatech.edu/squeak/ClosureCompiler you will find a
zip of changesets that adds a closure compiler to the standard Squeak
image (without replacing the existing compiler).  A new "general"
preference called #compileBlocksAsClosures determines which compiler to
use for new methods.  When true the closure compiler is used, when false
the existing compiler is used (default).

The closure compiler compiles non-inlined blocks as separate
compiledMethods.  These block methods are held in the literals of the
home method and sent the #createBlock... message at runtime to create
BlockClosures.  Outer temps referenced by the block are given as args to
the #createBlock... message which adds them to the closure it creates,
which consists of the method in its sole named field and the captured temps
in its indexable fields.  When #value... is sent to a BlockClosure its method
is executed in a new MethodContext with the BlockClosure remaining as the
receiver.  The block method accesses captured temps in indexed fields as if
they were named instance variables.

Captured temps that may change after being captured are wrapped in
SharedTempHolders and all methods (home and block) access their values
indirectly through the holders.  If a captured temp may not change (most
common) then no holder is created saving time.

BlockClosures that return to its home context hold the home context as
one of its captured temps.  Actually, to support safe continuations, it
holds the tag of its home context.  A ContextTag is a unique object for
each context that stays the same for all copies of each context.  When a
BlockClosure attempts to return to its home context it searches the
sender chain for the context that has the right ContextTag and returns
to it.  This works with copied contexts (continuations) as well as
original contexts.

Thanks to captured temps and context tags, block closures are totally
separate from their home context.  They are reentrant and each
activation has its own block-local temps.

BlockClosures are slower primarily because each activation is a new
context.  BlockContexts are fater because they reuse the same context. 
An optimizing VM (Jitter, VI4) that stack allocates contexts should
rectify this problem.  For an example of its slowness (and general
slowness of context activation) execute "[(1 to: 100000) do: [:i | i]]
timeToRun" under each compiler (toggle the preference).

The above example will be really slow for the closure compiler until you
generate interp.c and recompile your VM to include a couple of new
primitives (186 and 187) added with the closure compiler.  They
implement BlockClosure>>value... directly.  Without them the failure
code has to add the closure method to the BlockClosure method dictionary
then call #perform:.

Please read further comments in the ReadMe file and in BlockClosure
class>>#aboutClosures (both repeated on the Closure Compiler website). 
A package has been added to SqueakMap that just provides a link to this
website.

Cheers,
Anthony



More information about the Squeak-dev mailing list