Skip to content

Throw helper methods that just construct exceptions get inlined #78300

@stephentoub

Description

@stephentoub

Repro:
SharpLab

#nullable disable
using System;
using System.Runtime.CompilerServices;

public class C {
    public void M1(int i) { if (i == 0) throw Create(); }
    public void M2(int i) { if (i == 0) throw CreateNoInlining(); }
    public void M3(int i) { if (i == 0) Throw(); }
    
    static FormatException Create() => new FormatException(SR.Test);
    
    [MethodImpl(MethodImplOptions.NoInlining)]
    static FormatException CreateNoInlining() => new FormatException(SR.Test);
    
    static void Throw() => throw new FormatException(SR.Test);
}

class SR
{
    public static string Test => "";
}

This produces:

C.M1(Int32)
    L0000: push rsi
    L0001: sub rsp, 0x20
    L0005: test edx, edx
    L0007: je short L000f
    L0009: add rsp, 0x20
    L000d: pop rsi
    L000e: ret
    L000f: mov rcx, 0x7ffce3d82f68
    L0019: call 0x00007ffd4376f130
    L001e: mov rsi, rax
    L0021: mov ecx, 1
    L0026: mov rdx, 0x7ffceffec060
    L0030: call 0x00007ffd43741ec0
    L0035: mov rdx, rax
    L0038: mov rcx, rsi
    L003b: mov rax, 0x7ffce3d91f30
    L0045: call qword ptr [rax]
    L0047: mov rcx, rsi
    L004a: call 0x00007ffd4369fb10
    L004f: int3

C.M2(Int32)
    L0000: sub rsp, 0x28
    L0004: test edx, edx
    L0006: je short L000d
    L0008: add rsp, 0x28
    L000c: ret
    L000d: call 0x00007ffcefff0060
    L0012: mov rcx, rax
    L0015: call 0x00007ffd4369fb10
    L001a: int3

C.M3(Int32)
    L0000: sub rsp, 0x28
    L0004: test edx, edx
    L0006: je short L000d
    L0008: add rsp, 0x28
    L000c: ret
    L000d: call 0x00007ffcefff0078
    L0012: int3

I'd have expected M1 and M2 to be identical, with the JIT deciding not to inline Create() as all it's doing is constructing the exception that's about to be thrown, but without the NoInlining, it does get inlined.

Metadata

Metadata

Assignees

Labels

area-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