X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fgc-common.c;h=96ac8df05e719371dc08bd214cc1a4c4ec5e3a91;hb=0285aa5ff8416027932daa001b84429be2ca559b;hp=6c24c2741c1cfe9b39a3ddc291c18e4c83ae0b3c;hpb=aab1cd8a9dc69450a046d4f176ec5b9fde43c42c;p=sbcl.git diff --git a/src/runtime/gc-common.c b/src/runtime/gc-common.c index 6c24c27..96ac8df 100644 --- a/src/runtime/gc-common.c +++ b/src/runtime/gc-common.c @@ -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 */