Objects are stored in memory just as ordinary records with an extra field: a pointer to the Virtual Method Table (VMT). This field is stored first, and all fields in the object are stored in the order they are declared (with possible alignment of field addresses, unless the object was declared as being packed).
The VMT is initialized by the call to the object’s Constructor method. If the new operator was used to call the constructor, the data fields of the object will be stored in heap memory, otherwise they will directly be stored in the data section of the final executable.
If an object doesn’t have virtual methods, no pointer to a VMT is inserted.
The memory allocated looks as in table (8.4).
Offset | What | |
32-bit | 64-bit | |
+0 | +0 | Pointer to VMT (optional). |
+4 | +8 | Data. All fields in the order they’ve been declared. |
… | ||
The Virtual Method Table (VMT) for each object type consists of 2 check fields (containing the size of the data), a pointer to the object’s ancestor’s VMT (Nil if there is no ancestor), and then the pointers to all virtual methods. The VMT layout is illustrated in table (8.5). The VMT is constructed by the compiler.
Offset | What | |
32-bit | 64-bit | |
+0 | +0 | Size of object type data |
+4 | +8 | Minus the size of object type data. Enables determining of valid VMT pointers. |
+8 | +16 | Pointer to ancestor VMT, Nil if no ancestor available. |
+12 | +24 | Pointers to the virtual methods. |
… | ||