0.6.7.22: removed CVS dollar-Header-dollar tags from sources
[sbcl.git] / src / runtime / gencgc.c
index 29dea31..948ac48 100644 (file)
  */
 
 /*
- * $Header$
- */
-
-/*
  * For a review of garbage collection techniques (e.g. generational
  * GC) and terminology (e.g. "scavenging") see Paul R. Wilson,
  * "Uniprocessor Garbage Collection Techniques". As of 20000618, this
 #include "runtime.h"
 #include "sbcl.h"
 #include "os.h"
+#include "interr.h"
 #include "globals.h"
 #include "interrupt.h"
 #include "validate.h"
 #include "lispregs.h"
+#include "arch.h"
 #include "gc.h"
 #include "gencgc.h"
 
@@ -365,21 +363,24 @@ print_generation_stats(int verbose) /* FIXME: should take FILE argument */
 
        for (j = 0; j < last_free_page; j++)
            if (page_table[j].gen == i) {
+
                /* Count the number of boxed pages within the given
-                * generation */
-               if (page_table[j].allocated == BOXED_PAGE)
+                * generation. */
+               if (page_table[j].allocated == BOXED_PAGE) {
                    if (page_table[j].large_object)
                        large_boxed_cnt++;
                    else
                        boxed_cnt++;
-       
+               }
+
                /* Count the number of unboxed pages within the given
-                * generation */
-               if (page_table[j].allocated == UNBOXED_PAGE)
+                * generation. */
+               if (page_table[j].allocated == UNBOXED_PAGE) {
                    if (page_table[j].large_object)
                        large_unboxed_cnt++;
                    else
                        unboxed_cnt++;
+               }
            }
 
        gc_assert(generations[i].bytes_allocated
@@ -1741,6 +1742,9 @@ copy_large_unboxed_object(lispobj object, int nwords)
 
 #define DIRECT_SCAV 0
 
+/* FIXME: Most calls end up going to a little trouble to compute an
+ * 'nwords' value. The system might be a little simpler if this
+ * function used an 'end' parameter instead. */
 static void
 scavenge(lispobj *start, long nwords)
 {
@@ -4050,7 +4054,7 @@ search_read_only_space(lispobj *pointer)
 static lispobj *
 search_static_space(lispobj *pointer)
 {
-    lispobj* start = (lispobj*)static_space;
+    lispobj* start = (lispobj*)STATIC_SPACE_START;
     lispobj* end = (lispobj*)SymbolValue(STATIC_SPACE_FREE_POINTER);
     if ((pointer < start) || (pointer >= end))
        return NULL;
@@ -4114,7 +4118,8 @@ valid_dynamic_space_pointer(lispobj *pointer)
        case type_FuncallableInstanceHeader:
        case type_ByteCodeFunction:
        case type_ByteCodeClosure:
-           if ((int)pointer != ((int)start_addr+type_FunctionPointer)) {
+           if ((unsigned)pointer !=
+               ((unsigned)start_addr+type_FunctionPointer)) {
                if (gencgc_verbose)
                    FSHOW((stderr,
                           "/Wf2: %x %x %x\n",
@@ -4131,7 +4136,8 @@ valid_dynamic_space_pointer(lispobj *pointer)
        }
        break;
     case type_ListPointer:
-       if ((int)pointer != ((int)start_addr+type_ListPointer)) {
+       if ((unsigned)pointer !=
+           ((unsigned)start_addr+type_ListPointer)) {
            if (gencgc_verbose)
                FSHOW((stderr,
                       "/Wl1: %x %x %x\n",
@@ -4156,7 +4162,8 @@ valid_dynamic_space_pointer(lispobj *pointer)
            return 0;
        }
     case type_InstancePointer:
-       if ((int)pointer != ((int)start_addr+type_InstancePointer)) {
+       if ((unsigned)pointer !=
+           ((unsigned)start_addr+type_InstancePointer)) {
            if (gencgc_verbose)
                FSHOW((stderr,
                       "/Wi1: %x %x %x\n",
@@ -4172,7 +4179,8 @@ valid_dynamic_space_pointer(lispobj *pointer)
        }
        break;
     case type_OtherPointer:
-       if ((int)pointer != ((int)start_addr+type_OtherPointer)) {
+       if ((unsigned)pointer !=
+           ((int)start_addr+type_OtherPointer)) {
            if (gencgc_verbose)
                FSHOW((stderr,
                       "/Wo1: %x %x %x\n",
@@ -4481,8 +4489,12 @@ preserve_pointer(void *addr)
 
     region_allocation = page_table[addr_page_index].allocated;
 
-    /* Check the offset within the page */
-    if (((int)addr & 0xfff) > page_table[addr_page_index].bytes_used)
+    /* Check the offset within the page.
+     *
+     * FIXME: The mask should have a symbolic name, and ideally should
+     * be derived from page size instead of hardwired to 0xfff.
+     * (Also fix other uses of 0xfff, elsewhere.) */
+    if (((unsigned)addr & 0xfff) > page_table[addr_page_index].bytes_used)
        return;
 
     if (enable_pointer_filter && !valid_dynamic_space_pointer(addr))
@@ -4510,7 +4522,7 @@ preserve_pointer(void *addr)
        if ((page_table[addr_page_index].allocated == FREE_PAGE)
            || (page_table[addr_page_index].bytes_used == 0)
            /* Check the offset within the page. */
-           || (((int)addr & 0xfff)
+           || (((unsigned)addr & 0xfff)
                > page_table[addr_page_index].bytes_used)) {
            FSHOW((stderr,
                   "weird? ignore ptr 0x%x to freed area of large object\n",
@@ -4588,14 +4600,20 @@ scavenge_thread_stacks(void)
                           vector_length));
                if (vector_length > 0) {
                    lispobj *stack_pointer = (lispobj*)stack->data[0];
-                   if ((stack_pointer < control_stack) ||
-                       (stack_pointer > control_stack_end))
+                   if ((stack_pointer < (lispobj *)CONTROL_STACK_START) ||
+                       (stack_pointer > (lispobj *)CONTROL_STACK_END))
                        lose("invalid stack pointer %x",
                             (unsigned)stack_pointer);
-                   if ((stack_pointer > control_stack) &&
-                       (stack_pointer < control_stack_end)) {
-                       unsigned int length = ((int)control_stack_end -
-                                              (int)stack_pointer) / 4;
+                   if ((stack_pointer > (lispobj *)CONTROL_STACK_START) &&
+                       (stack_pointer < (lispobj *)CONTROL_STACK_END)) {
+                       /* FIXME: Ick!
+                        *   (1) hardwired word length = 4; and as usual,
+                        *       when fixing this, check for other places
+                        *       with the same problem
+                        *   (2) calling it 'length' suggests bytes;
+                        *       perhaps 'size' instead? */
+                       unsigned int length = ((unsigned)CONTROL_STACK_END -
+                                              (unsigned)stack_pointer) / 4;
                        int j;
                        if (length >= vector_length) {
                            lose("invalid stack size %d >= vector length %d",
@@ -5243,12 +5261,12 @@ print_ptr(lispobj *addr)
 extern int undefined_tramp;
 
 static void
-verify_space(lispobj*start, size_t words)
+verify_space(lispobj *start, size_t words)
 {
-    int dynamic_space = (find_page_index((void*)start) != -1);
-    int readonly_space =
-       (READ_ONLY_SPACE_START <= (int)start &&
-        (int)start < SymbolValue(READ_ONLY_SPACE_FREE_POINTER));
+    int is_in_dynamic_space = (find_page_index((void*)start) != -1);
+    int is_in_readonly_space =
+       (READ_ONLY_SPACE_START <= (unsigned)start &&
+        (unsigned)start < SymbolValue(READ_ONLY_SPACE_FREE_POINTER));
 
     while (words > 0) {
        size_t count = 1;
@@ -5260,7 +5278,7 @@ verify_space(lispobj*start, size_t words)
                (READ_ONLY_SPACE_START <= thing &&
                 thing < SymbolValue(READ_ONLY_SPACE_FREE_POINTER));
            int to_static_space =
-               ((int)static_space <= thing &&
+               (STATIC_SPACE_START <= thing &&
                 thing < SymbolValue(STATIC_SPACE_FREE_POINTER));
 
            /* Does it point to the dynamic space? */
@@ -5276,7 +5294,7 @@ verify_space(lispobj*start, size_t words)
                }
                /* Check that its not in the RO space as it would then be a
                 * pointer from the RO to the dynamic space. */
-               if (readonly_space) {
+               if (is_in_readonly_space) {
                    lose("ptr to dynamic space %x from RO space %x",
                         thing, start);
                }
@@ -5289,7 +5307,7 @@ verify_space(lispobj*start, size_t words)
            } else {
                /* Verify that it points to another valid space. */
                if (!to_readonly_space && !to_static_space
-                   && (thing != (int)&undefined_tramp)) {
+                   && (thing != (unsigned)&undefined_tramp)) {
                    lose("Ptr %x @ %x sees junk.", thing, start);
                }
            }
@@ -5334,7 +5352,7 @@ verify_space(lispobj*start, size_t words)
                        /* Check that it's not in the dynamic space.
                         * FIXME: Isn't is supposed to be OK for code
                         * objects to be in the dynamic space these days? */
-                       if (dynamic_space
+                       if (is_in_dynamic_space
                            /* It's ok if it's byte compiled code. The trace
                             * table offset will be a fixnum if it's x86
                             * compiled code - check. */
@@ -5435,19 +5453,25 @@ verify_space(lispobj*start, size_t words)
 static void
 verify_gc(void)
 {
+    /* FIXME: It would be nice to make names consistent so that
+     * foo_size meant size *in* *bytes* instead of size in some
+     * arbitrary units. (Yes, this caused a bug, how did you guess?:-)
+     * Some counts of lispobjs are called foo_count; it might be good
+     * to grep for all foo_size and rename the appropriate ones to
+     * foo_count. */
     int read_only_space_size =
        (lispobj*)SymbolValue(READ_ONLY_SPACE_FREE_POINTER)
        - (lispobj*)READ_ONLY_SPACE_START;
     int static_space_size =
        (lispobj*)SymbolValue(STATIC_SPACE_FREE_POINTER)
-       - (lispobj*)static_space;
+       - (lispobj*)STATIC_SPACE_START;
     int binding_stack_size =
        (lispobj*)SymbolValue(BINDING_STACK_POINTER)
        - (lispobj*)BINDING_STACK_START;
 
     verify_space((lispobj*)READ_ONLY_SPACE_START, read_only_space_size);
-    verify_space((lispobj*)static_space, static_space_size);
-    verify_space((lispobj*)BINDING_STACK_START, binding_stack_size);
+    verify_space((lispobj*)STATIC_SPACE_START   , static_space_size);
+    verify_space((lispobj*)BINDING_STACK_START  , binding_stack_size);
 }
 
 static void
@@ -5508,7 +5532,7 @@ verify_zero_fill(void)
        } else {
            int free_bytes = 4096 - page_table[page].bytes_used;
            if (free_bytes > 0) {
-               int *start_addr = (int *)((int)page_address(page)
+               int *start_addr = (int *)((unsigned)page_address(page)
                                          + page_table[page].bytes_used);
                int size = free_bytes / 4;
                int i;
@@ -5635,9 +5659,11 @@ garbage_collect_generation(int generation, int raise)
     /* Scavenge the stack's conservative roots. */
     {
        lispobj **ptr;
-       for (ptr = (lispobj **)CONTROL_STACK_END-1;
-            ptr > (lispobj **)&raise; ptr--)
+       for (ptr = (lispobj **)CONTROL_STACK_END - 1;
+            ptr > (lispobj **)&raise;
+            ptr--) {
            preserve_pointer(*ptr);
+       }
     }
 #ifdef CONTROL_STACKS
     scavenge_thread_stacks();
@@ -5666,26 +5692,28 @@ garbage_collect_generation(int generation, int raise)
     }
 
     /* Scavenge the binding stack. */
-    scavenge(binding_stack,
-            (lispobj *)SymbolValue(BINDING_STACK_POINTER) - binding_stack);
+    scavenge(BINDING_STACK_START,
+            (lispobj *)SymbolValue(BINDING_STACK_POINTER) -
+            (lispobj *)BINDING_STACK_START);
 
     if (SymbolValue(SCAVENGE_READ_ONLY_SPACE) != NIL) {
        read_only_space_size =
-           (lispobj *)SymbolValue(READ_ONLY_SPACE_FREE_POINTER)
-           - read_only_space;
+           (lispobj*)SymbolValue(READ_ONLY_SPACE_FREE_POINTER) -
+           (lispobj*)READ_ONLY_SPACE_START;
        FSHOW((stderr,
               "/scavenge read only space: %d bytes\n",
               read_only_space_size * sizeof(lispobj)));
-       scavenge(read_only_space, read_only_space_size);
+       scavenge(READ_ONLY_SPACE_START, read_only_space_size);
     }
 
-    static_space_size = (lispobj *)SymbolValue(STATIC_SPACE_FREE_POINTER)
-       - static_space;
+    static_space_size =
+       (lispobj *)SymbolValue(STATIC_SPACE_FREE_POINTER) -
+       (lispobj *)STATIC_SPACE_START;
     if (gencgc_verbose > 1)
        FSHOW((stderr,
               "/scavenge static space: %d bytes\n",
               static_space_size * sizeof(lispobj)));
-    scavenge(static_space, static_space_size);
+    scavenge(STATIC_SPACE_START, static_space_size);
 
     /* All generations but the generation being GCed need to be
      * scavenged. The new_space generation needs special handling as
@@ -6030,7 +6058,7 @@ gc_init(void)
 
     gc_init_tables();
 
-    heap_base = (void*)DYNAMIC_0_SPACE_START;
+    heap_base = (void*)DYNAMIC_SPACE_START;
 
     /* Initialize each page structure. */
     for (i = 0; i < NUM_PAGES; i++) {
@@ -6089,7 +6117,7 @@ void
 gencgc_pickup_dynamic(void)
 {
     int page = 0;
-    int addr = DYNAMIC_0_SPACE_START;
+    int addr = DYNAMIC_SPACE_START;
     int alloc_ptr = SymbolValue(ALLOCATION_POINTER);
 
     /* Initialize the first region. */
@@ -6099,7 +6127,7 @@ gencgc_pickup_dynamic(void)
        page_table[page].bytes_used = 4096;
        page_table[page].large_object = 0;
        page_table[page].first_object_offset =
-           (void *)DYNAMIC_0_SPACE_START - page_address(page);
+           (void *)DYNAMIC_SPACE_START - page_address(page);
        addr += 4096;
        page++;
     } while (addr < alloc_ptr);