win32-os.c: Split up handle_exception
[sbcl.git] / src / runtime / gc-common.c
index 6c24c27..96ac8df 100644 (file)
@@ -95,27 +95,8 @@ os_vm_size_t bytes_consed_between_gcs = 12*1024*1024;
 /*
  * copying objects
  */
-static
-lispobj
-gc_general_copy_object(lispobj object, long nwords, int page_type_flag)
-{
-    int tag;
-    lispobj *new;
-
-    gc_assert(is_lisp_pointer(object));
-    gc_assert(from_space_p(object));
-    gc_assert((nwords & 0x01) == 0);
-
-    /* Get tag of object. */
-    tag = lowtag_of(object);
 
-    /* Allocate space. */
-    new = gc_general_alloc(nwords*N_WORD_BYTES, page_type_flag, ALLOC_QUICK);
-
-    /* Copy the object. */
-    memcpy(new,native_pointer(object),nwords*N_WORD_BYTES);
-    return make_lispobj(new,tag);
-}
+/* gc_general_copy_object is inline from gc-internal.h */
 
 /* to copy a boxed object */
 lispobj
@@ -2662,7 +2643,7 @@ maybe_gc(os_context_t *context)
      * A kludgy alternative is to propagate the sigmask change to the
      * outer context.
      */
-#ifndef LISP_FEATURE_WIN32
+#if !(defined(LISP_FEATURE_WIN32) || defined(LISP_FEATURE_SB_SAFEPOINT))
     check_gc_signals_unblocked_or_lose(os_context_sigmask_addr(context));
     unblock_gc_signals(0, 0);
 #endif
@@ -2687,8 +2668,10 @@ maybe_gc(os_context_t *context)
         sigset_t *context_sigmask = os_context_sigmask_addr(context);
         if (!deferrables_blocked_p(context_sigmask)) {
             thread_sigmask(SIG_SETMASK, context_sigmask, 0);
+#ifndef LISP_FEATURE_SB_SAFEPOINT
             check_gc_signals_unblocked_or_lose(0);
 #endif
+#endif
             FSHOW((stderr, "/maybe_gc: calling POST_GC\n"));
             funcall0(StaticSymbolFunction(POST_GC));
 #ifndef LISP_FEATURE_WIN32
@@ -2783,12 +2766,47 @@ scrub_control_stack(void)
 void
 scavenge_control_stack(struct thread *th)
 {
-    lispobj *control_stack =
-        (lispobj *)(th->control_stack_start);
-    unsigned long control_stack_size =
-        access_control_stack_pointer(th) - control_stack;
+    lispobj *object_ptr;
+
+    /* In order to properly support dynamic-extent allocation of
+     * non-CONS objects, the control stack requires special handling.
+     * Rather than calling scavenge() directly, grovel over it fixing
+     * broken hearts, scavenging pointers to oldspace, and pitching a
+     * fit when encountering unboxed data.  This prevents stray object
+     * headers from causing the scavenger to blow past the end of the
+     * stack (an error case checked in scavenge()).  We don't worry
+     * about treating unboxed words as boxed or vice versa, because
+     * the compiler isn't allowed to store unboxed objects on the
+     * control stack.  -- AB, 2011-Dec-02 */
+
+    for (object_ptr = th->control_stack_start;
+         object_ptr < access_control_stack_pointer(th);
+         object_ptr++) {
 
-    scavenge(control_stack, control_stack_size);
+        lispobj object = *object_ptr;
+#ifdef LISP_FEATURE_GENCGC
+        if (forwarding_pointer_p(object_ptr))
+            lose("unexpected forwarding pointer in scavenge_control_stack: %p, start=%p, end=%p\n",
+                 object_ptr, th->control_stack_start, access_control_stack_pointer(th));
+#endif
+        if (is_lisp_pointer(object) && from_space_p(object)) {
+            /* It currently points to old space. Check for a
+             * forwarding pointer. */
+            lispobj *ptr = native_pointer(object);
+            if (forwarding_pointer_p(ptr)) {
+                /* Yes, there's a forwarding pointer. */
+                *object_ptr = LOW_WORD(forwarding_pointer_value(ptr));
+            } else {
+                /* Scavenge that pointer. */
+                long n_words_scavenged =
+                    (scavtab[widetag_of(object)])(object_ptr, object);
+                gc_assert(n_words_scavenged == 1);
+            }
+        } else if (scavtab[widetag_of(object)] == scav_lose) {
+            lose("unboxed object in scavenge_control_stack: %p->%x, start=%p, end=%p\n",
+                 object_ptr, object, th->control_stack_start, access_control_stack_pointer(th));
+        }
+    }
 }
 
 /* Scavenging Interrupt Contexts */