[Ironruby-core] Code Review: BlockDispatch7

Tomas Matousek Tomas.Matousek at microsoft.com
Wed Jul 9 22:09:28 EDT 2008

tfpt review "/shelveset:BlockDispatch7;REDMOND\tomat"

Improves dispatch to blocks.

Previously, DynamicSites were used to adapt call site's arguments to the signature of the target block. In block invocation no resolution needs to be performed, which makes it different from method invocation. The dynamic behavior is only in the arguments to parameters transformation. In usual case it is straightforward though. Only if splatting/unsplatting is used (and in some other special cases) there are various checks that need to be performed to shuffle the arguments right. Although dynamic sites could help here in some cases (by caching by a shape of the target block signatures) the usual cases are rather slowed down by the overhead. In an optimal case w/o any splatting/unsplatting and without polymorphic sites kicking in at least one comparison and 2 delegate calls needs to be done.

This change replaces dynamic site dispatch by a virtual dispatch optimized for 0-4 parameters. Each block is associated with a block dispatcher (a subclass of BlockDispatcher abstract class, previously RubyBlockInfo)  that corresponds to its signature. The specialized dispatchers implement virtual Invoke methods for 0...4 and N parameters w/ and w/o splatting. The call site uses one of those Invoke methods (based on its arguments) and calls it. The dispatcher holds on a delegate that points to the block method. The delegate is called by Invoke methods with transformed arguments. In the optimal case (e.g. 1.times {|x| puts x}) the cost of block yield is a virtual method dispatch and a delegate call. Besides no runtime-generated stubs are needed which improves startup time. Using the dispatchers also enables to move some previously generated code into RubyOps and therefore decreases the amount of generated code even more.

Blocks are still IDOs to provide good interop. This change also made the rules much simpler.


There is some work to be done to optimize some paths thru dispatchers. Will need to run some micro-benchmarks for block dispatch to see where we should do better.
Also, some parts of the code seem to be good candidates for source code generation, but I haven't opted for that for now since it was easier to write it by hand (there are many exemptions to the "rules" of the block dispatch, so even if the code looks like it could be generated at the first glance the generator would actually get more complicated to handle all such cases). I've let this in TODO bucket.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: BlockDispatch7.diff
Type: application/octet-stream
Size: 318183 bytes
Desc: BlockDispatch7.diff
URL: <http://rubyforge.org/pipermail/ironruby-core/attachments/20080709/61659c78/attachment-0001.obj>

More information about the Ironruby-core mailing list