SLR(1) parsingTopGarbage Collection (cont.)

Garbage Collection (cont.)

  1. Mark-scan collectors don't work very well when objects of a wide variety of sizes need to be allocated.

  2. An alternative approach to garbage collection is based on copying. To implemnent this approach we divide the heap into two areas and switch back and forth between them by garbage collecting when the active area fills up. This seems wasteful (we only use half the memory available at any time). It has several advantages, including that the work performed depends only on the amount of useful data around, not on the amount of garbage.

  3. The pseudo-code for this version of "findthings" (which is better called "movethings") looks like:
    movethings( heapobject ** root )
    {  
        if ( *root != NULL) {
            if (  !(*root)->alreadymoved ) {
                      move the record **root to new heap
                      (*root)->forwardingaddress = newposition
                      (*root)->alreadymoved = TRUE
                      for all ``child''ren of copied root do
                                  movethings( & child )
             }
             *root = pointer to new copy of record
          }
    }
    

  4. So, to make this all work, we have to plan the layout of data in memory in a way that will let us:

  5. The simplest approach to most of these requirement is to "tag" each object and/or pointer with a "descriptor" (sometimes one bit is enough) that will tell the garbage collector what it is.

  6. To update pointers that point to objects that have already been moved, we need to store the new address of the object somewhere in the space that held the original object (the word after the length?). This is called a forwarding pointer.

  7. SO, all that's left is to find all the roots. Most of them (all of them if we do it right) are on the stack of activation records. To find them, we write a loop to look at all the words in the stack and call movethings with any value that we are sure is a heap pointer.

  8. The stack contains parameters and locals (which are all tagged pointers and integers) and return points and return frame pointers (stored by JSR and LINK instructions).

    We can easily tell if the "tagged" values are pointers (or not). The return information may look like pointers (i.e. may be odd), but they won't point to the heap, so a simple test against the heap boundaries will detect them.

  9. To make sure that roots aren't hiding in registers, we have to make sure our code stores all registers that hold pointers onto the stack before any call (including to the garbage collector).

  10. Finally, if we really are garbage collecting because we ran out of memory we don't want to run a recursive algorithm that might require lots of stack space. This can be fixed by switching from a depth first traversal of the findable data in the heap to a breadth first version using the new copy of the heap as our worklist/queue.

Computer Science 434
Department of Computer Science
Williams College

SLR(1) parsingTopGarbage Collection (cont.)