A more flexible technique for supporting multiple inheritance is to determine the location of fields dynamically. This technique produces at most two versions of method code, and allows access to instance variables of objects other than self.
The location of the fields is provided by placing the correct field offset in the class dispatch vector, exactly as if the offset were a private method pointer. Many implementations of multiple inheritance have used intra-object pointers for this purpose; however, dynamic field offsets take no space per object, and are usually just as fast. Since dispatch vectors are shared, field offset loads are less likely than intra-object pointers to cause cache misses. The MIPS code to place the starting address of the fields into the register t3 is shown in Figure 13. Note that this computation may be amortized over all field accesses to a particular object within a method call.
|ld t1, 0(a0)||; load dispatch vector|
|ld t2, fields(t1)||; load field offset|
|add t3, a0, t2||; start of fields|
Dynamic field offsets can be used to extend the recompilation scheme of Section 4.1 so that it supports accesses to instance variables of objects other than self. These accesses use the dynamic field offset, since the correct field offset cannot be determined statically. When instance variables of self are accessed, the correct offset is known, as before.
A more space-efficient technique is for all code to access instance variables using the field offset. This approach has the advantage that all class methods can be inherited without recompilation; it has the disadvantage that accessing the instance variables of self requires the code of Figure 13.
A reasonable compromise is to generate at most two versions of the class code. In both versions of the code, instance variables of objects other than self are accessed through the dynamic field offset. The versions differ in how they access the instance variables of self.
The first, fast version is used for objects of the class itself and for subclasses that inherit from the class in a primary superclass chain. Since the field offset is known statically, instance variables are accessed by an indexed load, as in the basic bidirectional scheme.
The second, generic version accesses all instance variables through the dynamic field offset code of Figure 13, and is suitable for inheritance as a secondary superclass method. This second version is particularly appropriate for mix-in classes.