1.0.12.4: delete bad ROOM test
[sbcl.git] / src / runtime / gencgc.c
index 8f60129..719e127 100644 (file)
@@ -42,6 +42,7 @@
 #include "gc.h"
 #include "gc-internal.h"
 #include "thread.h"
+#include "alloc.h"
 #include "genesis/vector.h"
 #include "genesis/weak-pointer.h"
 #include "genesis/fdefn.h"
@@ -1095,7 +1096,7 @@ gc_heap_exhausted_error_or_lose (long available, long requested)
     }
     else {
         /* FIXME: assert free_pages_lock held */
-        thread_mutex_unlock(&free_pages_lock);
+        (void)thread_mutex_unlock(&free_pages_lock);
         funcall2(SymbolFunction(HEAP_EXHAUSTED_ERROR),
                  alloc_number(available), alloc_number(requested));
         lose("HEAP-EXHAUSTED-ERROR fell through");
@@ -1816,7 +1817,9 @@ gencgc_apply_code_fixups(struct code *old_code, struct code *new_code)
                     old_value - displacement;
         }
     } else {
-        fprintf(stderr, "widetag of fixup vector is %d\n", widetag_of(fixups_vector->header));
+        /* This used to just print a note to stderr, but a bogus fixup seems to
+         * indicate real heap corruption, so a hard hailure is in order. */
+        lose("fixup vector %p has a bad widetag: %d\n", fixups_vector, widetag_of(fixups_vector->header));
     }
 
     /* Check for possible errors. */
@@ -2050,29 +2053,21 @@ size_lutex(lispobj *where)
 static long
 scav_weak_pointer(lispobj *where, lispobj object)
 {
-    struct weak_pointer *wp = weak_pointers;
-    /* Push the weak pointer onto the list of weak pointers.
-     * Do I have to watch for duplicates? Originally this was
-     * part of trans_weak_pointer but that didn't work in the
-     * case where the WP was in a promoted region.
+    /* Since we overwrite the 'next' field, we have to make
+     * sure not to do so for pointers already in the list.
+     * Instead of searching the list of weak_pointers each
+     * time, we ensure that next is always NULL when the weak
+     * pointer isn't in the list, and not NULL otherwise.
+     * Since we can't use NULL to denote end of list, we
+     * use a pointer back to the same weak_pointer.
      */
+    struct weak_pointer * wp = (struct weak_pointer*)where;
 
-    /* Check whether it's already in the list. */
-    while (wp != NULL) {
-        if (wp == (struct weak_pointer*)where) {
-            break;
-        }
-        wp = wp->next;
-    }
-    if (wp == NULL) {
-        /* Add it to the start of the list. */
-        wp = (struct weak_pointer*)where;
-        if (wp->next != weak_pointers) {
-            wp->next = weak_pointers;
-        } else {
-            /*SHOW("avoided write to weak pointer");*/
-        }
+    if (NULL == wp->next) {
+        wp->next = weak_pointers;
         weak_pointers = wp;
+        if (NULL == wp->next)
+            wp->next = wp;
     }
 
     /* Do not let GC scavenge the value slot of the weak pointer.
@@ -3991,7 +3986,7 @@ garbage_collect_generation(generation_index_t generation, int raise)
 #else
             esp = (void **)((void *)&raise);
 #endif
-            for (ptr = ((void **)th->control_stack_end)-1; ptr > esp;  ptr--) {
+            for (ptr = ((void **)th->control_stack_end)-1; ptr >= esp;  ptr--) {
                 preserve_pointer(*ptr);
             }
         }
@@ -4589,7 +4584,7 @@ gc_initialize_pointers(void)
  * The check for a GC trigger is only performed when the current
  * region is full, so in most cases it's not needed. */
 
-char *
+lispobj *
 alloc(long nbytes)
 {
     struct thread *thread=arch_os_get_current_thread();
@@ -4682,7 +4677,7 @@ alloc(long nbytes)
  * catch GENCGC-related write-protect violations
  */
 
-void unhandled_sigmemoryfault(void);
+void unhandled_sigmemoryfault(void* addr);
 
 /* Depending on which OS we're running under, different signals might
  * be raised for a violation of write protection in the heap. This
@@ -4709,7 +4704,7 @@ gencgc_handle_wp_violation(void* fault_addr)
 
         /* It can be helpful to be able to put a breakpoint on this
          * case to help diagnose low-level problems. */
-        unhandled_sigmemoryfault();
+        unhandled_sigmemoryfault(fault_addr);
 
         /* not within the dynamic space -- not our responsibility */
         return 0;
@@ -4740,7 +4735,7 @@ gencgc_handle_wp_violation(void* fault_addr)
  * are about to let Lisp deal with it. It's basically just a
  * convenient place to set a gdb breakpoint. */
 void
-unhandled_sigmemoryfault()
+unhandled_sigmemoryfault(void *addr)
 {}
 
 void gc_alloc_update_all_page_tables(void)