Skip to content
November 25, 2008 / Abe Pralle

Fast call dispatch for aspects and interfaces

Up until now, the call-related speed issue I’ve been most worried about in the Slag VM has been aspect call dispatch (e.g. interface call dispatch).  Ironically, while thinking about multimethods (previous post) I just figured out a way to turn aspect calls into standard dynamic calls!

Here’s the basic issue: you’ve got class Horse that incorporates aspects Animal and Transportation and class Car that incorporates aspects Machine and Transportation:

    underlying aspect Animal
      METHODS
        method get_info.AnimalInfo: ...
    endAspect

    underlying aspect Machine
      METHODS
        method get_info.MachineInfo: ...
        method fix: ...
    endAspect

    underlying aspect Transportation
      METHODS
        method ride: ...
    endAspect

    class Horse : Animal, Transportation
    class Car   : Machine, Transportation

This gives you the following dynamic call tables for Horse and Car:

    Horse
      0  get_info().AnimalInfo
      1  ride()

    Car
      0  get_info().MachineInfo
      1  fix
      2  ride()

Here’s the sticky part: if I make a Transporation reference, I should be able to call ride() on objects of either type.  It can’t be a regular dynamic call using the tables above since it’s entry #1 for Horse and entry #2 for Car.

Up until now I’ve handled this in two ways: for the VM I’ve used multidiminsional call tables – every class will have an array of aspect call tables and I’ll assign aspect_table[0] to be a call table of Animal calls for anything that incorprates Animal, aspect_table[1] be a table of Machine calls for anything that incorporates Machine, and so on.  Or, if I’m cross-compiling to C, I’ll have an intermediate dispatch function that takes an aspect reference and uses if statements to see what kind of class it is and forward the call appropriately.

Here’s the other way to do it: define all aspect methods in base class Object.

This is an optimization for run-time performance, not compile-time analysis.  So you compile everything normally, and at the end you insert aspect method definitions into the base class call table and change all your aspect calls to be dynamic calls.

You have to watch out for name collisions, but this is easy enough to avoid by appending the return type on to the method name.  Our call tables become:

    Object
      0  get_info__AnimalInfo().AnimalInfo
      1  ride()
      2  get_info__MachineInfo().MachineInfo
      3  fix()

    Horse
      0  (defined)
      1  (defined)
      2  -
      3  -

    Car
      0  -
      1  (defined)
      2  (defined)
      3  (defined)

The other possible issue is memory usage, but let’s take a look: practically speaking, only a handful of methods are ever actually called using aspect dispatch.   But even in the worst case scenario, there are a total of 126 unique aspect method signatures in the Slag standard library.  If your program had, say, 200 classes and all of those aspect methods were called using aspect dispatch, that’d be an extra 126*200*4 bytes = 98k of call table space.  Not that bad!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: