Skip to content

JIT: Explore assuming non-null reference-type this #134674

Description

@adamperlin

Motivation

We currently preserve null checks on the incoming reference-type this argument. For C#-produced IL, ordinary instance calls should always have a non-null receiver, so treating the incoming this value as non-null may remove the need for some null-check and exception-path code. The biggest savings are for Wasm, so the experiment below is Wasm-only.

This is not valid for arbitrary IL: an instance method can be invoked with a null receiver via call, and CoreCLR currently permits execution until the method dereferences that receiver. This issue proposes an opt-in experiment only, not a production semantic change.

Experiment (Wasm Only)

Add a JIT code-generation option that assigns the incoming reference-type this argument a distinct known-non-null initial value number during ReadyToRun compilation. Value-type instance methods, static methods, non-R2R compilation, and default behavior remain unchanged.

Measurements

Using an untrimmed browser-Wasm System.Private.CoreLib Release R2R build:

  • Managed code reported by the JIT: 16,306,053 → 15,761,992 bytes (-544,061 bytes, -3.34%)
  • Wasm Code section: 14,336,449 → 13,867,040 bytes (-469,409 bytes, -3.27%)
  • Whole R2R image: 28,693,727 → 28,219,792 bytes (-473,935 bytes, -1.65%)

One representative method, SafeFileHandle.get_IsInvalid, shrank from 124 to 42 bytes by removing the null-range check and CORINFO_HELP_THROWNULLREF path. Static and value-type instance controls remained byte-identical.

Open design questions

A production version would need an explicit runtime/toolchain guarantee that excludes null receiver invocation, or a checked entry mechanism that preserves arbitrary-IL behavior. The experimental option intentionally provides neither and should remain off by default.

If the guarantees were in place, this could potentially be enabled across targets

Note

This issue was created with GitHub Copilot.

Activity

  1. added
    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
    on Sep 25, 2026
  2. dotnet-policy-service commented on Sep 25, 2026

    @dotnet-policy-service
    Contributor

    Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
    See info in area-owners.md if you want to be subscribed.

  3. changed the title [-]Explore assuming non-null reference-type `this` for Wasm R2R[/-] [+]JIT: Explore assuming non-null reference-type `this` for Wasm R2R[/+] on Sep 25, 2026
  4. changed the title [-]JIT: Explore assuming non-null reference-type `this` for Wasm R2R[/-] [+]JIT: Explore assuming non-null reference-type `this`[/+] on Sep 25, 2026
  5. added this to the 12.0.0 milestone on Sep 25, 2026
  6. dotnet-policy-service commented on Sep 25, 2026

    @dotnet-policy-service
    Contributor

    Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
    See info in area-owners.md if you want to be subscribed.

  7. MichalPetryka commented on Sep 25, 2026

    @MichalPetryka
    Contributor

    We plan to use null this for delegates in #85014 but there this won't ever be accessed inside of the method in normal IL from Roslyn, so it'd be fine if this is specced as calling with null this is legal but accessing this in such case is UB.

    For non WASM I'd be more worried about cases of users using reflection instead of custom IL for calling methods with null this, as AFAIR there are multiple ways to achieve that there including for example open delegates.

    There might be code that relies on this due to the fact that calling instance methods is faster, so there could be users having instance methods called with null this for performance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions