Remove the usage of VLAs in the code#7348
Conversation
|
I think statically sized arrays or in To be honest I don't really share the concerns over VLAs. We've used them for years without any issues. The zero-length VLA issue seems a bit language lawyering. |
|
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: |
|
TODO (from meeting):
|
|
Discussed in Nix team meeting 2022-12-19:
|
|
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: |
VLAs are a dangerous feature, and their usage triggers an undefined behavior since theire size can be zero in some cases. So replace them with `boost::small_vector`s which fit the same goal but are safer. It's also incidentally consistently 1% faster on the benchmarks.
There's generally no strict reason for using them, and they are somewhat fishy, so let's avoid them.
df95344 to
bdefeb5
Compare
78fc6b6 to
41b945a
Compare
I've reduced the numbers significantly. Most significantly, 4 is enough for normal lambda calls. I expect the primops to contribute less to stack depth by number of nested invocations, so these use larger numbers, albeit reduced from what was originally in the PR.
This is infinitely faster on expressions where these VLAs caused stack overflows.
I find this somewhat pointless since the code does not allocate variable amounts of stack space anymore. Yes, tests are good, but these would be expensive, especially in terms of maintaining them because it involves developing non-trivial test support code for it. Silvan could attest that this is non-trivial. I'd rather focus that effort on more impactful testing improvements. |
|
bug label: Fixes a stack overflow: NixOS/nixpkgs#214021 (comment) |
thufschmitt
left a comment
There was a problem hiding this comment.
Thanks for taking over this @roberth !
Looks good to me, although I think this deserves some benchmarks (IIRC, the original version had a small impact depending on the sizes chosen)
This makes stack usage significantly more compact, allowing larger amounts of data to be processed on the same stack. PrimOp functions with more than 8 positional (curried) arguments should use an attrset instead.
Clang warned that the expanded code used to have a buffer overflow. Very strange, but also very avoidable.
Try to stay away from stack overflows. These small vectors use stack space. Most instances will not need to allocate because in general most things are small, and large things are worth heap allocating. 16 * 3 * word = 384 bytes is still quite a bit, but these functions tend not to be part of deep recursions.
128 is still beyond the point where the allocation overhead is insignificant, but we don't anticipate to overflow for these use cases, so it's fine.
41b945a to
4e27f19
Compare
That would be great, but I can only treat this as a bugfix unfortunately. |
I wasn't, but I hyperfined it and there's zero visible difference on |
|
This broke the |
|
Remove the usage of VLAs in the code (cherry picked from commit ac4431e) Change-Id: Ifbf5fbfc2e27122362a2aaea4b62c7cf3ca46b1a
Although Variable-length arrays are allowed by the C standard, they are frowned
upon, and aren't valid C++ (
gccaccepts them a non-standard extension) andclangapparently does the same which is why they work here). So better get rid of them altogether.Depends on #7346.