1.0.21.24: saving runtime options in executables
[sbcl.git] / src / runtime / cheneygc.c
index 60bd5af..41eb42b 100644 (file)
@@ -30,6 +30,7 @@
 #include "genesis/static-symbols.h"
 #include "genesis/primitive-objects.h"
 #include "thread.h"
+#include "arch.h"
 
 /* So you need to debug? */
 #if 0
@@ -48,8 +49,6 @@ lispobj *new_space_free_pointer;
 
 static void scavenge_newspace(void);
 
-extern unsigned long bytes_consed_between_gcs;
-
 \f
 /* collecting garbage */
 
@@ -222,11 +221,16 @@ collect_garbage(generation_index_t ignore)
 
     /* Scan the weak pointers. */
 #ifdef PRINTNOISE
+    printf("Scanning weak hash tables ...\n");
+#endif
+    scan_weak_hash_tables();
+
+    /* Scan the weak pointers. */
+#ifdef PRINTNOISE
     printf("Scanning weak pointers ...\n");
 #endif
     scan_weak_pointers();
 
-
     /* Flip spaces. */
 #ifdef PRINTNOISE
     printf("Flipping spaces ...\n");
@@ -236,7 +240,7 @@ collect_garbage(generation_index_t ignore)
      * RSS by zeroing the from_space or madvise(MADV_DONTNEED) or
      * similar os-dependent tricks here */
     os_zero((os_vm_address_t) from_space,
-            (os_vm_size_t) DYNAMIC_SPACE_SIZE);
+            (os_vm_size_t) dynamic_space_size);
 
     current_dynamic_space = new_space;
     dynamic_space_free_pointer = new_space_free_pointer;
@@ -296,6 +300,7 @@ scavenge_newspace(void)
                 here,new_space_free_pointer); */
         next = new_space_free_pointer;
         scavenge(here, next - here);
+        scav_weak_hash_tables();
         here = next;
     }
     /* printf("done with newspace\n"); */
@@ -332,9 +337,9 @@ scavenge_interrupt_context(os_context_t *context)
        0x7FFFFFFFFFFFFFFF on 64-bit platforms */
     lip_offset = (((unsigned long)1) << (N_WORD_BITS - 1)) - 1;
     lip_register_pair = -1;
-    for (i = 0; i < (sizeof(boxed_registers) / sizeof(int)); i++) {
+    for (i = 0; i < (int)(sizeof(boxed_registers) / sizeof(int)); i++) {
         unsigned long reg;
-        long offset;
+        unsigned long offset;
         int index;
 
         index = boxed_registers[i];
@@ -367,7 +372,7 @@ scavenge_interrupt_context(os_context_t *context)
 #endif
 
     /* Scavenge all boxed registers in the context. */
-    for (i = 0; i < (sizeof(boxed_registers) / sizeof(int)); i++) {
+    for (i = 0; i < (int)(sizeof(boxed_registers) / sizeof(int)); i++) {
         int index;
         lispobj foo;
 
@@ -489,20 +494,6 @@ print_garbage(lispobj *from_space, lispobj *from_space_free_pointer)
 }
 
 \f
-/* vector-like objects */
-
-static long
-scav_vector(lispobj *where, lispobj object)
-{
-    if (HeaderValue(object) == subtype_VectorValidHashing) {
-        *where =
-            (subtype_VectorMustRehash<<N_WIDETAG_BITS) | SIMPLE_VECTOR_WIDETAG;
-    }
-
-    return 1;
-}
-
-\f
 /* weak pointers */
 
 #define WEAK_POINTER_NWORDS \
@@ -561,7 +552,6 @@ void
 gc_init(void)
 {
     gc_init_tables();
-    scavtab[SIMPLE_VECTOR_WIDETAG] = scav_vector;
     scavtab[WEAK_POINTER_WIDETAG] = scav_weak_pointer;
 }
 
@@ -598,7 +588,7 @@ void set_auto_gc_trigger(os_vm_size_t dynamic_usage)
              (unsigned long)((os_vm_address_t)dynamic_space_free_pointer
                              - (os_vm_address_t)current_dynamic_space));
 
-    length = os_trunc_size_to_page(DYNAMIC_SPACE_SIZE - dynamic_usage);
+    length = os_trunc_size_to_page(dynamic_space_size - dynamic_usage);
     if (length < 0)
         lose("set_auto_gc_trigger: tried to set gc trigger too high! (0x%08lx)\n",
              (unsigned long)dynamic_usage);
@@ -621,7 +611,7 @@ void clear_auto_gc_trigger(void)
         return;
 
     addr = (os_vm_address_t)current_auto_gc_trigger;
-    length = DYNAMIC_SPACE_SIZE + (os_vm_address_t)current_dynamic_space - addr;
+    length = dynamic_space_size + (os_vm_address_t)current_dynamic_space - addr;
 
 #if defined(SUNOS) || defined(SOLARIS)
     /* don't want to force whole space into swapping mode... */
@@ -632,3 +622,42 @@ void clear_auto_gc_trigger(void)
 
     current_auto_gc_trigger = NULL;
 }
+
+static boolean
+gc_trigger_hit(void *addr)
+{
+    if (current_auto_gc_trigger == NULL)
+        return 0;
+    else{
+        return (addr >= (void *)current_auto_gc_trigger &&
+                addr <((void *)current_dynamic_space + dynamic_space_size));
+    }
+}
+
+boolean
+cheneygc_handle_wp_violation(os_context_t *context, void *addr)
+{
+    if(!foreign_function_call_active && gc_trigger_hit(addr)){
+        struct thread *thread=arch_os_get_current_thread();
+        clear_auto_gc_trigger();
+        /* Don't flood the system with interrupts if the need to gc is
+         * already noted. This can happen for example when SUB-GC
+         * allocates or after a gc triggered in a WITHOUT-GCING. */
+        if (SymbolValue(GC_PENDING,thread) == NIL) {
+            if (SymbolValue(GC_INHIBIT,thread) == NIL) {
+                if (arch_pseudo_atomic_atomic(context)) {
+                    /* set things up so that GC happens when we finish
+                     * the PA section */
+                    SetSymbolValue(GC_PENDING,T,thread);
+                    arch_set_pseudo_atomic_interrupted(context);
+                } else {
+                    maybe_gc(context);
+                }
+            } else {
+                SetSymbolValue(GC_PENDING,T,thread);
+            }
+        }
+        return 1;
+    }
+    return 0;
+}