Skip to content

JIT clears the entire struct under SkipLocalsInit if it has gc fields, but doesn't have to. #129174

@EgorBo

Description

@EgorBo

From #129157 (comment)

using System;
using System.Runtime.CompilerServices;

[module: SkipLocalsInit]

public class Prog
{
    static void Test(string str)
    {
        if (TryParse(str, out var ms)) 
            Console.WriteLine(ms.A);
    }

    struct MyStruct
    {
        public string X; // replace with long
        public long A;
        public long B;
        public long C;
        public long D;
        public long E;
        public long F;
        public long G;
        public long H;
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    static bool TryParse(string str, out MyStruct ms) => throw null;
}

Normally, under SkipLocalsInit, the JIT can omit zeroing for out parameters and it does that if it has no GC fields, once at least one GC field is there it clears the entire struct while it could only clear individual GC slots (e.g. when there are just a few of them in a large struct)

Godbolt link: https://godbolt.org/z/xMTcqn8EW

Metadata

Metadata

Assignees

Labels

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

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions