TopDealing with InheritanceRun-time Storage Management

Run-time Storage Management

  1. Our goal at this point is to understand enough about run-time organization to understand the information the compiler must collect while processing declarations.

  2. The key idea is that at run-time all memory will be allocated in blocks. There will be frames (i.e. activation records) for method invocations and objects allocated on the heap in response to the construction of new objects and arrays.

  3. Ultimately, our understanding of run-time storage management will have to include knowledge of how to generate code to determine the address of any block of storage that contains a variable we want to access.
  4. For now, however, we will just assume we can find the necessary pointers to blocks of memory and think about the organization within the blocks to make sure that we collect enough information while processing declarations to determine the offset to each variable/method within the blocks of memory we allocate.

  5. As a start, we can identify four types of structures that will be allocated for Woolite programs. (Good news, these will also be sufficient for many other languages).
    Method Activation Records
    Each time a method is invoked, we will push a block of storage to hold the method's parameters and local variables onto a stack. This block of memory will also hold things like the return program counter and saved values of some critical pointers (like the pointer to the caller's frame and the previously active object).
    Object Records
    Each time a program constructs an object (not an array), we will allocate space on the heap to hold all of the instance variables declared in the object's class (including inherited variables -- even though we can't access them).
    Dispatch tables
    When a method is invoked, we need a way to determine how to interpret the name of the method given the actual type of the object involved. To make this possible, each object structure allocated on the heap will contain a pointer to a table of pointers to the code for the method's associated with the type of the object. These don't need to be dynamically allocated. There will be one per class and they can be statically allocated before execution begins.
    Arrays
    We will also need to allocate blocks of storage to hold the elements of arrays created by constructions. We distinguish these from the allocation of single objects because they won't need to contain dispatch tables.

  6. For variables (i.e. instance variables, local variables, and formal parameters) stored within activation records and objects, the semantic processor's task it to determine the offset to each variable within the block of memory allocated.
  7. The actual layout of activation records for methods is strongly influenced by the hardware support for function/method calls on the target system.

  8. To get a feel for the impact of a machine architecture on variable allocations, recall the stack frame layout conventions of the MC68000/WC34000:

  9. A compiler for such a machine needs to keep track of offsets for local variables and parameters separately since they "grow" in different directions.
  10. For Woolite, it is sufficient to simply count the number of parameters and local variables. It is then easy to compute the offset to the nth variable or nth parameter.
  11. The layout of blocks of memory on the heap is slightly complicated by the ability to extend classes.
  12. In an OO language the supports inheritance, we cannot in general implement method invocations by branching directly to the code for the correct method. Instead, we must build tables of pointers to the code for each classes methods and dynamically select the correct methods to invoke at run-time.
  13. In addition to building these tables, we have to be able to find the correct table quickly when executing an invocation like
    	o.m( ... )
    	
  14. As a result, each object allocated on the heap will have to include a pointer to the dispatch method for its class.
  15. Arrays don't require dispatch table pointers. Each array will be a collection of integers (which require no dispatch tables) or pointer to objects that each contain their own dispatch table pointers.

Computer Science 434
Department of Computer Science
Williams College

TopDealing with InheritanceRun-time Storage Management