cleanup: #define and use OS_VM_SIZE_FMT in write_generation_stats
[sbcl.git] / src / runtime / gencgc.c
index 1dbef40..652733f 100644 (file)
 #include "genesis/instance.h"
 #include "genesis/layout.h"
 #include "gencgc.h"
-#if defined(LUTEX_WIDETAG)
-#include "pthread-lutex.h"
-#endif
 #if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64)
 #include "genesis/cons.h"
 #endif
 
 /* forward declarations */
-page_index_t  gc_find_freeish_pages(long *restart_page_ptr, long nbytes,
+page_index_t  gc_find_freeish_pages(page_index_t *restart_page_ptr, long nbytes,
                                     int page_type_flag);
 
 \f
@@ -152,8 +149,8 @@ boolean gencgc_partial_pickup = 0;
  */
 
 /* the total bytes allocated. These are seen by Lisp DYNAMIC-USAGE. */
-unsigned long bytes_allocated = 0;
-unsigned long auto_gc_trigger = 0;
+os_vm_size_t bytes_allocated = 0;
+os_vm_size_t auto_gc_trigger = 0;
 
 /* the source and destination generations. These are set before a GC starts
  * scavenging. */
@@ -248,11 +245,11 @@ find_page_index(void *addr)
     return (-1);
 }
 
-static size_t
-npage_bytes(long npages)
+static os_vm_size_t
+npage_bytes(page_index_t npages)
 {
     gc_assert(npages>=0);
-    return ((unsigned long)npages)*GENCGC_CARD_BYTES;
+    return ((os_vm_size_t)npages)*GENCGC_CARD_BYTES;
 }
 
 /* Check that X is a higher address than Y and return offset from Y to
@@ -288,13 +285,13 @@ struct generation {
     page_index_t alloc_large_unboxed_start_page;
 
     /* the bytes allocated to this generation */
-    unsigned long bytes_allocated;
+    os_vm_size_t bytes_allocated;
 
     /* the number of bytes at which to trigger a GC */
-    unsigned long gc_trigger;
+    os_vm_size_t gc_trigger;
 
     /* to calculate a new level for gc_trigger */
-    unsigned long bytes_consed_between_gc;
+    os_vm_size_t bytes_consed_between_gc;
 
     /* the number of GCs since the last raise */
     int num_gc;
@@ -308,20 +305,12 @@ struct generation {
      * objects are added from a GC of a younger generation. Dividing by
      * the bytes_allocated will give the average age of the memory in
      * this generation since its last GC. */
-    unsigned long cum_sum_bytes_allocated;
+    os_vm_size_t cum_sum_bytes_allocated;
 
     /* a minimum average memory age before a GC will occur helps
      * prevent a GC when a large number of new live objects have been
      * added, in which case a GC could be a waste of time */
     double minimum_age_before_gc;
-
-    /* A linked list of lutex structures in this generation, used for
-     * implementing lutex finalization. */
-#ifdef LUTEX_WIDETAG
-    struct lutex *lutexes;
-#else
-    void *lutexes;
-#endif
 };
 
 /* an array of generation structures. There needs to be one more
@@ -361,11 +350,11 @@ static pthread_mutex_t free_pages_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t allocation_lock = PTHREAD_MUTEX_INITIALIZER;
 #endif
 
-extern unsigned long gencgc_release_granularity;
-unsigned long gencgc_release_granularity = GENCGC_RELEASE_GRANULARITY;
+extern os_vm_size_t gencgc_release_granularity;
+os_vm_size_t gencgc_release_granularity = GENCGC_RELEASE_GRANULARITY;
 
-extern unsigned long gencgc_alloc_granularity;
-unsigned long gencgc_alloc_granularity = GENCGC_ALLOC_GRANULARITY;
+extern os_vm_size_t gencgc_alloc_granularity;
+os_vm_size_t gencgc_alloc_granularity = GENCGC_ALLOC_GRANULARITY;
 
 \f
 /*
@@ -374,11 +363,10 @@ unsigned long gencgc_alloc_granularity = GENCGC_ALLOC_GRANULARITY;
 
 /* Count the number of pages which are write-protected within the
  * given generation. */
-static long
+static page_index_t
 count_write_protect_generation_pages(generation_index_t generation)
 {
-    page_index_t i;
-    unsigned long count = 0;
+    page_index_t i, count = 0;
 
     for (i = 0; i < last_free_page; i++)
         if (page_allocated_p(i)
@@ -389,11 +377,11 @@ count_write_protect_generation_pages(generation_index_t generation)
 }
 
 /* Count the number of pages within the given generation. */
-static long
+static page_index_t
 count_generation_pages(generation_index_t generation)
 {
     page_index_t i;
-    long count = 0;
+    page_index_t count = 0;
 
     for (i = 0; i < last_free_page; i++)
         if (page_allocated_p(i)
@@ -403,11 +391,11 @@ count_generation_pages(generation_index_t generation)
 }
 
 #if QSHOW
-static long
+static page_index_t
 count_dont_move_pages(void)
 {
     page_index_t i;
-    long count = 0;
+    page_index_t count = 0;
     for (i = 0; i < last_free_page; i++) {
         if (page_allocated_p(i)
             && (page_table[i].dont_move != 0)) {
@@ -420,11 +408,11 @@ count_dont_move_pages(void)
 
 /* Work through the pages and add up the number of bytes used for the
  * given generation. */
-static unsigned long
+static os_vm_size_t
 count_generation_bytes_allocated (generation_index_t gen)
 {
     page_index_t i;
-    unsigned long result = 0;
+    os_vm_size_t result = 0;
     for (i = 0; i < last_free_page; i++) {
         if (page_allocated_p(i)
             && (page_table[i].gen == gen))
@@ -468,11 +456,11 @@ write_generation_stats(FILE *file)
 
     for (i = 0; i < SCRATCH_GENERATION; i++) {
         page_index_t j;
-        long boxed_cnt = 0;
-        long unboxed_cnt = 0;
-        long large_boxed_cnt = 0;
-        long large_unboxed_cnt = 0;
-        long pinned_cnt=0;
+        page_index_t boxed_cnt = 0;
+        page_index_t unboxed_cnt = 0;
+        page_index_t large_boxed_cnt = 0;
+        page_index_t large_unboxed_cnt = 0;
+        page_index_t pinned_cnt=0;
 
         for (j = 0; j < last_free_page; j++)
             if (page_table[j].gen == i) {
@@ -499,27 +487,31 @@ write_generation_stats(FILE *file)
         gc_assert(generations[i].bytes_allocated
                   == count_generation_bytes_allocated(i));
         fprintf(file,
-                "   %1d: %5ld %5ld %5ld %5ld %5ld %5ld %5ld %5ld %5ld %8ld %5ld %8ld %4ld %3d %7.4f\n",
+                "   %1d: %5ld %5ld %5ld %5ld",
                 i,
                 generations[i].alloc_start_page,
                 generations[i].alloc_unboxed_start_page,
                 generations[i].alloc_large_start_page,
-                generations[i].alloc_large_unboxed_start_page,
-                boxed_cnt,
-                unboxed_cnt,
-                large_boxed_cnt,
-                large_unboxed_cnt,
-                pinned_cnt,
+                generations[i].alloc_large_unboxed_start_page);
+        fprintf(file,
+                " %5"PAGE_INDEX_FMT" %5"PAGE_INDEX_FMT" %5"PAGE_INDEX_FMT
+                " %5"PAGE_INDEX_FMT" %5"PAGE_INDEX_FMT,
+                boxed_cnt, unboxed_cnt, large_boxed_cnt,
+                large_unboxed_cnt, pinned_cnt);
+        fprintf(file,
+                " %8"OS_VM_SIZE_FMT
+                " %5"OS_VM_SIZE_FMT
+                " %8"OS_VM_SIZE_FMT
+                " %4"PAGE_INDEX_FMT" %3d %7.4f\n",
                 generations[i].bytes_allocated,
-                (npage_bytes(count_generation_pages(i))
-                 - generations[i].bytes_allocated),
+                (npage_bytes(count_generation_pages(i)) - generations[i].bytes_allocated),
                 generations[i].gc_trigger,
                 count_write_protect_generation_pages(i),
                 generations[i].num_gc,
                 generation_average_age(i));
     }
-    fprintf(file,"   Total bytes allocated    = %lu\n", bytes_allocated);
-    fprintf(file,"   Dynamic-space-size bytes = %lu\n", (unsigned long)dynamic_space_size);
+    fprintf(file,"   Total bytes allocated    = %"OS_VM_SIZE_FMT"\n", bytes_allocated);
+    fprintf(file,"   Dynamic-space-size bytes = %"OS_VM_SIZE_FMT"\n", dynamic_space_size);
 
     fpu_restore(fpu_state);
 }
@@ -598,9 +590,9 @@ void fast_bzero(void*, size_t); /* in <arch>-assem.S */
  * OS. Generally done after a large GC.
  */
 void zero_pages_with_mmap(page_index_t start, page_index_t end) {
-    int i;
+    page_index_t i;
     void *addr = page_address(start), *new_addr;
-    size_t length = npage_bytes(1+end-start);
+    os_vm_size_t length = npage_bytes(1+end-start);
 
     if (start > end)
       return;
@@ -1276,27 +1268,29 @@ gc_heap_exhausted_error_or_lose (long available, long requested)
 }
 
 page_index_t
-gc_find_freeish_pages(page_index_t *restart_page_ptr, long nbytes,
+gc_find_freeish_pages(page_index_t *restart_page_ptr, long bytes,
                       int page_type_flag)
 {
-    page_index_t first_page, last_page;
-    page_index_t restart_page = *restart_page_ptr;
-    long nbytes_goal = nbytes;
-    long bytes_found = 0;
-    long most_bytes_found = 0;
-    page_index_t most_bytes_found_from, most_bytes_found_to;
-    int small_object = nbytes < GENCGC_CARD_BYTES;
+    page_index_t most_bytes_found_from = 0, most_bytes_found_to = 0;
+    page_index_t first_page, last_page, restart_page = *restart_page_ptr;
+    os_vm_size_t nbytes = bytes;
+    os_vm_size_t nbytes_goal = nbytes;
+    os_vm_size_t bytes_found = 0;
+    os_vm_size_t most_bytes_found = 0;
+    boolean small_object = nbytes < GENCGC_CARD_BYTES;
     /* FIXME: assert(free_pages_lock is held); */
 
     if (nbytes_goal < gencgc_alloc_granularity)
-            nbytes_goal = gencgc_alloc_granularity;
+        nbytes_goal = gencgc_alloc_granularity;
 
     /* Toggled by gc_and_save for heap compaction, normally -1. */
     if (gencgc_alloc_start_page != -1) {
         restart_page = gencgc_alloc_start_page;
     }
 
-    gc_assert(nbytes>=0);
+    /* FIXME: This is on bytes instead of nbytes pending cleanup of
+     * long from the interface. */
+    gc_assert(bytes>=0);
     /* Search for a page with at least nbytes of space. We prefer
      * not to split small objects on multiple pages, to reduce the
      * number of contiguous allocation regions spaning multiple
@@ -1360,6 +1354,7 @@ gc_find_freeish_pages(page_index_t *restart_page_ptr, long nbytes,
         gc_heap_exhausted_error_or_lose(most_bytes_found, nbytes);
     }
 
+    gc_assert(most_bytes_found_to);
     *restart_page_ptr = most_bytes_found_from;
     return most_bytes_found_to-1;
 }
@@ -2037,181 +2032,6 @@ trans_unboxed_large(lispobj object)
     return copy_large_unboxed_object(object, length);
 }
 #endif
-
-\f
-/*
- * Lutexes. Using the normal finalization machinery for finalizing
- * lutexes is tricky, since the finalization depends on working lutexes.
- * So we track the lutexes in the GC and finalize them manually.
- */
-
-#if defined(LUTEX_WIDETAG)
-
-/*
- * Start tracking LUTEX in the GC, by adding it to the linked list of
- * lutexes in the nursery generation. The caller is responsible for
- * locking, and GCs must be inhibited until the registration is
- * complete.
- */
-void
-gencgc_register_lutex (struct lutex *lutex) {
-    int index = find_page_index(lutex);
-    generation_index_t gen;
-    struct lutex *head;
-
-    /* This lutex is in static space, so we don't need to worry about
-     * finalizing it.
-     */
-    if (index == -1)
-        return;
-
-    gen = page_table[index].gen;
-
-    gc_assert(gen >= 0);
-    gc_assert(gen < NUM_GENERATIONS);
-
-    head = generations[gen].lutexes;
-
-    lutex->gen = gen;
-    lutex->next = head;
-    lutex->prev = NULL;
-    if (head)
-        head->prev = lutex;
-    generations[gen].lutexes = lutex;
-}
-
-/*
- * Stop tracking LUTEX in the GC by removing it from the appropriate
- * linked lists. This will only be called during GC, so no locking is
- * needed.
- */
-void
-gencgc_unregister_lutex (struct lutex *lutex) {
-    if (lutex->prev) {
-        lutex->prev->next = lutex->next;
-    } else {
-        generations[lutex->gen].lutexes = lutex->next;
-    }
-
-    if (lutex->next) {
-        lutex->next->prev = lutex->prev;
-    }
-
-    lutex->next = NULL;
-    lutex->prev = NULL;
-    lutex->gen = -1;
-}
-
-/*
- * Mark all lutexes in generation GEN as not live.
- */
-static void
-unmark_lutexes (generation_index_t gen) {
-    struct lutex *lutex = generations[gen].lutexes;
-
-    while (lutex) {
-        lutex->live = 0;
-        lutex = lutex->next;
-    }
-}
-
-/*
- * Finalize all lutexes in generation GEN that have not been marked live.
- */
-static void
-reap_lutexes (generation_index_t gen) {
-    struct lutex *lutex = generations[gen].lutexes;
-
-    while (lutex) {
-        struct lutex *next = lutex->next;
-        if (!lutex->live) {
-            lutex_destroy((tagged_lutex_t) lutex);
-            gencgc_unregister_lutex(lutex);
-        }
-        lutex = next;
-    }
-}
-
-/*
- * Mark LUTEX as live.
- */
-static void
-mark_lutex (lispobj tagged_lutex) {
-    struct lutex *lutex = (struct lutex*) native_pointer(tagged_lutex);
-
-    lutex->live = 1;
-}
-
-/*
- * Move all lutexes in generation FROM to generation TO.
- */
-static void
-move_lutexes (generation_index_t from, generation_index_t to) {
-    struct lutex *tail = generations[from].lutexes;
-
-    /* Nothing to move */
-    if (!tail)
-        return;
-
-    /* Change the generation of the lutexes in FROM. */
-    while (tail->next) {
-        tail->gen = to;
-        tail = tail->next;
-    }
-    tail->gen = to;
-
-    /* Link the last lutex in the FROM list to the start of the TO list */
-    tail->next = generations[to].lutexes;
-
-    /* And vice versa */
-    if (generations[to].lutexes) {
-        generations[to].lutexes->prev = tail;
-    }
-
-    /* And update the generations structures to match this */
-    generations[to].lutexes = generations[from].lutexes;
-    generations[from].lutexes = NULL;
-}
-
-static long
-scav_lutex(lispobj *where, lispobj object)
-{
-    mark_lutex((lispobj) where);
-
-    return CEILING(sizeof(struct lutex)/sizeof(lispobj), 2);
-}
-
-static lispobj
-trans_lutex(lispobj object)
-{
-    struct lutex *lutex = (struct lutex *) native_pointer(object);
-    lispobj copied;
-    size_t words = CEILING(sizeof(struct lutex)/sizeof(lispobj), 2);
-    gc_assert(is_lisp_pointer(object));
-    copied = copy_object(object, words);
-
-    /* Update the links, since the lutex moved in memory. */
-    if (lutex->next) {
-        lutex->next->prev = (struct lutex *) native_pointer(copied);
-    }
-
-    if (lutex->prev) {
-        lutex->prev->next = (struct lutex *) native_pointer(copied);
-    } else {
-        generations[lutex->gen].lutexes =
-          (struct lutex *) native_pointer(copied);
-    }
-
-    return copied;
-}
-
-static long
-size_lutex(lispobj *where)
-{
-    return CEILING(sizeof(struct lutex)/sizeof(lispobj), 2);
-}
-#endif /* LUTEX_WIDETAG */
-
 \f
 /*
  * weak pointers
@@ -2293,304 +2113,6 @@ search_dynamic_space(void *pointer)
                             (lispobj *)pointer));
 }
 
-/* Helper for valid_lisp_pointer_p and
- * possibly_valid_dynamic_space_pointer.
- *
- * pointer is the pointer to validate, and start_addr is the address
- * of the enclosing object.
- */
-static int
-looks_like_valid_lisp_pointer_p(lispobj *pointer, lispobj *start_addr)
-{
-    if (!is_lisp_pointer((lispobj)pointer)) {
-        return 0;
-    }
-
-    /* Check that the object pointed to is consistent with the pointer
-     * low tag. */
-    switch (lowtag_of((lispobj)pointer)) {
-    case FUN_POINTER_LOWTAG:
-        /* Start_addr should be the enclosing code object, or a closure
-         * header. */
-        switch (widetag_of(*start_addr)) {
-        case CODE_HEADER_WIDETAG:
-          /* Make sure we actually point to a function in the code object,
-           * as opposed to a random point there. */
-          if (SIMPLE_FUN_HEADER_WIDETAG==widetag_of(*(pointer-FUN_POINTER_LOWTAG)))
-            return 1;
-          else
-            return 0;
-        case CLOSURE_HEADER_WIDETAG:
-        case FUNCALLABLE_INSTANCE_HEADER_WIDETAG:
-            if ((unsigned long)pointer !=
-                ((unsigned long)start_addr+FUN_POINTER_LOWTAG)) {
-                if (gencgc_verbose) {
-                    FSHOW((stderr,
-                           "/Wf2: %x %x %x\n",
-                           pointer, start_addr, *start_addr));
-                }
-                return 0;
-            }
-            break;
-        default:
-            if (gencgc_verbose) {
-                FSHOW((stderr,
-                       "/Wf3: %x %x %x\n",
-                       pointer, start_addr, *start_addr));
-            }
-            return 0;
-        }
-        break;
-    case LIST_POINTER_LOWTAG:
-        if ((unsigned long)pointer !=
-            ((unsigned long)start_addr+LIST_POINTER_LOWTAG)) {
-            if (gencgc_verbose) {
-                FSHOW((stderr,
-                       "/Wl1: %x %x %x\n",
-                       pointer, start_addr, *start_addr));
-            }
-            return 0;
-        }
-        /* Is it plausible cons? */
-        if ((is_lisp_pointer(start_addr[0]) ||
-             is_lisp_immediate(start_addr[0])) &&
-            (is_lisp_pointer(start_addr[1]) ||
-             is_lisp_immediate(start_addr[1])))
-            break;
-        else {
-            if (gencgc_verbose) {
-                FSHOW((stderr,
-                       "/Wl2: %x %x %x\n",
-                       pointer, start_addr, *start_addr));
-            }
-            return 0;
-        }
-    case INSTANCE_POINTER_LOWTAG:
-        if ((unsigned long)pointer !=
-            ((unsigned long)start_addr+INSTANCE_POINTER_LOWTAG)) {
-            if (gencgc_verbose) {
-                FSHOW((stderr,
-                       "/Wi1: %x %x %x\n",
-                       pointer, start_addr, *start_addr));
-            }
-            return 0;
-        }
-        if (widetag_of(start_addr[0]) != INSTANCE_HEADER_WIDETAG) {
-            if (gencgc_verbose) {
-                FSHOW((stderr,
-                       "/Wi2: %x %x %x\n",
-                       pointer, start_addr, *start_addr));
-            }
-            return 0;
-        }
-        break;
-    case OTHER_POINTER_LOWTAG:
-
-#if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64)
-        /* The all-architecture test below is good as far as it goes,
-         * but an LRA object is similar to a FUN-POINTER: It is
-         * embedded within a CODE-OBJECT pointed to by start_addr, and
-         * cannot be found by simply walking the heap, therefore we
-         * need to check for it. -- AB, 2010-Jun-04 */
-        if ((widetag_of(start_addr[0]) == CODE_HEADER_WIDETAG)) {
-            lispobj *potential_lra =
-                (lispobj *)(((unsigned long)pointer) - OTHER_POINTER_LOWTAG);
-            if ((widetag_of(potential_lra[0]) == RETURN_PC_HEADER_WIDETAG) &&
-                ((potential_lra - HeaderValue(potential_lra[0])) == start_addr)) {
-                return 1; /* It's as good as we can verify. */
-            }
-        }
-#endif
-
-        if ((unsigned long)pointer !=
-            ((unsigned long)start_addr+OTHER_POINTER_LOWTAG)) {
-            if (gencgc_verbose) {
-                FSHOW((stderr,
-                       "/Wo1: %x %x %x\n",
-                       pointer, start_addr, *start_addr));
-            }
-            return 0;
-        }
-        /* Is it plausible?  Not a cons. XXX should check the headers. */
-        if (is_lisp_pointer(start_addr[0]) || ((start_addr[0] & 3) == 0)) {
-            if (gencgc_verbose) {
-                FSHOW((stderr,
-                       "/Wo2: %x %x %x\n",
-                       pointer, start_addr, *start_addr));
-            }
-            return 0;
-        }
-        switch (widetag_of(start_addr[0])) {
-        case UNBOUND_MARKER_WIDETAG:
-        case NO_TLS_VALUE_MARKER_WIDETAG:
-        case CHARACTER_WIDETAG:
-#if N_WORD_BITS == 64
-        case SINGLE_FLOAT_WIDETAG:
-#endif
-            if (gencgc_verbose) {
-                FSHOW((stderr,
-                       "*Wo3: %x %x %x\n",
-                       pointer, start_addr, *start_addr));
-            }
-            return 0;
-
-            /* only pointed to by function pointers? */
-        case CLOSURE_HEADER_WIDETAG:
-        case FUNCALLABLE_INSTANCE_HEADER_WIDETAG:
-            if (gencgc_verbose) {
-                FSHOW((stderr,
-                       "*Wo4: %x %x %x\n",
-                       pointer, start_addr, *start_addr));
-            }
-            return 0;
-
-        case INSTANCE_HEADER_WIDETAG:
-            if (gencgc_verbose) {
-                FSHOW((stderr,
-                       "*Wo5: %x %x %x\n",
-                       pointer, start_addr, *start_addr));
-            }
-            return 0;
-
-            /* the valid other immediate pointer objects */
-        case SIMPLE_VECTOR_WIDETAG:
-        case RATIO_WIDETAG:
-        case COMPLEX_WIDETAG:
-#ifdef COMPLEX_SINGLE_FLOAT_WIDETAG
-        case COMPLEX_SINGLE_FLOAT_WIDETAG:
-#endif
-#ifdef COMPLEX_DOUBLE_FLOAT_WIDETAG
-        case COMPLEX_DOUBLE_FLOAT_WIDETAG:
-#endif
-#ifdef COMPLEX_LONG_FLOAT_WIDETAG
-        case COMPLEX_LONG_FLOAT_WIDETAG:
-#endif
-        case SIMPLE_ARRAY_WIDETAG:
-        case COMPLEX_BASE_STRING_WIDETAG:
-#ifdef COMPLEX_CHARACTER_STRING_WIDETAG
-        case COMPLEX_CHARACTER_STRING_WIDETAG:
-#endif
-        case COMPLEX_VECTOR_NIL_WIDETAG:
-        case COMPLEX_BIT_VECTOR_WIDETAG:
-        case COMPLEX_VECTOR_WIDETAG:
-        case COMPLEX_ARRAY_WIDETAG:
-        case VALUE_CELL_HEADER_WIDETAG:
-        case SYMBOL_HEADER_WIDETAG:
-        case FDEFN_WIDETAG:
-        case CODE_HEADER_WIDETAG:
-        case BIGNUM_WIDETAG:
-#if N_WORD_BITS != 64
-        case SINGLE_FLOAT_WIDETAG:
-#endif
-        case DOUBLE_FLOAT_WIDETAG:
-#ifdef LONG_FLOAT_WIDETAG
-        case LONG_FLOAT_WIDETAG:
-#endif
-        case SIMPLE_BASE_STRING_WIDETAG:
-#ifdef SIMPLE_CHARACTER_STRING_WIDETAG
-        case SIMPLE_CHARACTER_STRING_WIDETAG:
-#endif
-        case SIMPLE_BIT_VECTOR_WIDETAG:
-        case SIMPLE_ARRAY_NIL_WIDETAG:
-        case SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG:
-        case SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG:
-        case SIMPLE_ARRAY_UNSIGNED_BYTE_7_WIDETAG:
-        case SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG:
-        case SIMPLE_ARRAY_UNSIGNED_BYTE_15_WIDETAG:
-        case SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG:
-
-        case SIMPLE_ARRAY_UNSIGNED_FIXNUM_WIDETAG:
-
-        case SIMPLE_ARRAY_UNSIGNED_BYTE_31_WIDETAG:
-        case SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG:
-#ifdef  SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG
-        case SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG:
-#endif
-#ifdef  SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG
-        case SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG:
-#endif
-#ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
-        case SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG:
-#endif
-#ifdef SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG
-        case SIMPLE_ARRAY_SIGNED_BYTE_16_WIDETAG:
-#endif
-
-        case SIMPLE_ARRAY_FIXNUM_WIDETAG:
-
-#ifdef SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG
-        case SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG:
-#endif
-#ifdef SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG
-        case SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG:
-#endif
-        case SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG:
-        case SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG:
-#ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
-        case SIMPLE_ARRAY_LONG_FLOAT_WIDETAG:
-#endif
-#ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
-        case SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG:
-#endif
-#ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
-        case SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG:
-#endif
-#ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
-        case SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG:
-#endif
-        case SAP_WIDETAG:
-        case WEAK_POINTER_WIDETAG:
-#ifdef LUTEX_WIDETAG
-        case LUTEX_WIDETAG:
-#endif
-            break;
-
-        default:
-            if (gencgc_verbose) {
-                FSHOW((stderr,
-                       "/Wo6: %x %x %x\n",
-                       pointer, start_addr, *start_addr));
-            }
-            return 0;
-        }
-        break;
-    default:
-        if (gencgc_verbose) {
-            FSHOW((stderr,
-                   "*W?: %x %x %x\n",
-                   pointer, start_addr, *start_addr));
-        }
-        return 0;
-    }
-
-    /* looks good */
-    return 1;
-}
-
-/* Used by the debugger to validate possibly bogus pointers before
- * calling MAKE-LISP-OBJ on them.
- *
- * FIXME: We would like to make this perfect, because if the debugger
- * constructs a reference to a bugs lisp object, and it ends up in a
- * location scavenged by the GC all hell breaks loose.
- *
- * Whereas possibly_valid_dynamic_space_pointer has to be conservative
- * and return true for all valid pointers, this could actually be eager
- * and lie about a few pointers without bad results... but that should
- * be reflected in the name.
- */
-int
-valid_lisp_pointer_p(lispobj *pointer)
-{
-    lispobj *start;
-    if (((start=search_dynamic_space(pointer))!=NULL) ||
-        ((start=search_static_space(pointer))!=NULL) ||
-        ((start=search_read_only_space(pointer))!=NULL))
-        return looks_like_valid_lisp_pointer_p(pointer, start);
-    else
-        return 0;
-}
-
 #if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)
 
 /* Is there any possibility that pointer is a valid Lisp object
@@ -3020,7 +2542,7 @@ static void
 scavenge_generations(generation_index_t from, generation_index_t to)
 {
     page_index_t i;
-    int num_wp = 0;
+    page_index_t num_wp = 0;
 
 #define SC_GEN_CK 0
 #if SC_GEN_CK
@@ -3310,16 +2832,19 @@ scavenge_newspace_generation(generation_index_t generation)
     record_new_objects = 0;
 
 #if SC_NS_GEN_CK
-    /* Check that none of the write_protected pages in this generation
-     * have been written to. */
-    for (i = 0; i < page_table_pages; i++) {
-        if (page_allocated_p(i)
-            && (page_table[i].bytes_used != 0)
-            && (page_table[i].gen == generation)
-            && (page_table[i].write_protected_cleared != 0)
-            && (page_table[i].dont_move == 0)) {
-            lose("write protected page %d written to in scavenge_newspace_generation\ngeneration=%d dont_move=%d\n",
-                 i, generation, page_table[i].dont_move);
+    {
+        page_index_t i;
+        /* Check that none of the write_protected pages in this generation
+         * have been written to. */
+        for (i = 0; i < page_table_pages; i++) {
+            if (page_allocated_p(i)
+                && (page_table[i].bytes_used != 0)
+                && (page_table[i].gen == generation)
+                && (page_table[i].write_protected_cleared != 0)
+                && (page_table[i].dont_move == 0)) {
+                lose("write protected page %d written to in scavenge_newspace_generation\ngeneration=%d dont_move=%d\n",
+                     i, generation, page_table[i].dont_move);
+            }
         }
     }
 #endif
@@ -3707,9 +3232,6 @@ verify_space(lispobj *start, size_t words)
 #endif
                 case SAP_WIDETAG:
                 case WEAK_POINTER_WIDETAG:
-#ifdef LUTEX_WIDETAG
-                case LUTEX_WIDETAG:
-#endif
 #ifdef NO_TLS_VALUE_MARKER_WIDETAG
                 case NO_TLS_VALUE_MARKER_WIDETAG:
 #endif
@@ -3968,10 +3490,6 @@ garbage_collect_generation(generation_index_t generation, int raise)
     /* Initialize the weak pointer list. */
     weak_pointers = NULL;
 
-#ifdef LUTEX_WIDETAG
-    unmark_lutexes(generation);
-#endif
-
     /* When a generation is not being raised it is transported to a
      * temporary generation (NUM_GENERATIONS), and lowered when
      * done. Set up this new generation. There should be no pages
@@ -4177,8 +3695,8 @@ garbage_collect_generation(generation_index_t generation, int raise)
     /* As a check re-scavenge the newspace once; no new objects should
      * be found. */
     {
-        long old_bytes_allocated = bytes_allocated;
-        long bytes_allocated;
+        os_vm_size_t old_bytes_allocated = bytes_allocated;
+        os_vm_size_t bytes_allocated;
 
         /* Start with a full scavenge. */
         scavenge_newspace_generation_one_scan(new_space);
@@ -4241,11 +3759,6 @@ garbage_collect_generation(generation_index_t generation, int raise)
     else
         ++generations[generation].num_gc;
 
-#ifdef LUTEX_WIDETAG
-    reap_lutexes(generation);
-    if (raise)
-        move_lutexes(generation, generation+1);
-#endif
 }
 
 /* Update last_free_page, then SymbolValue(ALLOCATION_POINTER). */
@@ -4485,7 +3998,7 @@ gc_free_heap(void)
     for (page = 0; page < page_table_pages; page++) {
         /* Skip free pages which should already be zero filled. */
         if (page_allocated_p(page)) {
-            void *page_start, *addr;
+            void *page_start;
             for (last_page = page;
                  (last_page < page_table_pages) && page_allocated_p(last_page);
                  last_page++) {
@@ -4533,7 +4046,6 @@ gc_free_heap(void)
         generations[page].gc_trigger = 2000000;
         generations[page].num_gc = 0;
         generations[page].cum_sum_bytes_allocated = 0;
-        generations[page].lutexes = NULL;
     }
 
     if (gencgc_verbose > 1)
@@ -4565,6 +4077,12 @@ gc_init(void)
     page_table_pages = dynamic_space_size/GENCGC_CARD_BYTES;
     gc_assert(dynamic_space_size == npage_bytes(page_table_pages));
 
+    /* Default nursery size to 5% of the total dynamic space size,
+     * min 1Mb. */
+    bytes_consed_between_gcs = dynamic_space_size/(os_vm_size_t)20;
+    if (bytes_consed_between_gcs < (1024*1024))
+        bytes_consed_between_gcs = 1024*1024;
+
     /* The page_table must be allocated using "calloc" to initialize
      * the page structures correctly. There used to be a separate
      * initialization loop (now commented out; see below) but that was
@@ -4576,12 +4094,6 @@ gc_init(void)
     scavtab[WEAK_POINTER_WIDETAG] = scav_weak_pointer;
     transother[SIMPLE_ARRAY_WIDETAG] = trans_boxed_large;
 
-#ifdef LUTEX_WIDETAG
-    scavtab[LUTEX_WIDETAG] = scav_lutex;
-    transother[LUTEX_WIDETAG] = trans_lutex;
-    sizetab[LUTEX_WIDETAG] = size_lutex;
-#endif
-
     heap_base = (void*)DYNAMIC_SPACE_START;
 
     /* The page structures are initialized implicitly when page_table
@@ -4633,10 +4145,9 @@ gc_init(void)
         generations[i].num_gc = 0;
         generations[i].cum_sum_bytes_allocated = 0;
         /* the tune-able parameters */
-        generations[i].bytes_consed_between_gc = 2000000;
+        generations[i].bytes_consed_between_gc = bytes_consed_between_gcs;
         generations[i].number_of_gcs_before_promotion = 1;
         generations[i].minimum_age_before_gc = 0.75;
-        generations[i].lutexes = NULL;
     }
 
     /* Initialize gc_alloc. */
@@ -4685,13 +4196,6 @@ gencgc_pickup_dynamic(void)
         page++;
     } while (page_address(page) < alloc_ptr);
 
-#ifdef LUTEX_WIDETAG
-    /* Lutexes have been registered in generation 0 by coreparse, and
-     * need to be moved to the right one manually.
-     */
-    move_lutexes(0, PSEUDO_STATIC_GENERATION);
-#endif
-
     last_free_page = page;
 
     generations[gen].bytes_allocated = npage_bytes(page);