Stabilize TypeRef allocation gate - #4635
Conversation
Run allocation probes on an isolated thread and require steady-state zero-allocation batches so tiered runtime work cannot contaminate the asserted sample. Keep a non-vacuity test that proves persistent operation allocations remain visible. Fixes #4630 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use a fixed 10,000-call warmup and fixed 10,000-call measurement rather than searching for a quiet batch, preserving sensitivity to amortized allocations. Propagate isolated-thread exceptions and timeouts for attributable failures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Round 1 review reconciliation for locked head
I independently reproduced the finding against this exact head with the real test under bounded allocation pressure: 97/1,000 failures, all showing the same false-positive shape ( The replacement will serialize the allocation gate, drain prior GC/finalizer work, and accept only a fixed-width sample taken while a verified bounded no-GC region remained active. Region mechanics will invalidate a bounded attempt; they will not convert into a product allocation result. The fixed 10,000-call sample and amortized-allocation non-vacuity gate remain. |
Serialize the allocation gate and accept a fixed-width sample only while a bounded no-GC region remains active. Retry invalid region attempts without minimizing or discarding any valid non-zero product sample. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Round 2 replacement candidate pushed: exact head |
|
Round 2 fixed-head reviews dispatched at exact head |
|
Round 2 review reconciliation for exact head
No findings require action. Both required reviews are review-clean on the unchanged current head. |
…-type-ref-allocation-gate
|
Approved clean-review carry-forward completed: merge-only head |
…-type-ref-allocation-gate
|
Approved clean-review carry-forward completed again: merge-only head |
Summary
Makes the
TypeRefzero-allocation gate deterministic on Linux without changing product behavior or accepting amortized allocations.Closes #4630.
Demo
Before, a GC suspension could retire the measuring thread's unused allocation context and inflate its counter even when
TypeRefallocated nothing:The original round-1 remedy reproduced the same mechanism under bounded in-process pressure:
After, the gate retains a fixed 10,000-operation zero-byte sample but accepts it only when the runtime confirms that no GC interrupted the window. A neighboring amortized-allocation case remains non-zero, proving the guard does not turn the measurement into a success-shaped fallback.
Validation
dotnet run --project src/ILInspector.Analysis.Tests -c Release -- -method '*TypeRefShallowEqualityAndHashing_DoNotAllocate*' -method '*TypeRefExactAndLegacySimpleNames_AgreeWithoutDelimiterInference*' -method '*AllocationMeasurement_RejectsAmortizedOperationAllocation*'dotnet run --project src/ILInspector.Analysis.Tests -c Release(1,148 total, 0 failed, 8 environment-dependent corpus skips)