1.0.47.4: Fix slot-documentation for SB-POSIX:TERMIOS slot CC.
[sbcl.git] / src / runtime / gencgc.c
index 74b818e..288e968 100644 (file)
@@ -2238,8 +2238,12 @@ looks_like_valid_lisp_pointer_p(lispobj *pointer, lispobj *start_addr)
          * header. */
         switch (widetag_of(*start_addr)) {
         case CODE_HEADER_WIDETAG:
-            /* This case is probably caught above. */
-            break;
+          /* 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 !=
@@ -3833,14 +3837,11 @@ write_protect_generation_pages(generation_index_t generation)
 static void
 scavenge_control_stack(struct thread *th)
 {
-    unsigned long control_stack_size;
-
-    /* This is going to be a big problem when we try to port threads
-     * to PPC... CLH */
     lispobj *control_stack =
         (lispobj *)(th->control_stack_start);
+    unsigned long control_stack_size =
+        access_control_stack_pointer(th) - control_stack;
 
-    control_stack_size = current_control_stack_pointer - control_stack;
     scavenge(control_stack, control_stack_size);
 }
 #endif
@@ -4490,6 +4491,10 @@ gc_init(void)
     page_table_pages = dynamic_space_size/PAGE_BYTES;
     gc_assert(dynamic_space_size == npage_bytes(page_table_pages));
 
+    /* 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
+     * unnecessary and did hurt startup time. */
     page_table = calloc(page_table_pages, sizeof(struct page));
     gc_assert(page_table);
 
@@ -4505,14 +4510,38 @@ gc_init(void)
 
     heap_base = (void*)DYNAMIC_SPACE_START;
 
-    /* Initialize each page structure. */
-    for (i = 0; i < page_table_pages; i++) {
-        /* Initialize all pages as free. */
-        page_table[i].allocated = FREE_PAGE_FLAG;
-        page_table[i].bytes_used = 0;
-
-        /* Pages are not write-protected at startup. */
-        page_table[i].write_protected = 0;
+    /* The page structures are initialized implicitly when page_table
+     * is allocated with "calloc" above. Formerly we had the following
+     * explicit initialization here (comments converted to C99 style
+     * for readability as C's block comments don't nest):
+     *
+     * // Initialize each page structure.
+     * for (i = 0; i < page_table_pages; i++) {
+     *     // Initialize all pages as free.
+     *     page_table[i].allocated = FREE_PAGE_FLAG;
+     *     page_table[i].bytes_used = 0;
+     *
+     *     // Pages are not write-protected at startup.
+     *     page_table[i].write_protected = 0;
+     * }
+     *
+     * Without this loop the image starts up much faster when dynamic
+     * space is large -- which it is on 64-bit platforms already by
+     * default -- and when "calloc" for large arrays is implemented
+     * using copy-on-write of a page of zeroes -- which it is at least
+     * on Linux. In this case the pages that page_table_pages is stored
+     * in are mapped and cleared not before the corresponding part of
+     * dynamic space is used. For example, this saves clearing 16 MB of
+     * memory at startup if the page size is 4 KB and the size of
+     * dynamic space is 4 GB.
+     * FREE_PAGE_FLAG must be 0 for this to work correctly which is
+     * asserted below: */
+    {
+      /* Compile time assertion: If triggered, declares an array
+       * of dimension -1 forcing a syntax error. The intent of the
+       * assignment is to avoid an "unused variable" warning. */
+      char assert_free_page_flag_0[(FREE_PAGE_FLAG) ? -1 : 1];
+      assert_free_page_flag_0[0] = assert_free_page_flag_0[0];
     }
 
     bytes_allocated = 0;