Object oriented languages like C++ and Object Pascal support what are called virtual methods. Unlike plain vanilla methods, whose procedure addresses can be computed at compile time, the address of a virtual method may not be known until run time. Consider the case of an object class number that declares a virtual method show. The method show is assumed to print the number as floating point decimal. Suppose we now declare a class rational as a subclass of number with a show method that prints numbers out as a fraction.
Figure 3.13: The use of a virtual method table in object
oriented programming
Given an instance x of the class number, the command x.show must invoke a different method according to whether x is a plain old number, or is a rational number. The solution conventionally adopted to this problem is shown in figure 3.13. The objects themselves have a pointer, either full length, or datasegment-relative, to a table, the Virtual Method Table, that contains pointers to the actual methods used. There will be different Virtual Method Tables for plain numbers and for rationals, but in each of these tables, the entry that points to the show method will be at a position that is known at compile time.
If however these two classes are incorporated as libraries into different programs, it is likely that the addresses of the virtual method tables for the class rational in the datasegment will differ between the programs. Thus if a rational number is created in the persistent memory by one progam, but is subsequently used by a second program, the virtual method table pointer will be incorrect on the second occasion. Our implementation obviates this problem by a two step process:
Figure 3.14: The heaps in segments 4098 and 4104 are show assigned
to the class of rationals. On a segment fault, it is possible
by inspecting the classes table to find which class `owns'
a given segment.
This procedure then creates a heap specially tailored to that class, and creates a class descriptor for the class if none exists in the persistent store at that time. The class descriptor has the form shown in figure 3.14.
An entry is then made into the classes table at the index position of the persistent segment used for the heap, pointing to the class descriptor. If in the course of time, this heap is insufficient to hold all of the members of the class, additional ones are created. All the heaps owned by a class have their entries in the classes table set to point at the appropriate class descriptor.
The system stores housekeeping tables in the ROOTBLOK file, whose structure is shown in figure 3.15.
Figure 3.15: The type of the root block which provides housekeeping tables
for the persistence manager.
It has 4 components:
From the class descriptor, the value and offset within the instances, of the class's current virtual method table may be determined. This information can then be used to update all of the instances of the class, resident within the faulting heap segment, to point at the currently valid virtual method table.
By the time the interrupt handler returns, the instance of the class whose pointer caused the fault has been loaded into memory, and its virtual method table made accessible.