Skip to content

Preserve operand storage for ref conversion methods - #624

Open
jogibear9988 wants to merge 1 commit into
dadhi:masterfrom
jogibear9988:fix/ref-conversion-storage-independent
Open

jogibear9988 wants to merge 1 commit into
dadhi:masterfrom
jogibear9988:fix/ref-conversion-storage-independent

Conversation

@jogibear9988

Copy link
Copy Markdown
Contributor

Explicit conversion methods taking a ref parameter can receive a temporary instead of the original storage. Normalize the formal parameter type and distinguish direct ref passing from lifted conversions, which must use an unwrapped value copy.

Incoming references, value parameters, locals, fields, constants and method results; lifted/null cases, mutation, nullable struct results, discarded results and non-ref controls. These new custom-ref conversion regressions use the Standard expression API; the full LightExpression suite also runs. Regressions require strict FEC compilation. Native suites cover Standard and LightExpression.

Validation

Local validation uses master baseline 094d067 plus this change. Release solution build: zero warnings/errors.

Runtime TestX groups Legacy tests
.NET 10 493 passed 1,756 passed
.NET 8 493 passed 1,755 passed
.NET Framework 4.7.2 472 passed 1,639 passed

Measurements

Master baseline 094d0678 → 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)
API / workload Compile ns Invoke ns Compile B/op Invoke B/op
Standard / add_control 1783.3 → 1810.2 2.8 → 2.9 872.0 → 872.0 0.0 → 0.0
Standard / numeric_conversion 1711.3 → 1578.9 3.1 → 3.2 872.1 → 872.1 0.0 → 0.0
Standard / nullable_conversion 3071.8 → 3193.4 2.8 → 2.9 1648.1 → 1648.1 0.0 → 0.0
Standard / method_conversion 1514.6 → 1645.5 3.0 → 3.0 928.0 → 928.0 0.0 → 0.0
Standard / method_nullable_conversion 3072.0 → 3032.7 2.8 → 3.0 1704.0 → 1704.0 0.0 → 0.0
Standard / lifted_ref_conversion 3431.2 → 2959.2 2.8 → 2.7 1712.0 → 1712.0 0.0 → 0.0
Light / add_control 1315.2 → 1369.1 2.5 → 2.5 872.0 → 872.0 0.0 → 0.0
Light / numeric_conversion 1379.8 → 1427.8 3.1 → 3.1 872.0 → 872.0 0.0 → 0.0
Light / nullable_conversion 2771.3 → 3051.6 2.8 → 2.7 1648.1 → 1648.1 0.0 → 0.0
net10.0 results (master → change)
API / workload Compile ns Invoke ns Compile B/op Invoke B/op
Standard / add_control 4447.5 → 4593.4 2.6 → 2.6 872.1 → 872.1 0.0 → 0.0
Standard / numeric_conversion 4077.3 → 4068.4 2.5 → 2.5 872.1 → 872.1 0.0 → 0.0
Standard / nullable_conversion 7927.6 → 7699.5 2.4 → 2.4 1648.2 → 1648.2 0.0 → 0.0
Standard / method_conversion 4404.5 → 4366.8 2.5 → 2.5 928.0 → 928.0 0.0 → 0.0
Standard / method_nullable_conversion 7565.3 → 7762.5 2.3 → 2.3 1704.0 → 1704.0 0.0 → 0.0
Standard / lifted_ref_conversion 8139.0 → 7858.3 2.4 → 2.3 1712.0 → 1712.0 0.0 → 0.0
Light / add_control 3450.1 → 3418.9 2.3 → 2.2 872.0 → 872.0 0.0 → 0.0
Light / numeric_conversion 3032.9 → 3103.5 2.5 → 2.4 872.1 → 872.1 0.0 → 0.0
Light / nullable_conversion 7113.9 → 6738.5 2.5 → 2.4 1648.1 → 1648.1 0.0 → 0.0

Emitted IL differs in these measured workloads: none.
No measured allocation increase above 0.1 B/op in these controls.

Explicit conversion methods taking a ref parameter can receive a temporary instead of the original storage. Normalize the formal parameter type and distinguish direct ref passing from lifted conversions, which must use an unwrapped value copy.

Validation: Release solution build; full Standard and LightExpression .NET 8, .NET 10 and Framework runners pass.

Measurements: master 094d067 versus this change, compilation and invocation, both APIs, .NET 8/10, two opposite-order process rounds with seven samples each. No measured allocation increase above 0.1 B/op in the selected working controls. Timings and emitted IL are recorded in the PR description; these controls do not establish universal performance neutrality.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant