int main(int argc, char **argv) { // Debug flags debug_gc = getEnvFlag("MINILISP_DEBUG_GC"); always_gc = getEnvFlag("MINILISP_ALWAYS_GC"); // Memory allocation memory = alloc_semispace(); // Constants and primitives Symbols = Nil; void *root = NULL; DEFINE2(env, expr); *env = make_env(root, &Nil, &Nil); define_constants(root, env); define_primitives(root, env); // The main loop printf("%s", ">"); for (;;) { *expr = read_expr(root); if (!*expr) return 0; if (*expr == Cparen) error("Stray close parenthesis"); if (*expr == Dot) error("Stray dot"); print(eval(root, env, expr)); printf("\n%s", ">"); } }
// Implements Cheney's copying garbage collection algorithm. // http://en.wikipedia.org/wiki/Cheney%27s_algorithm static void gc(void *root) { assert(!gc_running); gc_running = true; // Allocate a new semi-space. from_space = memory; memory = alloc_semispace(); // Initialize the two pointers for GC. Initially they point to the beginning of the to-space. scan1 = scan2 = memory; // Copy the GC root objects first. This moves the pointer scan2. forward_root_objects(root); // Copy the objects referenced by the GC root objects located between scan1 and scan2. Once it's // finished, all live objects (i.e. objects reachable from the root) will have been copied to // the to-space. while (scan1 < scan2) { switch (scan1->type) { case TINT: case TSYMBOL: case TPRIMITIVE: // Any of the above types does not contain a pointer to a GC-managed object. break; case TCELL: scan1->car = forward(scan1->car); scan1->cdr = forward(scan1->cdr); break; case TFUNCTION: case TMACRO: scan1->params = forward(scan1->params); scan1->body = forward(scan1->body); scan1->env = forward(scan1->env); break; case TENV: scan1->vars = forward(scan1->vars); scan1->up = forward(scan1->up); break; default: error("Bug: copy: unknown type %d", scan1->type); } scan1 = (Obj *)((uint8_t *)scan1 + scan1->size); } // Finish up GC. #ifdef _WIN32 free(from_space); #else munmap(from_space, MEMORY_SIZE); #endif size_t old_nused = mem_nused; mem_nused = (size_t)((uint8_t *)scan1 - (uint8_t *)memory); if (debug_gc) fprintf(stderr, "GC: %zu bytes out of %zu bytes copied.\n", mem_nused, old_nused); gc_running = false; }