Move the global safepoint to one page before static space
authorDavid Lichteblau <david@lichteblau.com>
Mon, 29 Oct 2012 12:43:07 +0000 (13:43 +0100)
committerDavid Lichteblau <david@lichteblau.com>
Fri, 2 Nov 2012 12:23:19 +0000 (13:23 +0100)
New attempt at finding an optimal location for the global safepoint
page.  Hopefully this solution will cover all our use cases for
the foreseeable future.

  - Relative to static space for architectures with small immediates.

  - Also addresses the requirements of sb-dynamic-core, which needs
    the safepoint to have an absolute address on x86(-64).

Hence, a new macro !gencgc-space-setup -- tweaks space parameters to
squeeze in the safepoint page, while also simplifying parms.lisp for
some platforms.

13 files changed:
package-data-list.lisp-expr
src/compiler/generic/genesis.lisp
src/compiler/generic/parms.lisp
src/compiler/x86-64/macros.lisp
src/compiler/x86-64/parms.lisp
src/compiler/x86/macros.lisp
src/compiler/x86/parms.lisp
src/runtime/gencgc.c
src/runtime/globals.h
src/runtime/safepoint.c
src/runtime/win32-os.c
src/runtime/x86-64-assem.S
src/runtime/x86-assem.S

index 2c3552a..4a77d18 100644 (file)
@@ -2816,6 +2816,7 @@ structure representations"
                #!+linkage-table "LINKAGE-TABLE-SPACE-START"
                #!+linkage-table "LINKAGE-TABLE-SPACE-END"
                #!+linkage-table "LINKAGE-TABLE-ENTRY-SIZE"
+               #!+sb-safepoint "GC-SAFEPOINT-PAGE-ADDR"
                "TLS-SIZE"
                "TRACE-TABLE-CALL-SITE"
                "TRACE-TABLE-FUN-EPILOGUE" "TRACE-TABLE-FUN-PROLOGUE"
index ed55374..b262fcf 100644 (file)
@@ -2889,6 +2889,10 @@ core and return a descriptor to it."
   ;; pseudo-atomic-trap-number or pseudo-atomic-magic-constant
   ;; [possibly applicable to other platforms])
 
+  #!+sb-safepoint
+  (format t "#define GC_SAFEPOINT_PAGE_ADDR ((void*)0x~XUL) /* ~:*~A */~%"
+            sb!vm:gc-safepoint-page-addr)
+
   (dolist (symbol '(sb!vm::float-traps-byte
                     sb!vm::float-exceptions-byte
                     sb!vm::float-sticky-bits
index b49671f..19af15f 100644 (file)
                       (32 (expt 2 29))
                       (64 (expt 2 30))))))))))
 
+#!+gencgc
+;; Define START/END constants for GENCGC spaces.
+;; Assumptions:
+;;     We only need very small read-only and static spaces, because
+;;     gencgc does not purify any more.  We can count on being able to
+;;     allocate them with roughly the same size, and next to each other.
+;;
+;;     There is one page of unmapped buffer between them for good measure.
+;;
+;;     The linkage table (if enabled) can be treated the same way.
+;;
+;;     Dynamic space traditionally sits elsewhere, so has its own
+;;     parameter.  But if not specified, it is allocated right after
+;;     the other spaces (used on Windows/x86).
+;;
+;;     The safepoint page (if enabled) is to be allocated immediately
+;;     prior to static page.  For x86(-64) this would not matter, because
+;;     they can only reference it using an absolute fixup anyway, but
+;;     for RISC platforms we can (and must) do better.
+;;
+;;     The safepoint page needs to be small enough that the offset from
+;;     static space is immediate, e.g. >= -2^12 for SPARC.  #x1000 works
+;;     for almost all platforms, but is too small to make VirtualProtect
+;;     happy -- hence the need for an extra `alignment' configuration
+;;     option below, which parms.lisp can set to #x10000 on Windows.
+;;
+;; Cosmetic problem:
+;;
+;;     In the interest of readability, &KEY would be much nicer than
+;;     &OPTIONAL.  But is it possible to use keyword arguments to
+;;     DEF!MACRO?
+;;
+(def!macro !gencgc-space-setup
+    (small-spaces-start
+     &optional dynamic-space-start*
+               default-dynamic-space-size
+               ;; Smallest os_validate()able alignment; used as safepoint
+               ;; page size.  Default suitable for POSIX platforms.
+               (alignment            #x1000)
+               ;; traditional distance between spaces -- including the margin:
+               (small-space-spread #x100000)
+               ;; traditional margin between spaces
+               (margin-size          #x1000))
+  (let* ((spaces '(read-only static #!+linkage-table linkage-table))
+         (ptr small-spaces-start)
+         safepoint-address
+         (small-space-forms
+          (loop for (space next-space) on spaces appending
+                (let* ((next-start (+ ptr small-space-spread))
+                       (end next-start))
+                  (when (eq next-space 'static)
+                    ;; margin becomes safepoint page; substract margin again.
+                    (decf end alignment)
+                    (setf safepoint-address end))
+                  (prog1
+                      `((def!constant ,(symbolicate space "-SPACE-START")
+                            ,ptr)
+                        (def!constant ,(symbolicate space "-SPACE-END")
+                            ,(- end margin-size)))
+                    (setf ptr next-start)))))
+         (safepoint-page-forms
+          (list #!+sb-safepoint
+                `(def!constant gc-safepoint-page-addr ,safepoint-address)))
+         (dynamic-space-start* (or dynamic-space-start* ptr))
+         (optional-dynamic-space-end
+          (when default-dynamic-space-size
+            (list (+ dynamic-space-start* default-dynamic-space-size)))))
+    `(progn
+       ,@safepoint-page-forms
+       ,@small-space-forms
+       (def!constant dynamic-space-start ,dynamic-space-start*)
+       (def!constant dynamic-space-end (!configure-dynamic-space-end
+                                        ,@optional-dynamic-space-end)))))
+
 (defparameter *c-callable-static-symbols*
   '(sub-gc
     sb!kernel::post-gc
index 41d91f0..98337e1 100644 (file)
 
 #!+sb-safepoint
 (defun emit-safepoint ()
-  (inst test al-tn (make-ea :byte
-                            :disp (make-fixup "gc_safepoint_page" :foreign))))
+  (inst test al-tn (make-ea :byte :disp sb!vm::gc-safepoint-page-addr)))
 
 #!+sb-thread
 (defmacro pseudo-atomic (&rest forms)
index d294c4f..bd405c7 100644 (file)
 ;;; would be possible, but probably not worth the time and code bloat
 ;;; it would cause. -- JES, 2005-12-11
 
-(progn
-  (def!constant read-only-space-start     #x20000000)
-  (def!constant read-only-space-end       #x200ff000)
+;;; The default dynamic space size is lower on OpenBSD to allow SBCL to
+;;; run under the default 512M data size limit.
 
-  (def!constant static-space-start        #x20100000)
-  (def!constant static-space-end          #x201ff000)
+(!gencgc-space-setup #x20000000 #x1000000000 #!+openbsd #x1bcf0000)
 
-  (def!constant dynamic-space-start       #x1000000000)
-  #!-openbsd
-  (def!constant dynamic-space-end         (!configure-dynamic-space-end))
-  #!+openbsd
-  ;; This is lower on OpenBSD to allow SBCL to run under the default
-  ;; 512M data size limit.
-  (def!constant dynamic-space-end         (!configure-dynamic-space-end #x101bcf0000))
-
-  (def!constant linkage-table-space-start #x20200000)
-  (def!constant linkage-table-space-end   #x202ff000)
-
-  (def!constant linkage-table-entry-size 16))
+(def!constant linkage-table-entry-size 16)
 
 \f
 ;;;; other miscellaneous constants
index f0ed91e..d7b6bc2 100644 (file)
 
 #!+sb-safepoint
 (defun emit-safepoint ()
-  (inst test al-tn (make-ea :byte
-                            :disp (make-fixup "gc_safepoint_page" :foreign))))
+  (inst test eax-tn (make-ea :dword :disp sb!vm::gc-safepoint-page-addr)))
 
 #!+sb-thread
 (defmacro pseudo-atomic (&rest forms)
index 0fd0dca..5502afd 100644 (file)
 ;;;        starting at #x40000000. By only using 512 - 64 MB we can
 ;;;        run under the default 512 MB data size resource limit.
 
-#!+win32
-(progn
-  (def!constant read-only-space-start #x22000000)
-  (def!constant read-only-space-end   #x220ff000)
-
-  (def!constant static-space-start    #x22100000)
-  (def!constant static-space-end      #x221ff000)
-
-  (def!constant dynamic-space-start   #x22300000)
-  (def!constant dynamic-space-end     (!configure-dynamic-space-end))
-
-  (def!constant linkage-table-space-start #x22200000)
-  (def!constant linkage-table-space-end   #x222ff000))
-
-#!+linux
-(progn
-  (def!constant read-only-space-start     #x01000000)
-  (def!constant read-only-space-end       #x010ff000)
-
-  (def!constant static-space-start        #x01100000)
-  (def!constant static-space-end          #x011ff000)
-
-  (def!constant dynamic-space-start       #x09000000)
-  (def!constant dynamic-space-end         (!configure-dynamic-space-end))
-
-  (def!constant linkage-table-space-start #x01200000)
-  (def!constant linkage-table-space-end   #x012ff000))
-
-#!+sunos
-(progn
-  (def!constant read-only-space-start     #x20000000)
-  (def!constant read-only-space-end       #x200ff000)
-
-  (def!constant static-space-start        #x20100000)
-  (def!constant static-space-end          #x201ff000)
-
-  (def!constant dynamic-space-start       #x48000000)
-  (def!constant dynamic-space-end         (!configure-dynamic-space-end))
-
-  (def!constant linkage-table-space-start #x20200000)
-  (def!constant linkage-table-space-end   #x202ff000))
-
-#!+freebsd
-(progn
-  (def!constant read-only-space-start     #x01000000)
-  (def!constant read-only-space-end       #x010ff000)
-
-  (def!constant static-space-start        #x01100000)
-  (def!constant static-space-end          #x011ff000)
-
-  (def!constant dynamic-space-start       #x58000000)
-  (def!constant dynamic-space-end         (!configure-dynamic-space-end))
-
-  (def!constant linkage-table-space-start #x01200000)
-  (def!constant linkage-table-space-end   #x012ff000))
-
-#!+openbsd
-(progn
-  (def!constant read-only-space-start     #x1b000000)
-  (def!constant read-only-space-end       #x1b0ff000)
-
-  (def!constant static-space-start        #x1b100000)
-  (def!constant static-space-end          #x1b1ff000)
-
-  (def!constant dynamic-space-start       #x40000000)
-  (def!constant dynamic-space-end         (!configure-dynamic-space-end))
-
-  (def!constant linkage-table-space-start #x1b200000)
-  (def!constant linkage-table-space-end   #x1b2ff000))
-
-#!+netbsd
-(progn
-  (def!constant read-only-space-start     #x20000000)
-  (def!constant read-only-space-end       #x200ff000)
-
-  (def!constant static-space-start        #x20100000)
-  (def!constant static-space-end          #x201ff000)
-
-  (def!constant dynamic-space-start       #x60000000)
-  (def!constant dynamic-space-end         (!configure-dynamic-space-end))
-
-  ;; In CMUCL: 0xB0000000->0xB1000000
-  (def!constant linkage-table-space-start #x20200000)
-  (def!constant linkage-table-space-end   #x202ff000))
-
-
-#!+darwin
-(progn
-  (def!constant read-only-space-start #x04000000)
-  (def!constant read-only-space-end   #x040ff000)
-
-  (def!constant static-space-start    #x04100000)
-  (def!constant static-space-end      #x041ff000)
-
-  (def!constant dynamic-space-start #x10000000)
-  (def!constant dynamic-space-end   (!configure-dynamic-space-end))
-
-  (def!constant linkage-table-space-start #x04200000)
-  (def!constant linkage-table-space-end   #x042ff000))
+;;; NetBSD configuration used to have this comment regarding the linkage
+;;; table: "In CMUCL: 0xB0000000->0xB1000000"
+
+#!+win32   (!gencgc-space-setup #x22000000 nil nil #x10000)
+#!+linux   (!gencgc-space-setup #x01000000 #x09000000)
+#!+sunos   (!gencgc-space-setup #x20000000 #x48000000)
+#!+freebsd (!gencgc-space-setup #x01000000 #x58000000)
+#!+openbsd (!gencgc-space-setup #x1b000000 #x40000000)
+#!+netbsd  (!gencgc-space-setup #x20000000 #x60000000)
+#!+darwin  (!gencgc-space-setup #x04000000 #x10000000)
 
 ;;; Size of one linkage-table entry in bytes.
 (def!constant linkage-table-entry-size 8)
index a89d59c..838bcac 100644 (file)
@@ -4019,6 +4019,10 @@ gc_init(void)
 {
     page_index_t i;
 
+#if defined(LISP_FEATURE_SB_SAFEPOINT)
+    alloc_gc_page();
+#endif
+
     /* Compute the number of pages needed for the dynamic space.
      * Dynamic space size should be aligned on page size. */
     page_table_pages = dynamic_space_size/GENCGC_CARD_BYTES;
index fc8ad96..b0e812b 100644 (file)
@@ -77,11 +77,6 @@ extern lispobj *current_dynamic_space;
 
 extern void globals_init(void);
 
-#ifdef LISP_FEATURE_SB_SAFEPOINT
-# define GC_SAFEPOINT_PAGE_ADDR ((lispobj) gc_safepoint_page)
-extern char gc_safepoint_page[];
-#endif
-
 #else /* LANGUAGE_ASSEMBLY */
 
 # ifdef LISP_FEATURE_MIPS
index d94a61e..d28d5b9 100644 (file)
  * definition goes here.  Fixme: (Why) don't these work for Windows?
  */
 void
+alloc_gc_page()
+{
+    os_validate(GC_SAFEPOINT_PAGE_ADDR, 4);
+}
+
+void
 map_gc_page()
 {
     odxprint(misc, "map_gc_page");
index b9b1ebe..0c7c893 100644 (file)
@@ -269,6 +269,12 @@ static void set_seh_frame(void *frame)
 
 #if defined(LISP_FEATURE_SB_THREAD)
 
+void alloc_gc_page()
+{
+    AVER(VirtualAlloc(GC_SAFEPOINT_PAGE_ADDR, sizeof(lispobj),
+                      MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE));
+}
+
 /* Permit loads from GC_SAFEPOINT_PAGE_ADDR (NB page state change is
  * "synchronized" with the memory region content/availability --
  * e.g. you won't see other CPU flushing buffered writes after WP --
index f687c82..053167e 100644 (file)
@@ -537,10 +537,4 @@ ascs_finished:
        ret
        SIZE(GNAME(arch_scrub_control_stack))
 \f
-       .globl GNAME(gc_safepoint_page)
-       .data
-        .align  align_page
-GNAME(gc_safepoint_page):
-        .fill 32768,1,0
-\f
         END()
index 0171116..fba970b 100644 (file)
@@ -940,12 +940,6 @@ GNAME(fast_bzero_pointer):
          * to fast_bzero_detect if OS supports SSE.  */
         .long GNAME(fast_bzero_base)
 \f
-       .globl GNAME(gc_safepoint_page)
-       .data
-        .align  align_page
-GNAME(gc_safepoint_page):
-        .fill BACKEND_PAGE_BYTES,1,0
-\f
        .text
        .align  align_16byte,0x90
        .globl GNAME(fast_bzero)