예제 #1
0
/* Perform a mark_and_compact garbage collection, moving all live objects
 * to the start of the heap. Anything that we don't mark is dead.
 *
 * 1. Walk object graph starting from roots, marking live objects.
 *
 * 2. Walk all live objects and compute their forwarding addresses starting from start_of_heap.
 *
 * 3. Alter all non-NULL roots to point to the object's forwarding address.
 *
 * 4. For each live object:
 * 	    a) alter all non-NULL managed pointer fields to point to the forwarding addresses.
 * 		b) unmark object
 *
 * 5. Physically move object to forwarding address towards front of heap and reset marked.
 *
 *    This phase must be last as the object stores the forwarding address. When we move,
 *    we overwrite objects and could kill a forwarding address in a live object.
 */
void gc() {
    if (DEBUG) printf("GC\n");

	gc_mark();

	// TODO: add next_live field to heap_object to avoid walking all objects to find live
	// oops actually must move objects from low to high ptr addresses.
	// reallocate all live objects starting from start_of_heap
	if (DEBUG) printf("FORWARD\n");
	next_free_forwarding = heap;
	foreach_live(realloc_object);  		// for each marked (live) object, record forwarding address

	// make sure all roots point at new object addresses
	update_roots();                     // can't move objects before updating roots; roots point at *old* location

	if (DEBUG) printf("UPDATE PTR FIELDS\n");
	foreach_live(update_ptr_fields);

	// Now that we know where to move objects, update and move objects
	if (DEBUG) printf("COMPACT\n");
	// TODO: can this be foreach_live()?
	foreach_object(move_live_objects_to_forwarding_addr); // also visits the dead to wack p->magic

	// reset highwater mark *after* we've moved everything around; foreach_object() uses next_free
	next_free = next_free_forwarding;	// next object to be allocated would occur here

	if (DEBUG) printf("DONE GC\n");
}
예제 #2
0
void unmark() { foreach_object(unmark_object); }
예제 #3
0
void gc_unmark() {
	if (DEBUG) printf("UNMARK\n");
	foreach_object(unmark_object);
}