diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-10-06 13:37:41 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-10-12 12:29:09 -0300 |
commit | 9ecd446141f572252a57cb33d2bba6aa00d96a55 (patch) | |
tree | cecd4f91efc181f652d6647e18772732262422a5 /testes | |
parent | fb172d0a929432856983a51d4139f705d4c01365 (diff) | |
download | lua-9ecd446141f572252a57cb33d2bba6aa00d96a55.tar.gz lua-9ecd446141f572252a57cb33d2bba6aa00d96a55.tar.bz2 lua-9ecd446141f572252a57cb33d2bba6aa00d96a55.zip |
Avoid shrinking stacks to often
Shrink a stack only when the final stack size can be at most 2/3 the
previous size with half of its entries empty. This commit also
improves the clarity of 'luaD_growstack'.
Diffstat (limited to 'testes')
-rw-r--r-- | testes/cstack.lua | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/testes/cstack.lua b/testes/cstack.lua index 5767adf6..8ac48e89 100644 --- a/testes/cstack.lua +++ b/testes/cstack.lua | |||
@@ -2,7 +2,7 @@ | |||
2 | -- See Copyright Notice in file all.lua | 2 | -- See Copyright Notice in file all.lua |
3 | 3 | ||
4 | 4 | ||
5 | print"testing C-stack overflow detection" | 5 | print"testing stack overflow detection" |
6 | 6 | ||
7 | -- Segmentation faults in these tests probably result from a C-stack | 7 | -- Segmentation faults in these tests probably result from a C-stack |
8 | -- overflow. To avoid these errors, you should set a smaller limit for | 8 | -- overflow. To avoid these errors, you should set a smaller limit for |
@@ -98,4 +98,52 @@ do | |||
98 | print("final count: ", count) | 98 | print("final count: ", count) |
99 | end | 99 | end |
100 | 100 | ||
101 | |||
102 | if T then | ||
103 | print("testing stack recovery") | ||
104 | local N = 0 -- trace number of calls | ||
105 | local LIM = -1 -- will store N just before stack overflow | ||
106 | |||
107 | -- trace stack size; after stack overflow, it should be | ||
108 | -- the maximum allowed stack size. | ||
109 | local stack1 | ||
110 | local dummy | ||
111 | |||
112 | local function err(msg) | ||
113 | assert(string.find(msg, "stack overflow")) | ||
114 | local _, stacknow = T.stacklevel() | ||
115 | assert(stacknow == stack1 + 200) | ||
116 | end | ||
117 | |||
118 | -- When LIM==-1, the 'if' is not executed, so this function only | ||
119 | -- counts and stores the stack limits up to overflow. Then, LIM | ||
120 | -- becomes N, and then the 'if' code is run when the stack is | ||
121 | -- full. Then, there is a stack overflow inside 'xpcall', after which | ||
122 | -- the stack must have been restored back to its maximum normal size. | ||
123 | local function f() | ||
124 | dummy, stack1 = T.stacklevel() | ||
125 | if N == LIM then | ||
126 | xpcall(f, err) | ||
127 | local _, stacknow = T.stacklevel() | ||
128 | assert(stacknow == stack1) | ||
129 | return | ||
130 | end | ||
131 | N = N + 1 | ||
132 | f() | ||
133 | end | ||
134 | |||
135 | local topB, sizeB -- top and size Before overflow | ||
136 | local topA, sizeA -- top and size After overflow | ||
137 | topB, sizeB = T.stacklevel() | ||
138 | xpcall(f, err) | ||
139 | topA, sizeA = T.stacklevel() | ||
140 | -- sizes should be comparable | ||
141 | assert(topA == topB and sizeA < sizeB * 2) | ||
142 | print(string.format("maximum stack size: %d", stack1)) | ||
143 | LIM = N -- will stop recursion at maximum level | ||
144 | N = 0 -- to count again | ||
145 | f() | ||
146 | print"+" | ||
147 | end | ||
148 | |||
101 | print'OK' | 149 | print'OK' |