From 3ea89bab9e4600ba80b6bc931481100fca74fa9d Mon Sep 17 00:00:00 2001 From: David Lichteblau Date: Mon, 29 Oct 2012 13:43:07 +0100 Subject: [PATCH] Move the global safepoint to one page before static space 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. --- package-data-list.lisp-expr | 1 + src/compiler/generic/genesis.lisp | 4 ++ src/compiler/generic/parms.lisp | 74 +++++++++++++++++++++++++ src/compiler/x86-64/macros.lisp | 3 +- src/compiler/x86-64/parms.lisp | 21 ++----- src/compiler/x86/macros.lisp | 3 +- src/compiler/x86/parms.lisp | 109 ++++--------------------------------- src/runtime/gencgc.c | 4 ++ src/runtime/globals.h | 5 -- src/runtime/safepoint.c | 6 ++ src/runtime/win32-os.c | 6 ++ src/runtime/x86-64-assem.S | 6 -- src/runtime/x86-assem.S | 6 -- 13 files changed, 111 insertions(+), 137 deletions(-) diff --git a/package-data-list.lisp-expr b/package-data-list.lisp-expr index 2c3552a..4a77d18 100644 --- a/package-data-list.lisp-expr +++ b/package-data-list.lisp-expr @@ -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" diff --git a/src/compiler/generic/genesis.lisp b/src/compiler/generic/genesis.lisp index ed55374..b262fcf 100644 --- a/src/compiler/generic/genesis.lisp +++ b/src/compiler/generic/genesis.lisp @@ -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 diff --git a/src/compiler/generic/parms.lisp b/src/compiler/generic/parms.lisp index b49671f..19af15f 100644 --- a/src/compiler/generic/parms.lisp +++ b/src/compiler/generic/parms.lisp @@ -33,6 +33,80 @@ (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 diff --git a/src/compiler/x86-64/macros.lisp b/src/compiler/x86-64/macros.lisp index 41d91f0..98337e1 100644 --- a/src/compiler/x86-64/macros.lisp +++ b/src/compiler/x86-64/macros.lisp @@ -299,8 +299,7 @@ #!+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) diff --git a/src/compiler/x86-64/parms.lisp b/src/compiler/x86-64/parms.lisp index d294c4f..bd405c7 100644 --- a/src/compiler/x86-64/parms.lisp +++ b/src/compiler/x86-64/parms.lisp @@ -103,25 +103,12 @@ ;;; 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) ;;;; other miscellaneous constants diff --git a/src/compiler/x86/macros.lisp b/src/compiler/x86/macros.lisp index f0ed91e..d7b6bc2 100644 --- a/src/compiler/x86/macros.lisp +++ b/src/compiler/x86/macros.lisp @@ -404,8 +404,7 @@ #!+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) diff --git a/src/compiler/x86/parms.lisp b/src/compiler/x86/parms.lisp index 0fd0dca..5502afd 100644 --- a/src/compiler/x86/parms.lisp +++ b/src/compiler/x86/parms.lisp @@ -184,105 +184,16 @@ ;;; 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) diff --git a/src/runtime/gencgc.c b/src/runtime/gencgc.c index a89d59c..838bcac 100644 --- a/src/runtime/gencgc.c +++ b/src/runtime/gencgc.c @@ -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; diff --git a/src/runtime/globals.h b/src/runtime/globals.h index fc8ad96..b0e812b 100644 --- a/src/runtime/globals.h +++ b/src/runtime/globals.h @@ -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 diff --git a/src/runtime/safepoint.c b/src/runtime/safepoint.c index d94a61e..d28d5b9 100644 --- a/src/runtime/safepoint.c +++ b/src/runtime/safepoint.c @@ -51,6 +51,12 @@ * 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"); diff --git a/src/runtime/win32-os.c b/src/runtime/win32-os.c index b9b1ebe..0c7c893 100644 --- a/src/runtime/win32-os.c +++ b/src/runtime/win32-os.c @@ -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 -- diff --git a/src/runtime/x86-64-assem.S b/src/runtime/x86-64-assem.S index f687c82..053167e 100644 --- a/src/runtime/x86-64-assem.S +++ b/src/runtime/x86-64-assem.S @@ -537,10 +537,4 @@ ascs_finished: ret SIZE(GNAME(arch_scrub_control_stack)) - .globl GNAME(gc_safepoint_page) - .data - .align align_page -GNAME(gc_safepoint_page): - .fill 32768,1,0 - END() diff --git a/src/runtime/x86-assem.S b/src/runtime/x86-assem.S index 0171116..fba970b 100644 --- a/src/runtime/x86-assem.S +++ b/src/runtime/x86-assem.S @@ -940,12 +940,6 @@ GNAME(fast_bzero_pointer): * to fast_bzero_detect if OS supports SSE. */ .long GNAME(fast_bzero_base) - .globl GNAME(gc_safepoint_page) - .data - .align align_page -GNAME(gc_safepoint_page): - .fill BACKEND_PAGE_BYTES,1,0 - .text .align align_16byte,0x90 .globl GNAME(fast_bzero) -- 1.7.10.4