Repository navigation
Conversation
Use compatible candidates returned by pickGDV instead of discarding every candidate after the first. Validate candidates with compareTypesForCast and require guards sharing a success block to agree on whether they return the object or null. Load the object's method table once for multi-guard expansions. Retain the specialized class-cast fallback only when the target type itself has been ruled out, and keep the existing GDV candidate limits and profitability thresholds unchanged. <!-- --> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: cc84edb4-2bc3-4cfb-81af-8c1922ce58d8
Add DOTNET_JitCastMaxTypeChecks, defaulting to 3, for profiled and enumerated cast candidates. Keep virtual-call guarded devirtualization on its existing independent budget. Clamp conditional edge likelihoods to one so floating-point roundoff cannot cause an assertion when several cast candidates cover 100% of the profile. <!-- --> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: cc84edb4-2bc3-4cfb-81af-8c1922ce58d8
|
Azure Pipelines: Successfully started running 5 pipeline(s). 11 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
This comment was marked as outdated.
This comment was marked as outdated.
|
@EgorBot -arm -amd using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
BenchmarkSwitcher.FromAssembly(typeof(CastBench).Assembly).Run(args);
public class CastBench {
private readonly object[] _objects = [new B(), new C()];
[Benchmark(OperationsPerInvoke = 2)]
public int IsA() {
int count = 0;
foreach (object obj in _objects) {
if (obj is A) {
count++;
}
}
return count;
}
private class A { }
private sealed class B : A { }
private sealed class C : A { }
}Note This benchmark comment was composed with GitHub Copilot. |
|
PTAL @dotnet/jit-contrib @adamperlin A few improvements to cast expansion, enable multiple guessed by default. |
What is the size optimization that this is talking about? Checking three candidates inline does not sound like a size optimization to me - it is more code than a call to a cast helper. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 474803a8-11ce-496c-a351-ff85e990bedc
@jkotas oops, that was not intentional, although, e.g. 2 exact checks (no fallback) is not much bigger than just helper-call: https://godbolt.org/z/bcfqc6v5W (in case of NAOT we mostly talk about the non-fallbac get-exact-classes case only). Fixed. |
Use up to three compatible profiled runtime types when expanding
isinst/castclass, rather than only the first candidate. Guards sharing a result block must agree on returning the object or null, and multi-check expansions load the method table once. The general cast helper remains the fallback for unprofiled types.Add
DOTNET_JitCastMaxTypeChecks(default3) to control cast candidates independently of virtual-call GDV. NativeAOT'sgetExactClassesenumeration uses the same budget without relaxing its existing exactness checks; size-optimized NativeAOT casts consequently default to three candidates instead of one.Clamp normalized conditional edge likelihoods to avoid floating-point rounding assertions when candidate probabilities sum to 100%.