Proposal: Add a new keyword "trystackalloc" to prevent stack overflow #1344
-
It should only be used with Span. If there's no enough space on stack, it should return an empty Span, instead of throwing exception. For example: Span<int> sp = trystackalloc int[1000];
if(sp.Length==0) sp = new int[1000];
...... |
Beta Was this translation helpful? Give feedback.
Replies: 9 comments
-
Related proposal: https:/dotnet/corefx/issues/26954. With that, your code would probably look like this Span<int> span = stackalloc int[0];
if (RuntimeHelpers.TryEnsureSufficientExecutionStack(1000 * sizeof(int)))
span = stackalloc int[1000];
else
span = new int[1000]; I feel like adding a method is a better solution here: |
Beta Was this translation helpful? Give feedback.
-
These are two specialized constructs that do not address the scenario well. The scenario is allocation of a local scratch buffer of variable size. We need a construct that does that, without exposing the ugly details on how it is done underneath. It should automatically allocate inline from the stack when it the requested buffer is small, and from the pool when the requested buffer is large. E.g. it can look something like this:
|
Beta Was this translation helpful? Give feedback.
-
@jkotas If such abstraction is possible and can work well, then yeah, that would be a better option. Though I have a hard time imagining how that would work both on the inside (how is |
Beta Was this translation helpful? Give feedback.
-
@jkotas |
Beta Was this translation helpful? Give feedback.
-
The portable implementation of LocalBuffer can look like this:
This won't actually compile. You have to sprinkle with workarounds for the current C# language limitations to get it to compile, but you should get the idea. This can be further improved by treating LocalBuffer as runtime intrinsic type. It would allow allocating the object reference-containing buffers on the stack as well, etc. |
Beta Was this translation helpful? Give feedback.
-
@jkotas I think that implementation does not really replace Are you saying the intrinsic version could do that? |
Beta Was this translation helpful? Give feedback.
-
Yes, the intrinsic version can do that. More importantly, the intrinsic version allows runtime to pick the right threshold for you based the performance data. E.g. the threshold can differ between platforms, or for types that contain GC references and types that to not contain references. Also, I believe that the threshold for where it stops being worth it to allocate the buffers on the stack is pretty small, probably in the hundreds of bytes range. Once the max stackallocated buffer is this small, checking for sufficient space on the stack is not really a concern. |
Beta Was this translation helpful? Give feedback.
-
I have opened a somewhat related issue: #1817 stackalloc from caller's stack frame. If that was implemented, it would be possible to write a method that takes into account any number of factors (the size of the required buffer, |
Beta Was this translation helpful? Give feedback.
-
There's a proposal to handle this purely by adding a runtime API: dotnet/runtime#25423 |
Beta Was this translation helpful? Give feedback.
There's a proposal to handle this purely by adding a runtime API: dotnet/runtime#25423