0.9.6.23:
[sbcl.git] / src / runtime / gencgc.c
index fd982f9..d39bf9b 100644 (file)
@@ -2675,11 +2675,9 @@ update_page_write_prot(page_index_t page)
     return (wp_it);
 }
 
-/* Scavenge a generation.
- *
- * This will not resolve all pointers when generation is the new
- * space, as new objects may be added which are not checked here - use
- * scavenge_newspace generation.
+/* Scavenge all generations from FROM to TO, inclusive, except for
+ * new_space which needs special handling, as new objects may be
+ * added which are not checked here - use scavenge_newspace generation.
  *
  * Write-protected pages should not have any pointers to the
  * from_space so do need scavenging; thus write-protected pages are
@@ -2707,7 +2705,7 @@ update_page_write_prot(page_index_t page)
  * pointers as the objects contain a link to the next and are written
  * if a weak pointer is scavenged. Still it's a useful check. */
 static void
-scavenge_generation(generation_index_t generation)
+scavenge_generations(generation_index_t from, generation_index_t to)
 {
     page_index_t i;
     int num_wp = 0;
@@ -2720,9 +2718,12 @@ scavenge_generation(generation_index_t generation)
 #endif
 
     for (i = 0; i < last_free_page; i++) {
+        generation_index_t generation = page_table[i].gen;
         if ((page_table[i].allocated & BOXED_PAGE_FLAG)
             && (page_table[i].bytes_used != 0)
-            && (page_table[i].gen == generation)) {
+            && (generation != new_space)
+            && (generation >= from)
+            && (generation <= to)) {
             page_index_t last_page,j;
             int write_protected=1;
 
@@ -3502,26 +3503,39 @@ verify_dynamic_space(void)
 static void
 write_protect_generation_pages(generation_index_t generation)
 {
-    page_index_t i;
+    page_index_t start;
 
     gc_assert(generation < SCRATCH_GENERATION);
 
-    for (i = 0; i < last_free_page; i++)
-        if ((page_table[i].allocated == BOXED_PAGE_FLAG)
-            && (page_table[i].bytes_used != 0)
-            && !page_table[i].dont_move
-            && (page_table[i].gen == generation))  {
+    for (start = 0; start < last_free_page; start++) {
+        if ((page_table[start].allocated == BOXED_PAGE_FLAG)
+            && (page_table[start].bytes_used != 0)
+            && !page_table[start].dont_move
+            && (page_table[start].gen == generation))  {
             void *page_start;
+            page_index_t last;
 
-            page_start = (void *)page_address(i);
+            /* Note the page as protected in the page tables. */
+            page_table[start].write_protected = 1;
+
+            for (last = start + 1; last < last_free_page; last++) {
+                if ((page_table[last].allocated != BOXED_PAGE_FLAG)
+                    || (page_table[last].bytes_used == 0)
+                    || page_table[last].dont_move
+                    || (page_table[last].gen != generation))
+                  break;
+                page_table[last].write_protected = 1;
+            }
+
+            page_start = (void *)page_address(start);
 
             os_protect(page_start,
-                       PAGE_BYTES,
+                       PAGE_BYTES * (last - start),
                        OS_VM_PROT_READ | OS_VM_PROT_EXECUTE);
 
-            /* Note the page as protected in the page tables. */
-            page_table[i].write_protected = 1;
+            start = last;
         }
+    }
 
     if (gencgc_verbose > 1) {
         FSHOW((stderr,
@@ -3704,11 +3718,7 @@ garbage_collect_generation(generation_index_t generation, int raise)
     /* All generations but the generation being GCed need to be
      * scavenged. The new_space generation needs special handling as
      * objects may be moved in - it is handled separately below. */
-    for (i = 0; i <= PSEUDO_STATIC_GENERATION; i++) {
-        if ((i != generation) && (i != new_space)) {
-            scavenge_generation(i);
-        }
-    }
+    scavenge_generations(generation+1, PSEUDO_STATIC_GENERATION);
 
     /* Finally scavenge the new_space generation. Keep going until no
      * more objects are moved into the new generation */