Repository navigation
Preserve array initializer values across exception regions - #614
Conversation
|
@jogibear9988 It seems the 2 prs where overlapping and require resolution by hand |
Array initializers keep the new array and element position on the stack while evaluating an element. A try/finally in that element can invalidate the stack. Mark affected initializers during collection and use existing local-variable emission to store the array and element values.
7dddfde to
ed50aff
Compare
|
You're right: #613 and this PR handled different array forms, but both changed the same collection block. I should have called out that overlap. Rebased onto master The full Release solution build and .NET 8, .NET 10 and Framework test runners pass, including both bounds and initializer regressions, for Standard and LightExpression. Modern runners pass 467 TestX groups; Framework passes 446, alongside the legacy suites. I also refreshed compilation/runtime measurements against this master, for both APIs and six working controls. Allocations and emitted IL are unchanged in every measured control. Timings move in both directions, including unchanged controls, so I am not claiming a general speedup or proving universal performance neutrality. The description contains the current measurements and validation results. |
Array initializers keep the new array and element position on the stack while evaluating an element. A try/finally in that element can invalidate the stack. Mark affected initializers during collection and use existing local-variable emission to store the array and element values. Array bounds and initializers share one collection loop: initializers require an empty stack for every element containing an exception region, while bounds require spilling only when the exception region follows an earlier bound.
Value, reference, nullable and decimal elements; cleanup, exceptions, side effects and discarded results. Regressions use strict FEC compilation for both Standard and LightExpression.
Validation
Release solution build: zero warnings/errors.
Measurements
Current master
ce28e2b0→ this change, Release, Windows ARM64, .NET 8.0.28 / 10.0.9. Compilation uses prebuilt trees; runtime measures invocation through the same wrapper. Two fresh process rounds with reversed load order, seven samples per round, about 30 ms calibration, one logical CPU and tiered compilation disabled. Tables use the median of the two per-round medians.The controls below produce correct results on master for their measured inputs. Newly supported trees have no valid before/after execution comparison because master rejects them, produces incorrect results or emits invalid IL. Timings include machine and JIT/code-placement variation; the unchanged add control helps show that variation. These observations do not prove universal performance neutrality.
net8.0 results (master → change)
net10.0 results (master → change)
Emitted IL differs in these measured workloads: none.
No measured allocation increase above 0.1 B/op in these controls.