[cmucl-commit] [git] CMU Common Lisp branch master updated. snapshot-2013-04-6-g940ba82

Raymond Toy rtoy at common-lisp.net
Fri Apr 26 04:05:15 UTC 2013


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMU Common Lisp".

The branch, master has been updated
       via  940ba8218564d4bba25a722774162d5030d6ae94 (commit)
       via  a26d9ff9411543e45c6e30d4926e52b26638eb57 (commit)
       via  b130131c4b764e8efcc98da85e74a57ee4349613 (commit)
       via  203981112731a7f91fce94a21b265064b580888c (commit)
       via  5795db940f9511cd885aea20ae8ee54bf9f8bbc5 (commit)
       via  647aad8230c2e32a2202e0fef1fce3401cb7b905 (commit)
      from  b722521aea8ccd801d12afe519871ab34b8d789f (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 940ba8218564d4bba25a722774162d5030d6ae94
Author: Raymond Toy <toy.raymond at gmail.com>
Date:   Thu Apr 25 21:04:16 2013 -0700

    Turn on zero checking if gencgc_unmap_zero is lazy.
    
    This should only be temporary so we can get some testing with lazy
    mode.

diff --git a/src/lisp/gencgc.c b/src/lisp/gencgc.c
index e02e52a..2f7ecf1 100644
--- a/src/lisp/gencgc.c
+++ b/src/lisp/gencgc.c
@@ -352,6 +352,15 @@ boolean gencgc_zero_check_during_free_heap = FALSE;
 #endif
 
 /*
+ * For now, enable the gencgc_zero_check if gencgc_unmap_zero is lazy.
+ * XXX: Remove this additional condition when we feel that
+ * gencgc_unmap_zero is good enough.
+ */
+
+#define DO_GENCGC_ZERO_CHECK	(gencgc_zero_check || (gencgc_unmap_zero == MODE_LAZY))
+#define DO_GENCGC_ZERO_CHECK_DURING_FREE_HEAP	(gencgc_zero_check_during_free_heap || (gencgc_unmap_zero == MODE_LAZY))
+
+/*
  * The minimum size for a large object.
  */
 unsigned large_object_size = 4 * GC_PAGE_SIZE;
@@ -959,7 +968,11 @@ handle_madvise_first_page(int first_page)
                 first_page, flags, page_table[first_page].bytes_used);
     }
     
+#if 0
     if ((flags & PAGE_MADVISE_MASK) && !PAGE_ALLOCATED(first_page)) {
+#else
+    if (!PAGE_ALLOCATED(first_page)) {
+#endif
         int *page_start = (int *) page_address(first_page);
         
         if (gencgc_debug_madvise) {
@@ -967,7 +980,10 @@ handle_madvise_first_page(int first_page)
         }
         if (*page_start != 0) {
             memset(page_start, 0, GC_PAGE_SIZE);
+#if 0
             page_table[first_page].flags &= ~PAGE_MADVISE_MASK;
+#else
+#endif
         }
     }
     if (gencgc_debug_madvise) {
@@ -981,7 +997,11 @@ handle_madvise_other_pages(int first_page, int last_page)
     int i;
     
     for (i = first_page + 1; i <= last_page; ++i) {
+#if 0
         if (page_table[i].flags & PAGE_MADVISE_MASK) {
+#else
+            if (!PAGE_ALLOCATED(i)) {
+#endif
             int *page_start = (int *) page_address(i);
 
             if (gencgc_debug_madvise) {
@@ -990,7 +1010,9 @@ handle_madvise_other_pages(int first_page, int last_page)
             }
             if (*page_start != 0) {
                 memset(page_start, 0, GC_PAGE_SIZE);
+#if 0
                 page_table[i].flags &= ~PAGE_MADVISE_MASK;
+#endif
             }
         }
     }
@@ -1162,7 +1184,7 @@ gc_alloc_new_region(int nbytes, int unboxed, struct alloc_region *alloc_region)
         handle_madvise_other_pages(first_page, last_page);
     }
 
-    if (gencgc_zero_check) {
+    if (DO_GENCGC_ZERO_CHECK) {
 	int *p;
 
 	for (p = (int *) alloc_region->start_addr;
@@ -7000,7 +7022,11 @@ free_oldspace(void)
               }
 
               for (page = first_page; page < last_page; ++page) {
-                  page_table[page].flags |= PAGE_MADVISE_MASK;
+                  if (PAGE_ALLOCATED(page)) {
+                      fprintf(stderr, "Page %d is allocated!\n", page);
+
+                  }
+                  
                   page_start = (int *) page_address(page);
                   *page_start = 0xdead0000;
               }
@@ -7956,7 +7982,7 @@ gc_free_heap(void)
 	    if (addr == NULL || addr != page_start)
 		fprintf(stderr, "gc_zero: page moved, 0x%08lx ==> 0x%08lx!\n",
 			(unsigned long) page_start, (unsigned long) addr);
-	} else if (gencgc_zero_check_during_free_heap && page < 16384) {
+	} else if (DO_GENCGC_ZERO_CHECK_DURING_FREE_HEAP && page < 16384) {
 	    int *page_start;
 	    unsigned i;
 

commit a26d9ff9411543e45c6e30d4926e52b26638eb57
Author: Raymond Toy <toy.raymond at gmail.com>
Date:   Tue Apr 23 21:14:40 2013 -0700

     * Change default to MODE_LAZY
     * Disable gencgc_debug_madvise.

diff --git a/src/lisp/gencgc.c b/src/lisp/gencgc.c
index 5c9fcd8..e02e52a 100644
--- a/src/lisp/gencgc.c
+++ b/src/lisp/gencgc.c
@@ -324,7 +324,11 @@ enum gencgc_unmap_mode {
  * don't unmap.
  */
 
+#if defined(DARWIN) || defined(__linux__) || defined(sparc)
+enum gencgc_unmap_mode gencgc_unmap_zero = MODE_LAZY;
+#else
 enum gencgc_unmap_mode gencgc_unmap_zero = MODE_MEMSET;
+#endif
 
 /*
  * Enable checking that newly allocated regions are zero filled.
@@ -940,7 +944,10 @@ handle_heap_overflow(const char *msg, int size)
 #endif
 }
 
-boolean gencgc_debug_madvise = TRUE;
+/*
+ * Enable debug messages for MODE_MADVISE and MODE_LAZY
+ */
+boolean gencgc_debug_madvise = FALSE;
 
 static inline void
 handle_madvise_first_page(int first_page)

commit b130131c4b764e8efcc98da85e74a57ee4349613
Author: Raymond Toy <toy.raymond at gmail.com>
Date:   Sun Apr 21 14:34:40 2013 -0700

    Clean up implementation of new gencgc_unmap_zero.
    
     * Add MODE_LAZY
     * Rename PAGE_MADVISE flag to PAGE_MADVISE_MASK
     * Remove some #ifdef'ed out code.
     * Change default gencgc_unmap_zero to MODE_MEMSET for all OS/archs.

diff --git a/src/lisp/gencgc.c b/src/lisp/gencgc.c
index fc1f7dd..5c9fcd8 100644
--- a/src/lisp/gencgc.c
+++ b/src/lisp/gencgc.c
@@ -290,23 +290,41 @@ boolean check_code_fixups = FALSE;
 
 /* How have a page zero-filled. */
 enum gencgc_unmap_mode {
-    MODE_MAP,                   /* Remap the page */
-    MODE_MEMSET,                /* Manually zero fill */
-    MODE_MADVISE                /* madvise */
+    /* Unmap and mmap the region to get it zeroed */
+    MODE_MAP,
+
+    /* Memset the region to 0 */
+    MODE_MEMSET,
+
+    /*
+     * Call madvise to allow the kernel to free the memory if needed.
+     * But when the region needs to be used, we will zero it if
+     * necessary
+     */
+    MODE_MADVISE,
+
+    /*
+     * Like madvise, except we don't actually call madvize and lazily
+     * zero the region when needed.
+     */
+    MODE_LAZY,
 };
   
     
 /*
+ * Control how freed regions should be zeroed.  Default to MODE_MEMSET
+ * for all systems since tests indicate that it is much faster than
+ * unmapping and re-mapping it to zero the region.  See enum
+ * gencgc_unmap_made for other ossible options.
+ *
+ * XXX: Choose the appopriate mode for each OS/arch.
+ * 
  * To enable unmapping of a page and re-mmaping it to have it zero filled.
  * Note: this can waste a lot of swap on FreeBSD and Open/NetBSD(?) so
  * don't unmap.
  */
 
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
 enum gencgc_unmap_mode gencgc_unmap_zero = MODE_MEMSET;
-#else
-enum gencgc_unmap_mode  gencgc_unmap_zero = MODE_MAP;
-#endif
 
 /*
  * Enable checking that newly allocated regions are zero filled.
@@ -924,7 +942,7 @@ handle_heap_overflow(const char *msg, int size)
 
 boolean gencgc_debug_madvise = TRUE;
 
-static void
+static inline void
 handle_madvise_first_page(int first_page)
 {
     int flags = page_table[first_page].flags;
@@ -934,19 +952,15 @@ handle_madvise_first_page(int first_page)
                 first_page, flags, page_table[first_page].bytes_used);
     }
     
-    if ((flags & PAGE_MADVISE) && !PAGE_ALLOCATED(first_page)) {
+    if ((flags & PAGE_MADVISE_MASK) && !PAGE_ALLOCATED(first_page)) {
         int *page_start = (int *) page_address(first_page);
+        
+        if (gencgc_debug_madvise) {
+            fprintf(stderr, ": marker = %x", *page_start);
+        }
         if (*page_start != 0) {
-            if (gencgc_debug_madvise) {
-                fprintf(stderr, ": memset %x", *page_start);
-            }
-            
             memset(page_start, 0, GC_PAGE_SIZE);
-            page_table[first_page].flags &= ~PAGE_MADVISE;
-        } else {
-            if (gencgc_debug_madvise) {
-                fprintf(stderr, ":pre cleared");
-            }
+            page_table[first_page].flags &= ~PAGE_MADVISE_MASK;
         }
     }
     if (gencgc_debug_madvise) {
@@ -960,23 +974,16 @@ handle_madvise_other_pages(int first_page, int last_page)
     int i;
     
     for (i = first_page + 1; i <= last_page; ++i) {
-        if ((gencgc_unmap_zero == MODE_MADVISE)
-            && (page_table[i].flags & PAGE_MADVISE)) {
+        if (page_table[i].flags & PAGE_MADVISE_MASK) {
             int *page_start = (int *) page_address(i);
 
+            if (gencgc_debug_madvise) {
+                fprintf(stderr, "MADVISE page %d, FLAGS = %x: marker %x\n",
+                        i, page_table[i].flags, *page_start);
+            }
             if (*page_start != 0) {
-                if (gencgc_debug_madvise) {
-                    fprintf(stderr, "MADVISE page %d, FLAGS = %x: memset %x\n",
-                            i, page_table[i].flags, *page_start);
-                }
-                
                 memset(page_start, 0, GC_PAGE_SIZE);
-                page_table[i].flags &= ~PAGE_MADVISE;
-            } else {
-                if (gencgc_debug_madvise) {
-                    fprintf(stderr, "MADVISE page %d, FLAGS = %x:  pre-cleared\n",
-                            i, page_table[i].flags);
-                }
+                page_table[i].flags &= ~PAGE_MADVISE_MASK;
             }
         }
     }
@@ -1142,7 +1149,8 @@ gc_alloc_new_region(int nbytes, int unboxed, struct alloc_region *alloc_region)
     alloc_region->free_pointer = alloc_region->start_addr;
     alloc_region->end_addr = alloc_region->start_addr + bytes_found;
 
-    if (gencgc_unmap_zero == MODE_MADVISE) {
+    if ((gencgc_unmap_zero == MODE_MADVISE)
+        || (gencgc_unmap_zero == MODE_LAZY)) {
         handle_madvise_first_page(first_page);
         handle_madvise_other_pages(first_page, last_page);
     }
@@ -1607,26 +1615,9 @@ gc_alloc_large(int nbytes, int unboxed, struct alloc_region *alloc_region)
     /* Setup the pages. */
     orig_first_page_bytes_used = page_table[first_page].bytes_used;
 
-    if (gencgc_unmap_zero == MODE_MADVISE) {
-#if 1
+    if ((gencgc_unmap_zero == MODE_MADVISE)
+        || (gencgc_unmap_zero == MODE_LAZY)) {
         handle_madvise_first_page(first_page);
-#else        
-        int flags = page_table[first_page].flags;
-        
-        fprintf(stderr, "first_page = %d, FLAGS = %x, orig = %d",
-                first_page, flags, orig_first_page_bytes_used);
-        if ((flags & PAGE_MADVISE) && !PAGE_ALLOCATED(first_page)) {
-            int *page_start = (int *) page_address(first_page);
-            if (*page_start != 0) {
-                fprintf(stderr, ": memset %x", *page_start);
-                memset(page_start, 0, GC_PAGE_SIZE);
-                page_table[first_page].flags &= ~PAGE_MADVISE;
-            } else {
-                fprintf(stderr, ":pre cleared");
-            }
-        }
-        fprintf(stderr, "\n");
-#endif
     }
     
     
@@ -1677,24 +1668,11 @@ gc_alloc_large(int nbytes, int unboxed, struct alloc_region *alloc_region)
 	gc_assert(!PAGE_ALLOCATED(next_page));
 	gc_assert(page_table[next_page].bytes_used == 0);
 
-#if 0
         if ((gencgc_unmap_zero == MODE_MADVISE)
-            && (page_table[next_page].flags & PAGE_MADVISE)) {
-            int *page_start = (int *) page_address(next_page);
-
-            if (*page_start != 0) {
-                fprintf(stderr, "MADVISE page %d, FLAGS = %x: memset %x\n",
-                        next_page, page_table[next_page].flags, *page_start);
-                memset(page_start, 0, GC_PAGE_SIZE);
-                page_table[next_page].flags &= ~PAGE_MADVISE;
-            } else {
-                fprintf(stderr, "MADVISE page %d, FLAGS = %x:  pre-cleared\n",
-                        next_page, page_table[next_page].flags);
-            }
+            || (gencgc_unmap_zero == MODE_LAZY)) {
+            handle_madvise_other_pages(next_page - 1, next_page);
         }
-#else
-        handle_madvise_other_pages(next_page - 1, next_page);
-#endif        
+
 	PAGE_FLAGS_UPDATE(next_page, mmask, mflags);
 
 	page_table[next_page].first_object_offset =
@@ -6994,14 +6972,28 @@ free_oldspace(void)
 #define GENCGC_MADVISE	MADV_FREE              
 #endif
 
-#if 1 || !defined(__linux__)
-              madvise(page_start, GC_PAGE_SIZE * (last_page - first_page), GENCGC_MADVISE);
-#else
               page_start = (int *) page_address(first_page);
-              memset(page_start, 0, GC_PAGE_SIZE * (last_page - first_page));
-#endif
+
+              madvise(page_start, GC_PAGE_SIZE * (last_page - first_page), GENCGC_MADVISE);
+              for (page = first_page; page < last_page; ++page) {
+                  page_table[page].flags |= PAGE_MADVISE_MASK;
+                  page_start = (int *) page_address(page);
+                  *page_start = 0xdead0000;
+              }
+              
+              break;
+          }
+          case MODE_LAZY:
+          {
+              int page;
+              int *page_start;
+
+              if (gencgc_debug_madvise) {
+                  fprintf(stderr, "ADVISING pages %d-%d\n", first_page, last_page - 1);
+              }
+
               for (page = first_page; page < last_page; ++page) {
-                  page_table[page].flags |= PAGE_MADVISE;
+                  page_table[page].flags |= PAGE_MADVISE_MASK;
                   page_start = (int *) page_address(page);
                   *page_start = 0xdead0000;
               }
diff --git a/src/lisp/gencgc.h b/src/lisp/gencgc.h
index 7de0311..ce1bf07 100644
--- a/src/lisp/gencgc.h
+++ b/src/lisp/gencgc.h
@@ -77,7 +77,7 @@ int gc_write_barrier(void *);
 #define PAGE_LARGE_OBJECT_VAL(page) \
 	(PAGE_LARGE_OBJECT(page) >> PAGE_LARGE_OBJECT_SHIFT)
 
-#define PAGE_MADVISE	0x00000400
+#define PAGE_MADVISE_MASK	0x00000400
 
 /*
  * The generation that this page belongs to. This should be valid for

commit 203981112731a7f91fce94a21b265064b580888c
Author: Raymond Toy <toy.raymond at gmail.com>
Date:   Sat Apr 20 22:39:48 2013 -0700

     * Add support for linux and solaris/sparc. Linux isn't working with
       madvise, though.  I get an error about no transport function for
       some object.

diff --git a/src/lisp/gencgc.c b/src/lisp/gencgc.c
index c2aa983..fc1f7dd 100644
--- a/src/lisp/gencgc.c
+++ b/src/lisp/gencgc.c
@@ -6987,8 +6987,15 @@ free_oldspace(void)
               if (gencgc_debug_madvise) {
                   fprintf(stderr, "ADVISING pages %d-%d\n", first_page, last_page - 1);
               }
-#if 1
-              madvise(page_start, GC_PAGE_SIZE * (last_page - first_page), MADV_ZERO_WIRED_PAGES);
+
+#if defined(__linux__)
+#define GENCGC_MADVISE	MADV_DONTNEED
+#else
+#define GENCGC_MADVISE	MADV_FREE              
+#endif
+
+#if 1 || !defined(__linux__)
+              madvise(page_start, GC_PAGE_SIZE * (last_page - first_page), GENCGC_MADVISE);
 #else
               page_start = (int *) page_address(first_page);
               memset(page_start, 0, GC_PAGE_SIZE * (last_page - first_page));

commit 5795db940f9511cd885aea20ae8ee54bf9f8bbc5
Author: Raymond Toy <toy.raymond at gmail.com>
Date:   Sat Apr 20 12:07:33 2013 -0700

     * Add variable to control debug prints for madvise
     * Actually enable call to madvise instead of doing memset.

diff --git a/src/lisp/gencgc.c b/src/lisp/gencgc.c
index 0bcce5d..c2aa983 100644
--- a/src/lisp/gencgc.c
+++ b/src/lisp/gencgc.c
@@ -922,24 +922,36 @@ handle_heap_overflow(const char *msg, int size)
 #endif
 }
 
+boolean gencgc_debug_madvise = TRUE;
+
 static void
 handle_madvise_first_page(int first_page)
 {
     int flags = page_table[first_page].flags;
         
-    fprintf(stderr, "first_page = %d, FLAGS = %x, orig = %d",
-            first_page, flags, page_table[first_page].bytes_used);
+    if (gencgc_debug_madvise) {
+        fprintf(stderr, "first_page = %d, FLAGS = %x, orig = %d",
+                first_page, flags, page_table[first_page].bytes_used);
+    }
+    
     if ((flags & PAGE_MADVISE) && !PAGE_ALLOCATED(first_page)) {
         int *page_start = (int *) page_address(first_page);
         if (*page_start != 0) {
-            fprintf(stderr, ": memset %x", *page_start);
+            if (gencgc_debug_madvise) {
+                fprintf(stderr, ": memset %x", *page_start);
+            }
+            
             memset(page_start, 0, GC_PAGE_SIZE);
             page_table[first_page].flags &= ~PAGE_MADVISE;
         } else {
-            fprintf(stderr, ":pre cleared");
+            if (gencgc_debug_madvise) {
+                fprintf(stderr, ":pre cleared");
+            }
         }
     }
-    fprintf(stderr, "\n");
+    if (gencgc_debug_madvise) {
+        fprintf(stderr, "\n");
+    }
 }
 
 static void
@@ -953,13 +965,18 @@ handle_madvise_other_pages(int first_page, int last_page)
             int *page_start = (int *) page_address(i);
 
             if (*page_start != 0) {
-                fprintf(stderr, "MADVISE page %d, FLAGS = %x: memset %x\n",
-                        i, page_table[i].flags, *page_start);
+                if (gencgc_debug_madvise) {
+                    fprintf(stderr, "MADVISE page %d, FLAGS = %x: memset %x\n",
+                            i, page_table[i].flags, *page_start);
+                }
+                
                 memset(page_start, 0, GC_PAGE_SIZE);
                 page_table[i].flags &= ~PAGE_MADVISE;
             } else {
-                fprintf(stderr, "MADVISE page %d, FLAGS = %x:  pre-cleared\n",
-                        i, page_table[i].flags);
+                if (gencgc_debug_madvise) {
+                    fprintf(stderr, "MADVISE page %d, FLAGS = %x:  pre-cleared\n",
+                            i, page_table[i].flags);
+                }
             }
         }
     }
@@ -6967,8 +6984,10 @@ free_oldspace(void)
               int page;
               int *page_start;
 
-              fprintf(stderr, "ADVISING pages %d-%d\n", first_page, last_page - 1);
-#if 0
+              if (gencgc_debug_madvise) {
+                  fprintf(stderr, "ADVISING pages %d-%d\n", first_page, last_page - 1);
+              }
+#if 1
               madvise(page_start, GC_PAGE_SIZE * (last_page - first_page), MADV_ZERO_WIRED_PAGES);
 #else
               page_start = (int *) page_address(first_page);

commit 647aad8230c2e32a2202e0fef1fce3401cb7b905
Author: Raymond Toy <toy.raymond at gmail.com>
Date:   Sat Apr 20 11:03:34 2013 -0700

    First cut at using madvise instead of memset or mmap/munmap to zero
    out freed pages.

diff --git a/src/lisp/gencgc.c b/src/lisp/gencgc.c
index c2129e2..0bcce5d 100644
--- a/src/lisp/gencgc.c
+++ b/src/lisp/gencgc.c
@@ -287,15 +287,25 @@ boolean verify_dynamic_code_check = FALSE;
  */
 boolean check_code_fixups = FALSE;
 
+
+/* How have a page zero-filled. */
+enum gencgc_unmap_mode {
+    MODE_MAP,                   /* Remap the page */
+    MODE_MEMSET,                /* Manually zero fill */
+    MODE_MADVISE                /* madvise */
+};
+  
+    
 /*
  * To enable unmapping of a page and re-mmaping it to have it zero filled.
  * Note: this can waste a lot of swap on FreeBSD and Open/NetBSD(?) so
  * don't unmap.
  */
+
 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
-boolean gencgc_unmap_zero = FALSE;
+enum gencgc_unmap_mode gencgc_unmap_zero = MODE_MEMSET;
 #else
-boolean gencgc_unmap_zero = TRUE;
+enum gencgc_unmap_mode  gencgc_unmap_zero = MODE_MAP;
 #endif
 
 /*
@@ -912,6 +922,49 @@ handle_heap_overflow(const char *msg, int size)
 #endif
 }
 
+static void
+handle_madvise_first_page(int first_page)
+{
+    int flags = page_table[first_page].flags;
+        
+    fprintf(stderr, "first_page = %d, FLAGS = %x, orig = %d",
+            first_page, flags, page_table[first_page].bytes_used);
+    if ((flags & PAGE_MADVISE) && !PAGE_ALLOCATED(first_page)) {
+        int *page_start = (int *) page_address(first_page);
+        if (*page_start != 0) {
+            fprintf(stderr, ": memset %x", *page_start);
+            memset(page_start, 0, GC_PAGE_SIZE);
+            page_table[first_page].flags &= ~PAGE_MADVISE;
+        } else {
+            fprintf(stderr, ":pre cleared");
+        }
+    }
+    fprintf(stderr, "\n");
+}
+
+static void
+handle_madvise_other_pages(int first_page, int last_page)
+{
+    int i;
+    
+    for (i = first_page + 1; i <= last_page; ++i) {
+        if ((gencgc_unmap_zero == MODE_MADVISE)
+            && (page_table[i].flags & PAGE_MADVISE)) {
+            int *page_start = (int *) page_address(i);
+
+            if (*page_start != 0) {
+                fprintf(stderr, "MADVISE page %d, FLAGS = %x: memset %x\n",
+                        i, page_table[i].flags, *page_start);
+                memset(page_start, 0, GC_PAGE_SIZE);
+                page_table[i].flags &= ~PAGE_MADVISE;
+            } else {
+                fprintf(stderr, "MADVISE page %d, FLAGS = %x:  pre-cleared\n",
+                        i, page_table[i].flags);
+            }
+        }
+    }
+}
+
 /*
  * Find a new region with room for at least the given number of bytes.
  *
@@ -1072,6 +1125,11 @@ gc_alloc_new_region(int nbytes, int unboxed, struct alloc_region *alloc_region)
     alloc_region->free_pointer = alloc_region->start_addr;
     alloc_region->end_addr = alloc_region->start_addr + bytes_found;
 
+    if (gencgc_unmap_zero == MODE_MADVISE) {
+        handle_madvise_first_page(first_page);
+        handle_madvise_other_pages(first_page, last_page);
+    }
+
     if (gencgc_zero_check) {
 	int *p;
 
@@ -1446,10 +1504,12 @@ gc_alloc_large(int nbytes, int unboxed, struct alloc_region *alloc_region)
     do {
 	first_page = restart_page;
 
-	if (large)
+	if (large) {
 	    while (first_page < dynamic_space_pages
-		   && PAGE_ALLOCATED(first_page)) first_page++;
-	else
+		   && PAGE_ALLOCATED(first_page)) {
+                first_page++;
+            }
+        } else {
 	    while (first_page < dynamic_space_pages) {
 		int flags = page_table[first_page].flags;
 
@@ -1459,6 +1519,7 @@ gc_alloc_large(int nbytes, int unboxed, struct alloc_region *alloc_region)
 		    break;
 		first_page++;
 	    }
+        }
 
 	/* Check for a failure */
 	if (first_page >= dynamic_space_pages - reserved_heap_pages) {
@@ -1529,6 +1590,29 @@ gc_alloc_large(int nbytes, int unboxed, struct alloc_region *alloc_region)
     /* Setup the pages. */
     orig_first_page_bytes_used = page_table[first_page].bytes_used;
 
+    if (gencgc_unmap_zero == MODE_MADVISE) {
+#if 1
+        handle_madvise_first_page(first_page);
+#else        
+        int flags = page_table[first_page].flags;
+        
+        fprintf(stderr, "first_page = %d, FLAGS = %x, orig = %d",
+                first_page, flags, orig_first_page_bytes_used);
+        if ((flags & PAGE_MADVISE) && !PAGE_ALLOCATED(first_page)) {
+            int *page_start = (int *) page_address(first_page);
+            if (*page_start != 0) {
+                fprintf(stderr, ": memset %x", *page_start);
+                memset(page_start, 0, GC_PAGE_SIZE);
+                page_table[first_page].flags &= ~PAGE_MADVISE;
+            } else {
+                fprintf(stderr, ":pre cleared");
+            }
+        }
+        fprintf(stderr, "\n");
+#endif
+    }
+    
+    
     /*
      * If the first page was free then setup the gen, and
      * first_object_offset.
@@ -1575,6 +1659,25 @@ gc_alloc_large(int nbytes, int unboxed, struct alloc_region *alloc_region)
 
 	gc_assert(!PAGE_ALLOCATED(next_page));
 	gc_assert(page_table[next_page].bytes_used == 0);
+
+#if 0
+        if ((gencgc_unmap_zero == MODE_MADVISE)
+            && (page_table[next_page].flags & PAGE_MADVISE)) {
+            int *page_start = (int *) page_address(next_page);
+
+            if (*page_start != 0) {
+                fprintf(stderr, "MADVISE page %d, FLAGS = %x: memset %x\n",
+                        next_page, page_table[next_page].flags, *page_start);
+                memset(page_start, 0, GC_PAGE_SIZE);
+                page_table[next_page].flags &= ~PAGE_MADVISE;
+            } else {
+                fprintf(stderr, "MADVISE page %d, FLAGS = %x:  pre-cleared\n",
+                        next_page, page_table[next_page].flags);
+            }
+        }
+#else
+        handle_madvise_other_pages(next_page - 1, next_page);
+#endif        
 	PAGE_FLAGS_UPDATE(next_page, mmask, mflags);
 
 	page_table[next_page].first_object_offset =
@@ -1712,7 +1815,7 @@ gc_alloc_region(int nbytes, struct alloc_region *region, int unboxed, struct all
     void *new_obj;
     
 #if 0
-    fprintf(stderr, "gc_alloc %d\n", nbytes);
+    fprintf(stderr, "gc_alloc %d unboxed = %d\n", nbytes, unboxed);
 #endif
 
     /* Check if there is room in the current alloc region. */
@@ -6834,25 +6937,54 @@ free_oldspace(void)
 	       && PAGE_GENERATION(last_page) == from_space);
 
 	/* Zero pages from first_page to (last_page - 1) */
-	if (gencgc_unmap_zero) {
-	    char *page_start, *addr;
-
-	    page_start = page_address(first_page);
-
-	    os_invalidate((os_vm_address_t) page_start,
-			  GC_PAGE_SIZE * (last_page - first_page));
-	    addr =
-		(char *) os_validate((os_vm_address_t) page_start,
-				     GC_PAGE_SIZE * (last_page - first_page));
-	    if (addr == NULL || addr != page_start)
-		fprintf(stderr, "gc_zero: page moved, 0x%08lx ==> 0x%08lx!\n",
-			(unsigned long) page_start, (unsigned long) addr);
-	} else {
-	    int *page_start;
-
-	    page_start = (int *) page_address(first_page);
-	    memset(page_start, 0, GC_PAGE_SIZE * (last_page - first_page));
-	}
+        switch (gencgc_unmap_zero) {
+          case MODE_MAP:
+          {
+              char *page_start, *addr;
+
+              page_start = page_address(first_page);
+
+              os_invalidate((os_vm_address_t) page_start,
+                            GC_PAGE_SIZE * (last_page - first_page));
+              addr =
+                  (char *) os_validate((os_vm_address_t) page_start,
+                                       GC_PAGE_SIZE * (last_page - first_page));
+              if (addr == NULL || addr != page_start)
+                  fprintf(stderr, "gc_zero: page moved, 0x%08lx ==> 0x%08lx!\n",
+                          (unsigned long) page_start, (unsigned long) addr);
+              break;
+          }
+          case MODE_MEMSET:
+          {
+              int *page_start;
+
+              page_start = (int *) page_address(first_page);
+              memset(page_start, 0, GC_PAGE_SIZE * (last_page - first_page));
+              break;
+          }
+          case MODE_MADVISE:
+          {
+              int page;
+              int *page_start;
+
+              fprintf(stderr, "ADVISING pages %d-%d\n", first_page, last_page - 1);
+#if 0
+              madvise(page_start, GC_PAGE_SIZE * (last_page - first_page), MADV_ZERO_WIRED_PAGES);
+#else
+              page_start = (int *) page_address(first_page);
+              memset(page_start, 0, GC_PAGE_SIZE * (last_page - first_page));
+#endif
+              for (page = first_page; page < last_page; ++page) {
+                  page_table[page].flags |= PAGE_MADVISE;
+                  page_start = (int *) page_address(page);
+                  *page_start = 0xdead0000;
+              }
+              
+              break;
+          }
+          default:
+              gc_abort();
+        }
 
 	first_page = last_page;
     }
diff --git a/src/lisp/gencgc.h b/src/lisp/gencgc.h
index f5273b5..7de0311 100644
--- a/src/lisp/gencgc.h
+++ b/src/lisp/gencgc.h
@@ -77,6 +77,8 @@ int gc_write_barrier(void *);
 #define PAGE_LARGE_OBJECT_VAL(page) \
 	(PAGE_LARGE_OBJECT(page) >> PAGE_LARGE_OBJECT_SHIFT)
 
+#define PAGE_MADVISE	0x00000400
+
 /*
  * The generation that this page belongs to. This should be valid for
  * all pages that may have objects allocated, even current allocation

-----------------------------------------------------------------------

Summary of changes:
 src/lisp/gencgc.c |  239 ++++++++++++++++++++++++++++++++++++++++++++++-------
 src/lisp/gencgc.h |    2 +
 2 files changed, 213 insertions(+), 28 deletions(-)


hooks/post-receive
-- 
CMU Common Lisp


More information about the cmucl-commit mailing list