コールスタック・サイズの最大は? どこまで関数は深く呼び出せるのか? (JavaScript)

コールスタック・サイズの最大は?
==

どこまで関数は深く呼び出せるのか?
--

例えばこんなコード：

```js:
// 深く潜る
function diveDeep(n) {
	return diveDeep(n + 1);
}
```

再帰呼び出しをしているが、終了条件が無いので止まらない。

で、最大でどのくらいまで深く関数を呼べるのか試してみた。

TL;DR 結果は以下の通り
--

PCの環境の違いとか、ブラウザの実行状況などで、差が出てくるので、
何回か試してみて、一番大きかった数字を書いた。

| 順位 | ブラウザ | バージョン | 最大コールスタック・サイズ |
|:-:|:-:|:-:|:-:|
| 1 | Node.js(v8) | v6.9.2-x86  | 31,444  |
| 2 | Chrome(v8) | 54.0.2807.0   |  31,424 |
| 3 | Firefox  | 50.0  |  15,538 |
| 4 | Edge  | 14.14393  | 11,528  |
| 5 | IE11  | Trident/7.0  | 10,787  |
| 6 | jjs(nashorn)  | 1.8_60  | 1,187  |
| - | Node.js(v8) | v6.9.2-x86  | 31,444  |
| - | Node.js(v8) | v6.9.2-x64  | 15,699  |
| - | Node.js(v8) | v7.2.1-x86  | 31,412  |
| - | Node.js(v8) | v7.2.1-x64  | 15,664  |
| - | Chrome Canary | 57.0.2947.0 | 4,638 |

32bit版のv8がダントツ。Google, Mozilla, Microsoftの順って感じ。
64bit版のv8になると半減するね。まぁ、そういうもんか。
Canaryはカナリひどい。

※OS: Windows 10 (64bit), Memory: 16GB (2016/12/11時点)

HTMLのソース
--

いくつかのブラウザで試してみた。Chrome, Firefox, Edge, IE11 など。

```html:max-call-stack-size.html
<!doctype html>
<meta charset="UTF-8">
<p>Maximum call stack size:</p>
<script src="max-call-stack-size.js"></script>
```

JavaScriptのソース
--

ブラウザ以外では、nodeとjjs (nashorn; Javaに付いているやつ) で試してみた。

```js:max-call-stack-size.js
// 深く潜る
function diveDeep(n) {
	try {
		return diveDeep(n + 1);
	} catch (e) {
		return {count: n, error: e};
	}
}

// メイン
displayVersion(); // バージョンを表示
var result = diveDeep(0); // 深く潜る
// 結果を表示
pr('Maximum call stack size: ' + result.count);
pr('Error: ' + result.error);
var keys = (Object.getOwnPropertyNames || Object.keys)(result.error);
for (var i in keys)
	pr('Error.' + keys[i] + ': ' + result.error[keys[i]]);

// ブラウザのバージョン等を表示
function displayVersion() {
	pr(typeof navigator !== 'undefined' &&
			navigator.userAgent &&
			'Browser: ' + navigator.userAgent ||
		typeof process !== 'undefined' &&
			process.version &&
			'Node.js: ' + process.version ||
		'other');
}

// 表示
function pr(x) {
	if (typeof document !== 'undefined' && document.writeln)
		document.writeln((x + '\n\n').split('\n').join('<br/>\n'));
	/*else*/ if (typeof console !== 'undefined' && console.log)
		console.log(x);
	else if (typeof print !== 'undefined')
		print(x);
}
```

実行結果
==

Node(x86)
--

```:Node(x86)
Node.js: v6.9.2
Maximum call stack size: 31444
Error: RangeError: Maximum call stack size exceeded
Error.message: Maximum call stack size exceeded
Error.stack: RangeError: Maximum call stack size exceeded
    at diveDeep (xxx/max-call-stack-size.js:6:3)
    at diveDeep (xxx/max-call-stack-size.js:4:10)
    at diveDeep (xxx/max-call-stack-size.js:4:10)
    at diveDeep (xxx/max-call-stack-size.js:4:10)
    at diveDeep (xxx/max-call-stack-size.js:4:10)
    at diveDeep (xxx/max-call-stack-size.js:4:10)
    at diveDeep (xxx/max-call-stack-size.js:4:10)
    at diveDeep (xxx/max-call-stack-size.js:4:10)
    at diveDeep (xxx/max-call-stack-size.js:4:10)
    at diveDeep (xxx/max-call-stack-size.js:4:10)
```

Chrome
--

```:Chrome
Maximum call stack size:

Browser: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36
Maximum call stack size: 31424
Error: RangeError: Maximum call stack size exceeded
Error.stack: RangeError: Maximum call stack size exceeded
    at diveDeep (file:///max-call-stack-size.js:6:3)
    at diveDeep (file:///max-call-stack-size.js:4:10)
    at diveDeep (file:///max-call-stack-size.js:4:10)
    at diveDeep (file:///max-call-stack-size.js:4:10)
    at diveDeep (file:///max-call-stack-size.js:4:10)
    at diveDeep (file:///max-call-stack-size.js:4:10)
    at diveDeep (file:///max-call-stack-size.js:4:10)
    at diveDeep (file:///max-call-stack-size.js:4:10)
    at diveDeep (file:///max-call-stack-size.js:4:10)
    at diveDeep (file:///max-call-stack-size.js:4:10)
Error.message: Maximum call stack size exceeded
```

Firefox
--

```:Firefox
Maximum call stack size:

Browser: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0

Maximum call stack size: 15538

Error: InternalError: too much recursion

Error.fileName: file:///max-call-stack-size.js

Error.lineNumber: 3

Error.columnNumber: 1

Error.message: too much recursion
```

IE11
--

```:IE11
Maximum call stack size:
Browser: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.1; rv:11.0) like Gecko
Maximum call stack size: 10787
Error: Error: スタック領域が不足しています。
Error.message: スタック領域が不足しています。
Error.description: スタック領域が不足しています。
Error.number: -2146828260
Error.stack: Error: スタック領域が不足しています。
   at diveDeep (file:///max-call-stack-size.js:4:3)
   at diveDeep (file:///max-call-stack-size.js:4:3)
   at diveDeep (file:///max-call-stack-size.js:4:3)
   at diveDeep (file:///max-call-stack-size.js:4:3)
   at diveDeep (file:///max-call-stack-size.js:4:3)
   at diveDeep (file:///max-call-stack-size.js:4:3)
   at diveDeep (file:///max-call-stack-size.js:4:3)
   at diveDeep (file:///max-call-stack-size.js:4:3)
   at diveDeep (file:///max-call-stack-size.js:4:3)
   at diveDeep (file:///max-call-stack-size.js:4:3)
```

Edge
--

```:Edge
Maximum call stack size:
Browser: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393
Maximum call stack size: 11528
Error: Error: Out of stack space
Error.message: Out of stack space
Error.description: Out of stack space
Error.number: -2146828260
Error.stack: Error: Out of stack space
   at diveDeep (file:///max-call-stack-size.js:4:3)
   at diveDeep (file:///max-call-stack-size.js:4:3)
   at diveDeep (file:///max-call-stack-size.js:4:3)
   at diveDeep (file:///max-call-stack-size.js:4:3)
   at diveDeep (file:///max-call-stack-size.js:4:3)
   at diveDeep (file:///max-call-stack-size.js:4:3)
   at diveDeep (file:///max-call-stack-size.js:4:3)
   at diveDeep (file:///max-call-stack-size.js:4:3)
   at diveDeep (file:///max-call-stack-size.js:4:3)
   at diveDeep (file:///max-call-stack-size.js:4:3)
```

jjs (nashorn; Java 8)
--

```:jjs
>jjs -v
nashorn 1.8.0_60

>jjs max-call-stack-size.js
other
Maximum call stack size: 1187
Error: java.lang.StackOverflowError
max-call-stack-size.js:16 TypeError: java.lang.StackOverflowError is not an Object
```

Chrome Canary
--

```:ChromeCanary
Maximum call stack size:

Browser: Mozilla/5.0 (Windows NT 10.0.14393; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2947.0 Safari/537.36
Maximum call stack size: 4638
Error: RangeError: Maximum call stack size exceeded
Error.stack: RangeError: Maximum call stack size exceeded
    at diveDeep (file:///max-call-stack-size.js:6:3)
    at diveDeep (file:///max-call-stack-size.js:4:10)
    at diveDeep (file:///max-call-stack-size.js:4:10)
    at diveDeep (file:///max-call-stack-size.js:4:10)
    at diveDeep (file:///max-call-stack-size.js:4:10)
    at diveDeep (file:///max-call-stack-size.js:4:10)
    at diveDeep (file:///max-call-stack-size.js:4:10)
    at diveDeep (file:///max-call-stack-size.js:4:10)
    at diveDeep (file:///max-call-stack-size.js:4:10)
    at diveDeep (file:///max-call-stack-size.js:4:10)
Error.message: Maximum call stack size exceeded
```

でっていう
==

で、何の役にも立たない...

以下の記事を書いた時に気になったので調べただけです。
[竹内関数を遅延評価で高速化してみた(JavaScript/Node.js/ES2015/ES6) - Qiita](http://qiita.com/LightSpeedC/items/304c4bb1d2ea3381a446)