Esempio n. 1
0
static bool read_input() {
  char* line = read_line(stdin);
  userlog(LOG_DEBUG, "input: %s", (line ? line : "<null>"));

  if (line == NULL || strcmp(line, "EXIT") == 0) {
    userlog(LOG_INFO, "exiting: %s", line);
    return false;
  }

  if (strcmp(line, "ROOTS") == 0) {
    array* new_roots = array_create(20);
    CHECK_NULL(new_roots, false);

    while (1) {
      line = read_line(stdin);
      userlog(LOG_DEBUG, "input: %s", (line ? line : "<null>"));
      if (line == NULL || strlen(line) == 0) {
        return false;
      }
      else if (strcmp(line, "#") == 0) {
        break;
      }
      else {
        int l = strlen(line);
        if (l > 1 && line[l-1] == '/')  line[l-1] = '\0';
        CHECK_NULL(array_push(new_roots, strdup(line)), false);
      }
    }

    return update_roots(new_roots);
  }

  userlog(LOG_INFO, "unrecognised command: %s", line);
  return true;
}
Esempio n. 2
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");
}
Esempio n. 3
0
static void run_self_test() {
  array* test_roots = array_create(1);
  char* cwd = malloc(PATH_MAX);
  if (getcwd(cwd, PATH_MAX) == NULL) {
    strncpy(cwd, ".", PATH_MAX);
  }
  array_push(test_roots, cwd);
  update_roots(test_roots);
}