Re: Information on dispatch-techniques

Christian von Roques <roques@pond.sub.org>
3 Nov 1996 09:57:45 -0500

          From comp.compilers

Related articles
Information on dispatch-techniques astor@lucifer.guardian.no (Alexander Kjeldaas) (1996-10-30)
Re: Information on dispatch-techniques roques@pond.sub.org (Christian von Roques) (1996-11-03)
Re: Information on dispatch-techniques nkramer@cs.cmu.edu (Nick Kramer) (1996-11-05)
Re: Information on dispatch-techniques volanski@irisa.fr (1996-11-07)
Re: Information on dispatch-techniques astor@lucifer.guardian.no (Alexander Kjeldaas) (1996-11-26)
| List of all articles for this month |

From: Christian von Roques <roques@pond.sub.org>
Newsgroups: comp.compilers
Date: 3 Nov 1996 09:57:45 -0500
Organization: Some lucky fish from Karlsruhe, Germany
References: 96-10-150
Keywords: OOP, performance

Alexander Kjeldaas <astor@lucifer.guardian.no> writes:


> I'm looking for papers/information on different dispatch techniques
> for object oriented languages. I'm interesting in everything from the
> most efficient to the most flexible. I'm also interested in any
> measurements made on the efficiency of the different techniques.


The problem of resolving a singly dispatch can be formulated as
follows: Find the address `a' of some code to call for a call to
function `f' in type `T' applied to an object `o' of a runtime type
`t' which is a subtype of `T'. a = dispatch(T.f, t)


I haven't read any literature, but know the following solutions:


  * Each function T.f corresponds to a number `f'. At the same offset
      in all objects of type `t' is a pointer to a dispatch-table `d_t'
      which holds the address a = d_t[f].


      Pseudo ASM: r1 contains `o', the DT is at offset 0 in `o'.
mov [r1+0],r2 ; r2 = d_t
call [r2+f] ; call d_t[f]


      Sometimes this method is implemented with a type-tag, but without
      the pointer to the dispatch-table in the objects. This slower
      implementation requires a table `dt' mapping type-tag to
      dispatch-table d_t = dt[t].


      Pseudo ASM: r1 contains `o', the type-tag is at offset 0 in `o'.
mov [r1+0],r2 ; r2 = t
mov [r2+dt],r2 ; r2 = d_t = dt[t]
call [r2+f] ; call d_t[f]




  * Each runtime-type corresponds o a number `t'. At the same offset
      in all objects is the number of its runtime-type [the type-tag].
      For each function T.f exists a dispatch-table `d_f' which holds the
      address a = d_f[t].


      Pseudo ASM: r1 contains `o', the type-tag is at offset 0 in `o'.
mov [r1+0],r2 ; r2 = t
call [r2+d_f] ; call d_f[t]


  * Dispatching can be implemented using a two-dimensional
      dispatch-table `d' indexed with the function `f' and the dynamic
      type `t'. a = d[f,t] To reduce the memory requirements of the very
      sparse d it is implemented using a hash-table. As hash-table
      lookups are slow, each dispatching call caches the result of the
      last hash-table access. This is the way the old ICSI-Sather did
      it. This is slow.


The advantage of using d_f is that it is as fast as the first method
using d_t, whereas a type-tag may need less space than a pointer.


For some source languages, the dispatch-table `d_f*' for a function
T*.f*, with `T*' being a subtype of `T', is a subtable of `d_f'.
for all t subtype of T*: d_f*[t] == d_f[t].


To reduce the space needed for dispatch-tables which often are sparse
one usually overlays them. I've heard reports, that this works
better for the d_f than for the d_t.


              Christian.
--


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.