diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-01-11 21:30:03 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-01-11 21:30:03 -0800 |
commit | 08d261d183a6071f8d72ea9af05c59c152f28c95 (patch) | |
tree | d0540433fef13941e37c833eecf65d2b7f756a5b | |
parent | 5e107c8d5a10b74933f52cffaa27d0c01106dc60 (diff) |
do not blow up the stack with lots of varargs
-rw-r--r-- | src/analyzer.js | 55 | ||||
-rw-r--r-- | src/runtime.js | 3 | ||||
-rw-r--r-- | tests/runner.py | 20 |
3 files changed, 61 insertions, 17 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index 4aac53a8..6fd7ef66 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -788,26 +788,49 @@ function analyzer(data, sidePass) { delete item.allocatedSize; } func.initialStack = index; - // We need to note if stack allocations other than initial allocs can happen here - // (for example, via alloca). If so, we need to rewind the stack when we leave. func.otherStackAllocations = false; - var finishedInitial = false; - for (var i = 0; i < lines.length; i++) { - var item = lines[i].value; - if (!item || item.intertype != 'alloca') { - finishedInitial = true; - continue; + while (func.initialStack == 0) { // one-time loop with possible abort in the middle + // If there is no obvious need for stack management, perhaps we don't need it + // (we try to optimize that way with SKIP_STACK_IN_SMALL). However, + // we need to note if stack allocations other than initial allocs can happen here + // If so, we need to rewind the stack when we leave. + + // By-value params are causes of additional allocas (although we could in theory make them normal allocas too) + func.params.forEach(function(param) { + if (param.byVal) { + func.otherStackAllocations = true; + } + }); + if (func.otherStackAllocations) break; + + // Allocas + var finishedInitial = false; + for (var i = 0; i < lines.length; i++) { + var item = lines[i].value; + if (!item || item.intertype != 'alloca') { + finishedInitial = true; + continue; + } + if (item.intertype == 'alloca' && finishedInitial) { + func.otherStackAllocations = true; + break; + } } - if (item.intertype == 'alloca' && finishedInitial) { - func.otherStackAllocations = true; + if (func.otherStackAllocations) break; + + // Varargs + for (var i = 0; i < lines.length; i++) { + var item = lines[i]; + if (item.value) item = item.value; + if (item.intertype == 'call' && isVarArgsFunctionType(item.type)) { + func.otherStackAllocations = true; + break; + } } + if (func.otherStackAllocations) break; + + break; } - // by-value params are also causes of additional allocas (although we could in theory make them normal allocas too) - func.params.forEach(function(param) { - if (param.byVal) { - func.otherStackAllocations = true; - } - }); }); this.forwardItem(data, 'Relooper'); } diff --git a/src/runtime.js b/src/runtime.js index 2b81258d..6439d0ed 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -34,7 +34,8 @@ var RuntimeGenerator = { stackEnter: function(initial, force) { if (initial === 0 && SKIP_STACK_IN_SMALL && !force) return ''; - var ret = 'var __stackBase__ = STACKTOP; STACKTOP += ' + initial; + var ret = 'var __stackBase__ = STACKTOP'; + if (initial > 0) ret += '; STACKTOP += ' + initial; if (USE_TYPED_ARRAYS == 2) { assert(initial % QUANTUM_SIZE == 0); if (ASSERTIONS) { diff --git a/tests/runner.py b/tests/runner.py index 18ce11af..dd11b950 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -1459,6 +1459,26 @@ if 'benchmark' not in str(sys.argv) and 'sanity' not in str(sys.argv): ''' self.do_run(src, 'sum:9780*') + # We should not blow up the stack with numerous varargs + + src = r''' + #include <stdio.h> + #include <stdlib.h> + + void func(int i) { + printf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", + i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i); + } + int main() { + for (int i = 0; i < 1024; i++) + func(i); + printf("ok!\n"); + return 0; + } + ''' + Settings.TOTAL_STACK = 1024 + self.do_run(src, 'ok!') + def test_array2(self): src = ''' #include <stdio.h> |