Code Generation for Objects

class A {
  a: Int <- 0;
  d: Int <- 1;
  f(): Int { a <- a + d };
};

class B inherits A {
  b: Int <- 2;
  f(): Int { a };
  g(): Int { a <- a - b };
};

class C inherits A {
  c: Int <- 3;
  h(): Int { a <- a*c };
};

For A methods to work correctly in A, B and C objects, attribute a must be in the same "place" in each object.

Object layout

For efficiency:

Example layout

Offset   Information stored
0   Class tag
4   Object size
8   Dispatch ptr
12  Attribute 1
16  Attribute 2
...

The object size and dispatch pointer are arguably redundant (this information is derivable from the Class tag), but help with an efficient implementation.

Observation: Given a layout for class A, a layout for subclass B can be defined by extending the layout of A with additional slots for the additional attributes of B. This is a clever trick designed for efficiency and convenience; it is always possible to have a different version of the generated code for each different class.

Leaves the layout of A unchanged (B is an extension).

Looking at our example:

Class A: {0: Atag, 4: 5, 8: *, 12: a, 16: d}
Class B: {0: Btag, 4: 6, 8: *, 12: a, 16: d, 20: b}
Class C: {0: Ctag, 4: 6, 8: *, 12: a, 16: d, 20: c}

The offset of an attribute is the same in a class and all of its subclasses

Consider layout for An < ... A3 < A2 < A1

Header     |A1 object  |            |
A1 attrs   |           |A2 object   |
A2 attrs               |            |A3 object
A3 attrs                            |
...
An attrs

OO Code generation

Every class has a fixed set of methods

A dispatch table indexes these methods

Dispatch table layout

Class A: {0: fA}
Class B: {0: fB, 4: g}
class C: {0: fA, 4: h}

The dispatch pointer in an object of class X points to the dispatch table for class X. Every method f of class X is assigned an offset Of in the dispatch table at compile time

To implement a dynamic dispatch e.f(), we

Multiple Inheritance

If C is a subclass of two independent classes A and B simultaneously (C inherits from both A and B), then: Modern compilers support a command-line flag called "rtti" (run-time type information); if rtti is disabled, then the dynamic_cast operator is not supported.

CPP Pointer Adjustment