Skip to content

Commit a47c806

Browse files
committed
x86: Check for stack overflow for large stack allocated objects.
On x86, the stack guard page could get missed when allocating large objects on the stack (over 1 page). Instead of giving up or only allowing this on low safety, just check explicitly whether an overflow could happen and signal an appropriate condition. Other platforms don't need this overflow check as urgently, since they do zero-filling which ensures that they will in fact hit the guard page eventually before the stack is manipulated again. (Although there may not be any space left for the handler to do its thing. In any case, a similar check could be added.) We can remove the TRULY-DYNAMIC-EXTENT declaration now, since its only purpose was to facilitate the old way of just avoiding allocations that could silently overflow the stack. If we really want to skip the overflow check during self-build always, that could just be achieved via a special variable. No need to have an extra "internal-only" declaration to do that. This simplifies frontend processing of dynamic extent. Add a test exhibiting large stack allocation interacting with the limited stack size.
1 parent 59f76a1 commit a47c806

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+325
-304
lines changed

NEWS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
;;;; -*- coding: utf-8; fill-column: 78 -*-
22

3+
changes relative to sbcl-2.3.9:
4+
* enhancement: The compiler now allows stack allocating vectors of any size
5+
on all safety levels, not just those which it can prove are of sub-page
6+
sizes. It can do this because it now inserts code to check for stack
7+
overflow explicitly on higher safety levels.
8+
39
changes in sbcl-2.3.9 relative to sbcl-2.3.8:
410
* enhancement: stack allocation via DYNAMIC-EXTENT now applies to all values
511
that a variable can take on (for example via SETQ), not just the initial

benchmarks/grab-mutex.lisp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
(defmacro timing-test (&body body)
2121
`(let ((m *mutex*) (waste (make-array 100 :element-type 'sb-vm:word)))
22-
(declare (truly-dynamic-extent waste))
22+
(declare (dynamic-extent waste))
2323
(setq sb-thread::*grab-mutex-calls-performed* 0)
2424
;; Get all threads to agree on the moment they should start
2525
(sb-thread:signal-semaphore *ready-semaphore*)

contrib/sb-introspect/introspect.lisp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,7 @@ Experimental: interface subject to change."
884884
(not (xset-member-p part seen)))
885885
(add-to-xset part seen)
886886
(funcall fun part))))
887-
(declare (truly-dynamic-extent #'call))
887+
(declare (dynamic-extent #'call))
888888
(when ext
889889
(multiple-value-bind (value foundp)
890890
(let ((table sb-pcl::*eql-specializer-table*))

doc/manual/efficiency.texinfo

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,8 @@ one-dimensional, and has a constant @code{:element-type}.
112112

113113
@cindex Safety optimization quality
114114
@strong{Note}: stack space is limited, so allocation of a large vector
115-
may cause stack overflow. For this reason potentially large vectors,
116-
which might circumvent stack overflow detection, are stack allocated
117-
only in zero @code{safety} policies.
115+
may cause stack overflow. Stack overflow checks are done except in zero
116+
@code{safety} policies.
118117

119118
@item
120119
@findex @cl{flet}

src/code/aprof.lisp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
(sb-fasl:get-asm-routine 'sb-vm::enable-sized-alloc-counter t))
103103
(stack (make-array 1 :element-type 'sb-vm:word))
104104
(insts (code-instructions code)))
105-
(declare (truly-dynamic-extent stack))
105+
(declare (dynamic-extent stack))
106106
(with-alien ((allocation-tracker-counted (function void system-area-pointer) :extern)
107107
(allocation-tracker-sized (function void system-area-pointer) :extern))
108108
(do-packed-varints (loc locs)

src/code/array.lisp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -924,7 +924,7 @@ of specialized arrays is supported."
924924

925925
;;; SUBSCRIPTS has a dynamic-extent list structure and is destroyed
926926
(defun %array-row-major-index (array &rest subscripts)
927-
(declare (truly-dynamic-extent subscripts)
927+
(declare (dynamic-extent subscripts)
928928
(array array))
929929
(let ((length (length subscripts)))
930930
(cond ((array-header-p array)
@@ -958,7 +958,7 @@ of specialized arrays is supported."
958958

959959
(defun array-in-bounds-p (array &rest subscripts)
960960
"Return T if the SUBSCRIPTS are in bounds for the ARRAY, NIL otherwise."
961-
(declare (truly-dynamic-extent subscripts))
961+
(declare (dynamic-extent subscripts))
962962
(let ((length (length subscripts)))
963963
(cond ((array-header-p array)
964964
(let ((rank (%array-rank array)))
@@ -979,12 +979,12 @@ of specialized arrays is supported."
979979
(length (truly-the (simple-array * (*)) array)))))))))
980980

981981
(defun array-row-major-index (array &rest subscripts)
982-
(declare (truly-dynamic-extent subscripts))
982+
(declare (dynamic-extent subscripts))
983983
(apply #'%array-row-major-index array subscripts))
984984

985985
(defun aref (array &rest subscripts)
986986
"Return the element of the ARRAY specified by the SUBSCRIPTS."
987-
(declare (truly-dynamic-extent subscripts))
987+
(declare (dynamic-extent subscripts))
988988
(row-major-aref array (apply #'%array-row-major-index array subscripts)))
989989

990990
;;; (setf aref/bit/sbit) are implemented using setf-functions,
@@ -993,7 +993,7 @@ of specialized arrays is supported."
993993
;;; haven't found technical advantages or disadvantages for either
994994
;;; scheme.
995995
(defun (setf aref) (new-value array &rest subscripts)
996-
(declare (truly-dynamic-extent subscripts)
996+
(declare (dynamic-extent subscripts)
997997
(type array array))
998998
(setf (row-major-aref array (apply #'%array-row-major-index array subscripts))
999999
new-value))
@@ -1020,14 +1020,14 @@ of specialized arrays is supported."
10201020
(defun bit (bit-array &rest subscripts)
10211021
"Return the bit from the BIT-ARRAY at the specified SUBSCRIPTS."
10221022
(declare (type (array bit) bit-array)
1023-
(truly-dynamic-extent subscripts)
1023+
(dynamic-extent subscripts)
10241024
(optimize (safety 1)))
10251025
(row-major-aref bit-array (apply #'%array-row-major-index bit-array subscripts)))
10261026

10271027
(defun (setf bit) (new-value bit-array &rest subscripts)
10281028
(declare (type (array bit) bit-array)
10291029
(type bit new-value)
1030-
(truly-dynamic-extent subscripts)
1030+
(dynamic-extent subscripts)
10311031
(optimize (safety 1)))
10321032
(setf (row-major-aref bit-array
10331033
(apply #'%array-row-major-index bit-array subscripts))
@@ -1036,15 +1036,15 @@ of specialized arrays is supported."
10361036
(defun sbit (simple-bit-array &rest subscripts)
10371037
"Return the bit from SIMPLE-BIT-ARRAY at the specified SUBSCRIPTS."
10381038
(declare (type (simple-array bit) simple-bit-array)
1039-
(truly-dynamic-extent subscripts)
1039+
(dynamic-extent subscripts)
10401040
(optimize (safety 1)))
10411041
(row-major-aref simple-bit-array
10421042
(apply #'%array-row-major-index simple-bit-array subscripts)))
10431043

10441044
(defun (setf sbit) (new-value bit-array &rest subscripts)
10451045
(declare (type (simple-array bit) bit-array)
10461046
(type bit new-value)
1047-
(truly-dynamic-extent subscripts)
1047+
(dynamic-extent subscripts)
10481048
(optimize (safety 1)))
10491049
(setf (row-major-aref bit-array
10501050
(apply #'%array-row-major-index bit-array subscripts))

src/code/cross-early.lisp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111

1212
(in-package "SB-IMPL")
1313

14-
(declaim (declaration truly-dynamic-extent))
15-
1614
;;; MAYBE-INLINE, FREEZE-TYPE, and block compilation declarations can be safely ignored
1715
;;; (possibly at some cost in efficiency).
1816
(declaim (declaration freeze-type maybe-inline start-block end-block))

src/code/debug.lisp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2049,7 +2049,7 @@ forms that explicitly control this kind of evaluation.")
20492049
(string (make-array 127 :element-type 'base-char))
20502050
(n 0)
20512051
code)
2052-
(declare (truly-dynamic-extent cursor string))
2052+
(declare (dynamic-extent cursor string))
20532053
(aver (zerop
20542054
(sb-alien:alien-funcall sb-unw-init
20552055
(vector-sap cursor) (sb-alien:alien-sap context))))

src/code/early-extensions.lisp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,7 @@
265265
(push `(,name (&rest args) ,macro-body) macros))))
266266
`(macrolet ,macros
267267
(let* ,(nreverse binds)
268-
,@(if dx `((declare (#+sb-xc-host dynamic-extent ; maybe host can do
269-
#-sb-xc-host truly-dynamic-extent ,@dx))))
268+
,@(if dx `((declare (dynamic-extent ,@dx))))
270269
;; Even if the user reads each collection result,
271270
;; reader conditionals might statically eliminate all writes.
272271
;; Since we don't know, all the -n-tail variable are ignorable.
@@ -1282,7 +1281,6 @@ NOTE: This interface is experimental and subject to change."
12821281
((or (listp id) ; must be a type-specifier
12831282
(memq id '(special ignorable ignore
12841283
dynamic-extent
1285-
truly-dynamic-extent
12861284
sb-c::constant-value
12871285
sb-c::no-constraints))
12881286
(info :type :kind id))

src/code/eval.lisp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@
340340

341341
(defun values (&rest values)
342342
"Return all arguments, in order, as values."
343-
(declare (truly-dynamic-extent values))
343+
(declare (dynamic-extent values))
344344
(values-list values))
345345

346346
(defun values-list (list)

0 commit comments

Comments
 (0)