0

I have two dumps from production and both of them JIT the method System.ComponentModel.Composition.Hosting.CompositionLock.LockComposition from the System.ComponentModel.Composition.dll assembly like this:

0:146> !U /d 00007ffc93d72c10
Normal JIT generated code
System.ComponentModel.Composition.Hosting.CompositionLock.LockComposition()
Begin 00007ffc93d72c10, size 53
>>> 00007ffc`93d72c10 57              push    rdi
00007ffc`93d72c11 56              push    rsi
00007ffc`93d72c12 4883ec28        sub     rsp,28h
00007ffc`93d72c16 488bf1          mov     rsi,rcx
00007ffc`93d72c19 807e1400        cmp     byte ptr [rsi+14h],0
00007ffc`93d72c1d 7427            je      00007ffc`93d72c46
00007ffc`93d72c1f 48b9487a2f9cfc7f0000 mov rcx,7FFC9C2F7A48h (MT: System.ComponentModel.Composition.Hosting.CompositionLock+CompositionLockHolder)
00007ffc`93d72c29 e8e2f8ef54      call    clr!JIT_TrialAllocSFastMP_InlineGetThread (00007ffc`e8c72510)
00007ffc`93d72c2e 488bf8          mov     rdi,rax
00007ffc`93d72c31 488bcf          mov     rcx,rdi
00007ffc`93d72c34 488bd6          mov     rdx,rsi
00007ffc`93d72c37 e844e5ffff      call    00007ffc`93d71180 (System.ComponentModel.Composition.Hosting.CompositionLock+CompositionLockHolder..ctor(System.ComponentModel.Composition.Hosting.CompositionLock), mdToken: 000000000600061e)
00007ffc`93d72c3c 488bc7          mov     rax,rdi
00007ffc`93d72c3f 4883c428        add     rsp,28h
00007ffc`93d72c43 5e              pop     rsi
00007ffc`93d72c44 5f              pop     rdi
00007ffc`93d72c45 c3              ret
00007ffc`93d72c46 b977050000      mov     ecx,577h
00007ffc`93d72c4b ba61000000      mov     edx,61h
00007ffc`93d72c50 e80b00f054      call    clr!JIT_GetSharedGCStaticBase_InlineGetAppDomain (00007ffc`e8c72c60)
00007ffc`93d72c55 488b8038010000  mov     rax,qword ptr [rax+138h]
00007ffc`93d72c5c 4883c428        add     rsp,28h
00007ffc`93d72c60 5e              pop     rsi
00007ffc`93d72c61 5f              pop     rdi
00007ffc`93d72c62 c3              ret

The absolute memory addresses are different, of course, but other than that both dumps show exactly the same code.

When I inspect the same method in a locally running sample application, I get a very different code:

0:063> !U /d 00007ff93aa22e70
Normal JIT generated code
System.ComponentModel.Composition.Hosting.CompositionLock.LockComposition()
Begin 00007ff93aa22e70, size 7e
>>> 00007ff9`3aa22e70 57              push    rdi
00007ff9`3aa22e71 56              push    rsi
00007ff9`3aa22e72 53              push    rbx
00007ff9`3aa22e73 4883ec30        sub     rsp,30h
00007ff9`3aa22e77 488bf1          mov     rsi,rcx
00007ff9`3aa22e7a 400fb67e14      movzx   edi,byte ptr [rsi+14h]
00007ff9`3aa22e7f 85ff            test    edi,edi
00007ff9`3aa22e81 744d            je      00007ff9`3aa22ed0
00007ff9`3aa22e83 48b9f053b13af97f0000 mov rcx,7FF93AB153F0h (MT: System.ComponentModel.Composition.Hosting.CompositionLock+CompositionLockHolder)
00007ff9`3aa22e8d e81ed1a45e      call    clr!JIT_TrialAllocSFastMP_InlineGetThread (00007ff9`9946ffb0)
00007ff9`3aa22e92 488bd8          mov     rbx,rax
00007ff9`3aa22e95 488d4b08        lea     rcx,[rbx+8]
00007ff9`3aa22e99 488bd6          mov     rdx,rsi
00007ff9`3aa22e9c e8bfada45e      call    clr!JIT_WriteBarrier (00007ff9`9946dc60)
00007ff9`3aa22ea1 33c9            xor     ecx,ecx
00007ff9`3aa22ea3 894b10          mov     dword ptr [rbx+10h],ecx
00007ff9`3aa22ea6 85ff            test    edi,edi
00007ff9`3aa22ea8 741b            je      00007ff9`3aa22ec5
00007ff9`3aa22eaa b96b000000      mov     ecx,6Bh
00007ff9`3aa22eaf ba61000000      mov     edx,61h
00007ff9`3aa22eb4 e847d8a45e      call    clr!JIT_GetSharedGCStaticBase_InlineGetAppDomain (00007ff9`99470700)
00007ff9`3aa22eb9 488b8830010000  mov     rcx,qword ptr [rax+130h]
00007ff9`3aa22ec0 e88bd2a45e      call    clr!JIT_MonEnter (00007ff9`99470150)
00007ff9`3aa22ec5 488bc3          mov     rax,rbx
00007ff9`3aa22ec8 4883c430        add     rsp,30h
00007ff9`3aa22ecc 5b              pop     rbx
00007ff9`3aa22ecd 5e              pop     rsi
00007ff9`3aa22ece 5f              pop     rdi
00007ff9`3aa22ecf c3              ret
00007ff9`3aa22ed0 b96b000000      mov     ecx,6Bh
00007ff9`3aa22ed5 ba61000000      mov     edx,61h
00007ff9`3aa22eda e821d8a45e      call    clr!JIT_GetSharedGCStaticBase_InlineGetAppDomain (00007ff9`99470700)
00007ff9`3aa22edf 488b8038010000  mov     rax,qword ptr [rax+138h]
00007ff9`3aa22ee6 4883c430        add     rsp,30h
00007ff9`3aa22eea 5b              pop     rbx
00007ff9`3aa22eeb 5e              pop     rsi
00007ff9`3aa22eec 5f              pop     rdi
00007ff9`3aa22eed c3              ret

The file (not assembly) version of System.ComponentModel.Composition.dll on the production servers is 4.8.3761.0 and that of the local one is 4.8.9032.0 - slightly different, but according to IL Spy the code in question has not changed.

The C# code for the function is:

public IDisposable LockComposition()
{
    if (_isThreadSafe)
    {
        return new CompositionLockHolder(this);
    }
    return _EmptyLockHolder;
}

And it looks like the server did not inline the creation of CompositionLockHolder instance.

But the local code seems to have inlined it.

Here is more code from the same area:

public void SatisfyImportsOnce(ComposablePart part)
{
    ...
    using (_lock.LockComposition())
    {
        ...
    }
}
...
public CompositionLockHolder(CompositionLock @lock)
{
    _lock = @lock;
    _isDisposed = 0;
    _lock.EnterCompositionLock();
}
...
private void EnterCompositionLock()
{
    if (_isThreadSafe)
    {
        Monitor.Enter(_compositionLock);
    }
}

Can we instruct the local runtime to JIT the same way as the server?

3
  • which .net version? Commented Aug 22, 2024 at 0:53
  • Could you help me out here? Is there a particular WinDbg command you have in mind? Commented Aug 22, 2024 at 1:06
  • 1
    The code that determines inlining is here. Ought to be enough to convince you to look for another approach. Commented Aug 22, 2024 at 8:20

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.