measure-hwm.scm 5.7 KB

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