diff --git a/src/gc.c b/src/gc.c index 102b9f15..76f2965e 100644 --- a/src/gc.c +++ b/src/gc.c @@ -123,15 +123,16 @@ gc_init () /*:((internal)) */ MAX_STRING = atoi (p); long arena_bytes = (ARENA_SIZE + JAM_SIZE) * sizeof (struct scm); -#if! POINTER_CELLS - long alloc_bytes = arena_bytes + (STACK_SIZE * sizeof (SCM)); +#if !POINTER_CELLS || GC_NOFLIP + long alloc_bytes = arena_bytes + (STACK_SIZE * sizeof (struct scm)); #else long alloc_bytes = (arena_bytes * 2) + (STACK_SIZE * sizeof (struct scm*)); #endif + g_arena = malloc (alloc_bytes); g_cells = g_arena; -#if! POINTER_CELLS +#if !POINTER_CELLS || GC_NOFLIP g_stack_array = g_arena + arena_bytes; #else g_stack_array = g_arena + (arena_bytes * 2); @@ -346,7 +347,17 @@ gc_init_news () /*:((internal)) */ g_news = g_cells + g_free; SCM ncell_arena = cell_arena; #else + +#if GC_NOFLIP g_news = g_free; +#else + char* p = g_cells - M2_CELL_SIZE; + if (p == g_arena) + g_news = g_free; + else + g_news = g_arena; +#endif + SCM ncell_arena = g_news; #endif @@ -413,14 +424,114 @@ void *p = realloc (g_cells - M2_CELL_SIZE, realloc_bytes); return 0; } +void +gc_cellcpy (struct scm *dest, struct scm *src, size_t n) +{ + void *p = src; + void *q = dest; + long dist = p - q; + while (n != 0) + { + long t = src->type; + long a = src->car; + long d = src->cdr; + dest->type = t; + if (t == TBROKEN_HEART) + { + dest->type = 0; + a = 0; + d = 0; +#if 0 + assert_msg (0, "gc_cellcpy: broken heart"); +#endif + } + if (t == TMACRO + || t == TPAIR + || t == TREF + || t == TVARIABLE) + dest->car = a - dist; + else + dest->car = a; + if ((t == TBYTES + || t == TCLOSURE + || t == TCONTINUATION + || t == TKEYWORD + || t == TMACRO + || t == TPAIR + || t == TPORT + || t == TSPECIAL + || t == TSTRING + || t == TSTRUCT + || t == TSYMBOL + || t == TVALUES + || t == TVECTOR) + && src->cdr) // allow for 0 terminated list of symbols + dest->cdr = d - dist; + else + dest->cdr = d; + if (t == TBYTES) + { +#if GC_TEST + eputs ("copying bytes["); + eputs (ntoab (&src->cdr, 16, 0)); + eputs (", "); + eputs (ntoab (a, 10, 0)); + eputs ("]: "); + eputs (&src->cdr); + eputs ("\n to ["); + eputs (ntoab (&dest->cdr, 16, 0)); +#endif + memcpy (&dest->cdr, &src->cdr, a); +#if GC_TEST + eputs ("]: "); + eputs (&dest->cdr); + eputs ("\n"); +#endif + n = n - a; + int c = bytes_cells (a) * M2_CELL_SIZE; + dest = dest + c; + src = src + c; + } + else + { + n = n - 1; + dest = dest + M2_CELL_SIZE; + src = src + M2_CELL_SIZE; + } + } +} + void gc_flip () { #if POINTER_CELLS + if (g_free - g_news > JAM_SIZE) + JAM_SIZE = (g_free - g_news) + ((g_free - g_news) / 2); + +#if GC_NOFLIP + cell_arena = g_cells - M2_CELL_SIZE; /* FIXME? */ + gc_cellcpy (g_cells, g_news, (g_free - g_news) / M2_CELL_SIZE); + + void *p = g_news; + void *q = g_cells; + long dist = p - q; + + g_free = (void*)g_free - dist; +#if !GC_TEST + g_symbols = (void*)g_symbols - dist; + g_symbol_max = (void*)g_symbol_max - dist; + g_macros = (void*)g_macros - dist; + g_ports = (void*)g_ports - dist; + M0 = (void*)M0 - dist; +#endif + +#else + g_cells = g_news; cell_arena = g_news - M2_CELL_SIZE; cell_zero = cell_arena + M2_CELL_SIZE; cell_nil = cell_zero + M2_CELL_SIZE; +#endif #endif if (g_debug > 2) @@ -510,7 +621,14 @@ gc_loop (SCM scan) /*:((internal)) */ { long t = NTYPE (scan); if (t == TBROKEN_HEART) - assert_msg (0, "broken heart"); + { + NTYPE (scan) = 0; + NCAR (scan) = 0; + NCDR (scan) = 0; +#if 0 + assert_msg (0, "gc_loop: broken heart"); +#endif + } if (t == TMACRO || t == TPAIR || t == TREF @@ -603,9 +721,14 @@ gc_ () gc_copy (s); #if POINTER_CELLS + cell_arena = g_news - M2_CELL_SIZE; /* for debugging */ + #if GC_TEST cell_nil = save_gfree; + cell_zero = cell_nil - M2_CELL_SIZE; + g_symbol_max = g_free; #else + cell_nil = save_gfree; long save_gsymbols = g_symbols; cell_nil = save_gfree; g_symbols = 0; @@ -616,13 +739,16 @@ gc_ () #endif #endif +#if !GC_TEST g_symbols = gc_copy (g_symbols); g_macros = gc_copy (g_macros); g_ports = gc_copy (g_ports); M0 = gc_copy (M0); + long i; for (i = g_stack; i < STACK_SIZE; i = i + 1) copy_stack (i, gc_copy (g_stack_array[i])); +#endif gc_loop (cell_nil); }