question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Incorrect JIT asm when accessing static fields

See original GitHub issue

Hi, I’ve noticed some weird behavior in the JIT asm window when using code that accesses static fields (both in non-generic and in generic classes). Consider this example:

public class C
{
    public static int M()
    {
        return Test.SomeField;
    }
}

public class Test
{
    public static int SomeField;
}

This results in the following x64 asm:

C.M()
    L0000: sub rsp, 0x28
    L0004: mov rcx, 0x7ffb3056cb40
    L000e: xor edx, edx
    L0010: call 0x7ffb8827d930
    L0015: mov eax, [rax+0x8]
    L0018: add rsp, 0x28
    L001c: ret

I’m not really sure how is sharplab producing that, but it doesn’t seem correct. What is all that code doing, and why is there even a function call? As far as I know, static fields just have a static address in memory once the type is JITted, and in fact using a Release x64 build in Visual Studio and showing the disassembly from there shows this:

; return Test<int>.SomeField;
00007FFF99AC1642  mov         ebp,esp  
00007FFF99AC1644  mov         eax,dword ptr [7FFF99B84E80h]  
00007FFF99AC164A  pop         rbp  
00007FFF99AC164B  ret  

Now of course the prologue/epilogue wouldn’t be there in an actual Release build with the method being inlined, but still, the field here is effectively just read with a single mov instruction, as expected. Why is the output in sharplab so different in this case?

Here is another sharplab.io test with also a generic class with a static field.

Thank you for your time! 😄

Note: possibly related to #197 and #384?

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
Sergio0694commented, Apr 14, 2020

Hey @ashmind - no problem! Also commented in one related issue citing this particular case, it case it helps. And sure, I’ll close this issue and we can continue in just #445 since those are related. Thank you for your time! 😄

1reaction
Blufordscommented, Mar 30, 2020

Appears to be caused by making the assembly unloadable in the AssemblyLoadContext.

Assembly I get with it disabled:

    L0000: push rbp
    L0001: mov rbp, rsp
    L0004: mov rax, 0x7f5f6ec408ac
    L000e: mov eax, [rax]
    L0010: pop rbp
    L0011: ret

Also, tiered compilation appears to impact the JIT without it. Disabling tiered compilation(COMPlus_TieredCompilation=0) now gives this assembly output:

    L0000: nop [rax+rax]
    L0005: mov rax, 0x7f5dca29906c
    L000f: mov eax, [rax]
    L0011: ret

This likely isn’t a good fix(I don’t really know anything about .NET core’s internals) but I hope it points you guys in the right direction.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Static field access in collectible dynamic assemblies lacks ...
One would be to take care of static variable storage yourself, a class with instance fields. No problem getting those collected.
Read more >
Consider expanding JIT Asm support · Issue #384
Currently the JIT Asm results target only targets Desktop CLR and does not let you ... Incorrect JIT asm when accessing static fields...
Read more >
CA1810: Initialize reference type static fields inline
When a type declares an explicit static constructor, the just-in-time (JIT) compiler adds a check to each static method and instance ...
Read more >
Static single-assignment form
In compiler design, static single assignment form is a property of an intermediate representation (IR) that requires each variable to be assigned exactly ......
Read more >
Burst User Guide | Burst | 1.2.3
Burst has basic support for accessing static readonly data, but if you want to share static mutable data between C# and HPC#, you...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found