cleanup: use OS_VM_SIZE_FMT in collect_garbage
[sbcl.git] / src / runtime / gencgc.c
index 27ad418..a2a409b 100644 (file)
@@ -57,7 +57,7 @@
 #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
@@ -79,11 +79,11 @@ boolean enable_page_protection = 1;
 
 /* the minimum size (in bytes) for a large object*/
 #if (GENCGC_ALLOC_GRANULARITY >= PAGE_BYTES) && (GENCGC_ALLOC_GRANULARITY >= GENCGC_CARD_BYTES)
-long large_object_size = 4 * GENCGC_ALLOC_GRANULARITY;
+os_vm_size_t large_object_size = 4 * GENCGC_ALLOC_GRANULARITY;
 #elif (GENCGC_CARD_BYTES >= PAGE_BYTES) && (GENCGC_CARD_BYTES >= GENCGC_ALLOC_GRANULARITY)
-long large_object_size = 4 * GENCGC_CARD_BYTES;
+os_vm_size_t large_object_size = 4 * GENCGC_CARD_BYTES;
 #else
-long large_object_size = 4 * PAGE_BYTES;
+os_vm_size_t large_object_size = 4 * PAGE_BYTES;
 #endif
 
 \f
@@ -149,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. */
@@ -245,17 +245,17 @@ 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
  * X in bytes. */
-static inline
-size_t void_diff(void *x, void *y)
+static inline os_vm_size_t
+void_diff(void *x, void *y)
 {
     gc_assert(x >= y);
     return (pointer_sized_uint_t)x - (pointer_sized_uint_t)y;
@@ -285,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;
@@ -305,7 +305,7 @@ 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
@@ -350,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
 /*
@@ -363,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)
@@ -378,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)
@@ -392,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)) {
@@ -409,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))
@@ -457,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) {
@@ -488,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);
 }
@@ -587,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;
@@ -786,7 +789,7 @@ gc_alloc_new_region(long nbytes, int page_type_flag, struct alloc_region *alloc_
 {
     page_index_t first_page;
     page_index_t last_page;
-    unsigned long bytes_found;
+    os_vm_size_t bytes_found;
     page_index_t i;
     int ret;
 
@@ -869,15 +872,11 @@ gc_alloc_new_region(long nbytes, int page_type_flag, struct alloc_region *alloc_
 
     /* we can do this after releasing free_pages_lock */
     if (gencgc_zero_check) {
-        long *p;
-        for (p = (long *)alloc_region->start_addr;
-             p < (long *)alloc_region->end_addr; p++) {
+        word_t *p;
+        for (p = (word_t *)alloc_region->start_addr;
+             p < (word_t *)alloc_region->end_addr; p++) {
             if (*p != 0) {
-                /* KLUDGE: It would be nice to use %lx and explicit casts
-                 * (long) in code like this, so that it is less likely to
-                 * break randomly when running on a machine with different
-                 * word sizes. -- WHN 19991129 */
-                lose("The new region at %x is not zero (start=%p, end=%p).\n",
+                lose("The new region is not zero at %p (start=%p, end=%p).\n",
                      p, alloc_region->start_addr, alloc_region->end_addr);
             }
         }
@@ -985,13 +984,13 @@ add_new_area(page_index_t first_page, size_t offset, size_t size)
 void
 gc_alloc_update_page_tables(int page_type_flag, struct alloc_region *alloc_region)
 {
-    int more;
+    boolean more;
     page_index_t first_page;
     page_index_t next_page;
-    unsigned long bytes_used;
-    unsigned long orig_first_page_bytes_used;
-    unsigned long region_size;
-    unsigned long byte_cnt;
+    os_vm_size_t bytes_used;
+    os_vm_size_t region_size;
+    os_vm_size_t byte_cnt;
+    page_bytes_t orig_first_page_bytes_used;
     int ret;
 
 
@@ -1117,13 +1116,11 @@ static inline void *gc_quick_alloc(long nbytes);
 void *
 gc_alloc_large(long nbytes, int page_type_flag, struct alloc_region *alloc_region)
 {
-    page_index_t first_page;
-    page_index_t last_page;
-    int orig_first_page_bytes_used;
-    long byte_cnt;
-    int more;
-    unsigned long bytes_used;
-    page_index_t next_page;
+    boolean more;
+    page_index_t first_page, next_page, last_page;
+    page_bytes_t orig_first_page_bytes_used;
+    os_vm_size_t byte_cnt;
+    os_vm_size_t bytes_used;
     int ret;
 
     ret = thread_mutex_lock(&free_pages_lock);
@@ -1265,27 +1262,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
@@ -1349,6 +1348,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;
 }
@@ -2536,7 +2536,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
@@ -2826,16 +2826,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
@@ -3686,8 +3689,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);
@@ -3953,7 +3956,7 @@ collect_garbage(generation_index_t last_gen)
 
     auto_gc_trigger = bytes_allocated + bytes_consed_between_gcs;
     if(gencgc_verbose)
-        fprintf(stderr,"Next gc when %ld bytes have been consed\n",
+        fprintf(stderr,"Next gc when %"OS_VM_SIZE_FMT" bytes have been consed\n",
                 auto_gc_trigger);
 
     /* If we did a big GC (arbitrarily defined as gen > 1), release memory
@@ -3989,7 +3992,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++) {
@@ -4068,6 +4071,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
@@ -4130,7 +4139,7 @@ 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;
     }