PROGRAM DESCRIPTORS
Implement record descriptors and pointer maps for the MiniJava compiler. For each record-type declaration, make a string literal to serve as the record descriptor. The length of the string should be equal to the number of fields in the record. The ith byte of the string should be p if the ith field of the record is a pointer (string, record, or array), or n if the ith field is a nonpointer. The allocRecord function should now take the record descriptor string (pointer) instead of a length; the allocator can obtain the length from the string literal. Then allocRecord should store this descriptor pointer at field zero of the record. Modify the runtime system appropriately. The user-visible fields of the record will now be at offsets 1, 2, 3,… instead of 0, 1, 2,…; adjust the compiler appropriately. Design a descriptor format for arrays, and implement it in the compiler and runtime system. Implement a temp-map with a boolean for each temporary: Is it a pointer or not? Also make a similar map for the offsets in each stack frame, for frame-resident pointer variables. You will not need to handle derived pointers, as your MiniJava compiler probably does not keep derived pointers live across function calls. For each procedure call, put a new return-address label Lret immediately after the call instruction. For each one, make a data fragment of the form
Lptrmap327 : |
.word |
Lptrmap326 |
link to previous ptr-map entry |
.word |
Lret327 |
key for this entry | |
.word |
… |
pointer map for this return address | |
⋮ |
and then the runtime system can traverse this linked list of pointer-map entries, and perhaps build it into a data structure of its own choosing for fast lookup of return addresses. The data-layout pseudo-instructions (.word, etc.) are, of course, machine-dependent.