When threads have marginally more than 128 KB of stack space, RuntimeHelpers.TryEnsureSufficientExecutionStack discounts 128 KB of stack space and only considers the remaining space, and there may not be enough even for a non-nested/non-recursive thread pool work item. In that situation, StackGuard.RunOnEmptyStackCore is triggered again from its continuation and keeps doing so since TryEnsureSufficientExecutionStack always returns false.
This appears to be the continuation triggered by RunOnEmptyStackCore, which triggers itself continually:
|
private Result RewriteExpression(Expression node, Stack stack) |
|
{ |
|
if (node == null) |
|
{ |
|
return new Result(RewriteAction.None, null); |
|
} |
|
|
|
// When compiling deep trees, we run the risk of triggering a terminating StackOverflowException, |
|
// so we use the StackGuard utility here to probe for sufficient stack and continue the work on |
|
// another thread when we run out of stack space. |
|
if (!_guard.TryEnterOnCurrentStack()) |
|
{ |
|
return _guard.RunOnEmptyStack((StackSpiller @this, Expression n, Stack s) => @this.RewriteExpression(n, s), this, node, stack); |
When threads have marginally more than 128 KB of stack space,
RuntimeHelpers.TryEnsureSufficientExecutionStackdiscounts 128 KB of stack space and only considers the remaining space, and there may not be enough even for a non-nested/non-recursive thread pool work item. In that situation,StackGuard.RunOnEmptyStackCoreis triggered again from its continuation and keeps doing so sinceTryEnsureSufficientExecutionStackalways returns false.This appears to be the continuation triggered by
RunOnEmptyStackCore, which triggers itself continually:runtime/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/StackSpiller.Generated.cs
Lines 16 to 28 in 16300e0