Repository navigation
Fix duplicate intermediate addresses in nested struct assignments - #585
Open
jogibear9988 wants to merge 1 commit into
Open
jogibear9988 wants to merge 1 commit into
jogibear9988 wants to merge 1 commit into
Conversation
Assignments through nested struct fields can leave an extra managed address on the evaluation stack. On master, the regression compiles strictly but invoking the delegate throws InvalidProgramException in both expression APIs. Compute the duplication destination once in the existing member emitter: duplicate the receiver or the final writable address when requested, and retain one address for intermediate struct owners. No new emitter, traversal, context metadata or allocation is introduced. Focused Standard/Light regressions pass on .NET 8, .NET 10 and .NET Framework 4.7.2. Full solution and legacy suites pass. Modern full runners retain only the reproduced upstream nullable MultiplyChecked parity failure. Working benchmark controls retain allocation counts and emitted IL.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Assignments through nested struct fields can leave an extra managed address on the evaluation stack. On master, the regression compiles strictly but invoking the delegate throws InvalidProgramException in both expression APIs.
Compute the duplication destination once in the existing member emitter: duplicate the receiver or the final writable address when requested, and retain one address for intermediate struct owners. No new emitter, traversal, context metadata or allocation is introduced.
Validation
Covers value/void assignments, one-time receiver/RHS evaluation, compound and increment results, and ref access. For the nested compound shape where System lowers through a struct copy, the test records that behavior separately and checks writable storage using an explicit once-only assignment expansion.
Performance checks
Compared with master at
f8f2a240abd650dda738162957606aac2659873fusing already-working expressions, for both Standard and LightExpression. The broken regression establishes correctness and is not used as a before/after speed baseline. All selected working controls retain identical decoded emitted IL and the same measured compilation/invocation allocation counts.Measurement setup and full results
Windows ARM64, SDK 10.0.301, .NET 8.0.28/10.0.9, Release. Prebuilt trees; Light conversion outside the timed section; strict CompileFast without System fallback; fixed CPU affinity, tiering disabled, 300 compilation warmups and 100,000 invocation warmups. Two fresh processes with opposite load order, nine alternating samples per side, GC before samples and a 256 MiB no-GC region where available. Table values are geometric means of process medians; compilation uses the longer approximately 100 ms paired-calibration run and invocation uses approximately 24 ms. Framework is correctness-tested, not timed.
The full short run covers add, reference constant, root/nested constructors, a 16-argument delegate, flat field assignment and nested field reads. The longer run focuses on this fix's affected working paths plus unchanged controls. Slower observations are included above. Identical-binary master/master compilation variation in the same setup was net10.0: -11.6% to +10.4%; net8.0: -21.3% to +14.0%. These timings do not prove zero overhead for every input/machine, and no speedup claim is made. Runtime timing differences above are observations of identical emitted control IL.
All-process compilation timing ranges
These ranges include the less stable observations, not just the longer-run aggregate in the table. They are individual process-median changes across working controls; they are not speedup claims.