Skip to content

Avoid boxing in flag enum checks by using bitwise tests#705

Merged
tannergooding merged 1 commit into
dotnet:mainfrom
tannergooding:avoid-hasflag-boxing
Jul 12, 2026
Merged

Avoid boxing in flag enum checks by using bitwise tests#705
tannergooding merged 1 commit into
dotnet:mainfrom
tannergooding:avoid-hasflag-boxing

Conversation

@tannergooding

Copy link
Copy Markdown
Member

Replace Enum.HasFlag with direct bitwise tests. HasFlag boxes both the enum value and the flag argument on every call. The configuration option getters are queried heavily during generation, so this shows up as ~14.7 MB (~5%) of allocations when profiling a real-world workload (the terrafx/terrafx.interop.windows d3d12 generation) under Tier0/JIT.

All of the affected flags are single-bit, so (value & flag) != 0 is exactly equivalent to HasFlag, and !x.HasFlag(f) becomes (x & f) == 0.


The JIT elides HasFlag boxing via an intrinsic once the getters tier up, and NativeAOT is optimized throughout -- so this is effectively a no-op for the shipped ClangSharpPInvokeGenerator tool and a win for local/JIT-hosted runs (tests, in-process generation, short-lived processes that never fully tier up).

Sites: the configuration option getters in PInvokeGeneratorConfiguration (the hot path), plus ValueDesc, PInvokeGenerator.VisitDecl, and the CLI Program.

Behavior-preserving; all 3706 tests pass with a 0-warning build.

Enum.HasFlag boxes both the enum value and the flag argument on every
call. The configuration option getters are queried heavily during
generation, so this shows up as ~14.7 MB (~5%) of allocations on the
terrafx d3d12 generation under Tier0/JIT.

Replace HasFlag with a direct bitwise test. All of the affected flags
are single-bit, so (value & flag) != 0 is exactly equivalent. The JIT
elides HasFlag boxing via an intrinsic once the getters tier up, and
NativeAOT is optimized throughout, so this is a no-op there and a win
for local/JIT-hosted runs.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@tannergooding
tannergooding merged commit faebe2d into dotnet:main Jul 12, 2026
14 checks passed
@tannergooding
tannergooding deleted the avoid-hasflag-boxing branch July 12, 2026 21:05
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