1;;;; Copyright (C) 2008 Free Software Foundation, Inc. 2;;;; 3;;;; This library is free software; you can redistribute it and/or 4;;;; modify it under the terms of the GNU Lesser General Public 5;;;; License as published by the Free Software Foundation; either 6;;;; version 2.1 of the License, or (at your option) any later version. 7;;;; 8;;;; This library is distributed in the hope that it will be useful, 9;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of 10;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11;;;; Lesser General Public License for more details. 12;;;; 13;;;; You should have received a copy of the GNU Lesser General Public 14;;;; License along with this library; if not, write to the Free Software 15;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 16;;;; 17 18;;; Commentary: 19 20;;; This code is run during the Guile build, in order to set the stack 21;;; limit to a value that will allow the `make check' tests to pass, 22;;; taking into account the average stack usage on the build platform. 23;;; For more detail, see the text below that gets written out to the 24;;; stack limit calibration file. 25 26;;; Code: 27 28;; Store off Guile's default stack limit. 29(define default-stack-limit (cadr (memq 'stack (debug-options)))) 30 31;; Now disable the stack limit, so that we don't get a stack overflow 32;; while running this code! 33(debug-set! stack 0) 34 35;; Define a variable to hold the measured stack high water mark (HWM). 36(define top-repl-hwm-measured 0) 37 38;; Use an evaluator trap to measure the stack size at every 39;; evaluation step, and increase top-repl-hwm-measured if it is less 40;; than the measured stack size. 41(trap-set! enter-frame-handler 42 (lambda _ 43 (let ((stack-size (%get-stack-size))) 44 (if (< top-repl-hwm-measured stack-size) 45 (set! top-repl-hwm-measured stack-size))))) 46(trap-enable 'enter-frame) 47(trap-enable 'traps) 48 49;; Call (turn-on-debugging) and (top-repl) in order to simulate as 50;; closely as possible what happens - and in particular, how much 51;; stack is used - when a standard Guile REPL is started up. 52;; 53;; `make check' stack overflow errors have been reported in the past 54;; for: 55;; 56;; - test-suite/standalone/test-use-srfi, which runs `guile -q 57;; --use-srfi=...' a few times, with standard input for the REPL 58;; coming from a shell script 59;; 60;; - test-suite/tests/elisp.test, which does not involve the REPL, but 61;; has a lot of `use-modules' calls. 62;; 63;; Stack high water mark (HWM) measurements show that the HWM is 64;; higher in the test-use-srfi case - specifically because of the 65;; complexity of (top-repl) - so that is what we simulate for our 66;; calibration model here. 67(turn-on-debugging) 68(with-output-to-port (%make-void-port "w") 69 (lambda () 70 (with-input-from-string "\n" top-repl))) 71 72;; top-repl-hwm-measured now contains the stack HWM that resulted from 73;; running that code. 74 75;; This is the value of top-repl-hwm-measured that we get on a 76;; `canonical' build platform. (See text below for what that means.) 77(define top-repl-hwm-i686-pc-linux-gnu 9461) 78 79;; Using the above results, output code that tests can run in order to 80;; configure the stack limit correctly for the current build platform. 81(format #t "\ 82;; Stack limit calibration file. 83;; 84;; This file is automatically generated by Guile when it builds, in 85;; order to set the stack limit to a value that reflects the stack 86;; usage of the build platform (OS + compiler + compilation options), 87;; specifically so that none of Guile's own tests (which are run by 88;; `make check') fail because of a benign stack overflow condition. 89;; 90;; By a `benign' stack overflow condition, we mean one where the test 91;; code is behaving correctly, but exceeds the configured stack limit 92;; because the limit is set too low. A non-benign stack overflow 93;; condition would be if a piece of test code behaved significantly 94;; differently on some platform to how it does normally, and as a 95;; result consumed a lot more stack. Although they seem pretty 96;; unlikely, we would want to catch non-benign conditions like this, 97;; and that is why we don't just do `(debug-set! stack 0)' when 98;; running `make check'. 99;; 100;; Although the primary purpose of this file is to prevent `make 101;; check' from failing without good reason, Guile developers and users 102;; may also find the following information useful, when determining 103;; what stack limit to configure for their own programs. 104 105 (let (;; The stack high water mark measured when starting up the 106 ;; standard Guile REPL on the current build platform. 107 (top-repl-hwm-measured ~a) 108 109 ;; The value of top-repl-hwm-measured that we get when building 110 ;; Guile on an i686 PC GNU/Linux system, after configuring with 111 ;; `./configure --enable-maintainer-mode --with-threads'. 112 ;; (Hereafter referred to as the `canonical' build platform.) 113 (top-repl-hwm-i686-pc-linux-gnu ~a) 114 115 ;; Guile's default stack limit (i.e. the initial, C-coded value 116 ;; of the 'stack debug option). In the context of this file, 117 ;; the important thing about this number is that we know that 118 ;; it allows all of the `make check' tests to pass on the 119 ;; canonical build platform. 120 (default-stack-limit ~a) 121 122 ;; Calibrated stack limit. This is the default stack limit, 123 ;; scaled by the factor between top-repl-hwm-i686-pc-linux-gnu 124 ;; and top-repl-hwm-measured. 125 (calibrated-stack-limit ~a)) 126 127 ;; Configure the calibrated stack limit. 128 (debug-set! stack calibrated-stack-limit)) 129" 130 top-repl-hwm-measured 131 top-repl-hwm-i686-pc-linux-gnu 132 default-stack-limit 133 ;; Use quotient here to get an integer result, rather than a 134 ;; rational. 135 (quotient (* default-stack-limit top-repl-hwm-measured) 136 top-repl-hwm-i686-pc-linux-gnu)) 137