Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RyuJIT and static fields initialization in beforefieldinited types #4346

Closed
omariom opened this issue Jul 1, 2015 · 7 comments
Closed

RyuJIT and static fields initialization in beforefieldinited types #4346

omariom opened this issue Jul 1, 2015 · 7 comments
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Comments

@omariom
Copy link
Contributor

omariom commented Jul 1, 2015

I get used to that JIT normally calls static fields initializer on compiling a method where the static fields are used, so that when the method executes it can access the fields directly without checking if they've been initialized.

RyuJIT seems has changed how it deals with initialization of static fields in beforefieldinited types.

Test code:

class Program
{
    private static bool s_flag = true;

    static void Main(string[] args)
    {
        Test();
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    public static int Test()
    {
        return s_flag ? 0x33 : 0x66;
    }
}

Generated code:

G_M65206_IG01:
       4883EC28             sub      rsp, 40

G_M65206_IG02:
       48B978590774F87F0000 mov      rcx, 0x7FF874075978
       BA01000000           mov      edx, 1
       E8E8AE745F           call     CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE
       0FB605DB54EAFF       movzx    rax, byte  ptr [classVar[0x74075cc0]]
       85C0                 test     eax, eax
       750A                 jne      SHORT G_M65206_IG04
       B866000000           mov      eax, 102

G_M65206_IG03:
       4883C428             add      rsp, 40
       C3                   ret      

G_M65206_IG04:
       B833000000           mov      eax, 51

G_M65206_IG05:
       4883C428             add      rsp, 40
       C3                   ret      

Is it an intentional and permanent change?

@jkotas
Copy link
Member

jkotas commented Jul 4, 2015

It is intentional change to avoid differences in timing of static constructor invocations across different JIT versions, and between JIT and AOT configurations. These timing differences has been historically source of number of compatibility problems. The behavior is controlled by MethodDesc::RunCCTorAsIfNGenImageExists method.

@omariom
Copy link
Contributor Author

omariom commented Jul 4, 2015

But doesn't this change itself introduce another difference in timing?
Compared with .NET 4(.5.2).

@jkotas
Copy link
Member

jkotas commented Jul 4, 2015

Yes, it does. Our compatibility requirements between different runtimes (.NET Framework vs. CoreCLR) are not as high as compatibility requirements between versions of the same runtime (v1, v2, ...).

BTW: The new behavior is enabled under a set of quirks even for .NET 4.5.2.

@omariom
Copy link
Contributor Author

omariom commented Jul 5, 2015

@jkotas Does it all mean that in .NET 4.6 RTM static readonly fields of scalar types won't be treated as JIT time constants?

@jkotas
Copy link
Member

jkotas commented Jul 5, 2015

They should be still treated as JIT time constants in methods that are JITed after the static constructor has run.

@omariom
Copy link
Contributor Author

omariom commented Jul 5, 2015

Ahaaa.. Now I see..:eyes:

class Program
{
    private static bool s_flag = true;

    static void Main(string[] args)
    {
        FirstAccess();
        Test();
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    public static int FirstAccess()
    {
        return s_flag  ? 33 : 66;
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    public static int Test()
    {
        return s_flag  ? 33 : 66;
    }
}

Test method:

G_M65206_IG02:
       0FB6057354EAFF       movzx    rax, byte  ptr [classVar[0x755f5cc0]]
       85C0                 test     eax, eax
       7506                 jne      SHORT G_M65206_IG04
       B842000000           mov      eax, 66
G_M65206_IG03:
       C3                   ret      
G_M65206_IG04:
       B821000000           mov      eax, 33
G_M65206_IG05:
       C3                   ret  

The same method if s_flag is a readonly field:

G_M65206_IG02:
       B821000000           mov      eax, 33
G_M65206_IG03:
       C3                   ret 

@omariom
Copy link
Contributor Author

omariom commented Jul 5, 2015

:octocat: This case is not considered an issue any more (at least by me) and can officially be closed.

@omariom omariom closed this as completed Jul 5, 2015
@msftgits msftgits transferred this issue from dotnet/coreclr Jan 30, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Jan 5, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
None yet
Development

No branches or pull requests

2 participants