Skip to content

Instantly share code, notes, and snippets.

@WhiteBlackGoose
Last active September 2, 2021 09:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save WhiteBlackGoose/5c567281c0b6bbac816ae0d48607ccba to your computer and use it in GitHub Desktop.
Save WhiteBlackGoose/5c567281c0b6bbac816ae0d48607ccba to your computer and use it in GitHub Desktop.
Windows and Linux codegen differemce

Linux:

; Benchmarks.ForeachWithRangeEnumeratorRaw()
       push      rbp
       push      rbx
       sub       rsp,18
       lea       rbp,[rsp+20]
       xor       ebx,ebx
       mov       edi,[rdi+8]
       dec       edi
       test      edi,edi
       jl        short M00_L02
       mov       [rbp-20],ebx
       mov       [rbp-1C],edi
       mov       rdi,[rbp-20]
       call      Library.Extensions.GetEnumerator(System.Range)
       mov       [rbp-18],rax
       mov       [rbp-10],edx
       mov       eax,[rbp-18]
       mov       edi,[rbp-14]
       mov       esi,[rbp-10]
       add       esi,edi
       cmp       esi,eax
       je        short M00_L01
       nop       dword ptr [rax+rax]
       
       
; No local function - Linux' JIT used registers for the struct
M00_L00:
       add       ebx,esi
       add       esi,edi
       cmp       esi,eax
       jne       short M00_L00
       
       
M00_L01:
       mov       eax,ebx
       add       rsp,18
       pop       rbx
       pop       rbp
       ret
M00_L02:
       call      System.ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException()
       int       3
; Total bytes of code 87

Windows:

; Benchmarks.ForeachWithRangeEnumeratorRaw()
       push      rsi
       sub       rsp,40
       xor       eax,eax
       mov       [rsp+30],rax
       mov       [rsp+38],rax
       xor       esi,esi
       mov       edx,[rcx+8]
       dec       edx
       test      edx,edx
       jl        short M00_L02
       mov       [rsp+28],esi
       mov       [rsp+2C],edx
       mov       rdx,[rsp+28]
       lea       rcx,[rsp+30]
       call      Library.Extensions.GetEnumerator(System.Range)
       mov       eax,[rsp+38]
       add       eax,[rsp+34]
       mov       [rsp+38],eax
       mov       eax,[rsp+38]
       cmp       eax,[rsp+30]
       je        short M00_L01
       nop       dword ptr [rax]
       
       
; Windows' JIT kept the struct on stack
M00_L00:
       add       esi,[rsp+38]
       mov       eax,[rsp+38]
       add       eax,[rsp+34]
       mov       [rsp+38],eax
       mov       eax,[rsp+38]
       cmp       eax,[rsp+30]
       jne       short M00_L00
       
       
M00_L01:
       mov       eax,esi
       add       rsp,40
       pop       rsi
       ret
M00_L02:
       call      System.ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException()
       int       3
; Total bytes of code 120

Linux:

; Benchmarks.ForeachWithRangeEnumeratorRawWithLocal()
       push      rbp
       sub       rsp,20
       lea       rbp,[rsp+20]
       mov       edi,[rdi+8]
       dec       edi
       test      edi,edi
       jl        short M00_L00
       xor       eax,eax
       mov       [rbp-18],eax
       mov       [rbp-14],edi
       mov       rdi,[rbp-18]
       call      Library.Extensions.GetEnumerator(System.Range)
       mov       [rbp-10],rax
       mov       [rbp-8],edx
       mov       rdi,[rbp-10]
       mov       esi,[rbp-8]
       add       rsp,20
       pop       rbp
       
       
; Linux' JIT uses jmp instead of call
       jmp       near ptr Benchmarks.<ForeachWithRangeEnumeratorRawWithLocal>g__EnumerateItAll|14_0(Library.RangeEnumerator)
       
       
M00_L00:
       call      System.ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException()
       int       3
; Total bytes of code 66
; Benchmarks.<ForeachWithRangeEnumeratorRawWithLocal>g__EnumerateItAll|14_0(Library.RangeEnumerator)
       push      rbp
       sub       rsp,10
       lea       rbp,[rsp+10]
       mov       [rbp-10],rdi
       mov       [rbp-8],esi
       xor       eax,eax
       mov       edi,[rbp-8]
       add       edi,[rbp-0C]
       mov       [rbp-8],edi
       mov       esi,[rbp-10]
       cmp       edi,esi
       je        short M02_L01
       
       
; Linux' JIT uses stack for the struct in the local function
M02_L00:
       mov       edi,[rbp-8]
       add       eax,edi
       add       edi,[rbp-0C]
       mov       [rbp-8],edi
       cmp       edi,esi
       jne       short M02_L00
       
       
M02_L01:
       add       rsp,10
       pop       rbp
       ret
; Total bytes of code 56

Windows:

; Benchmarks.ForeachWithRangeEnumeratorRawWithLocal()
       sub       rsp,48
       mov       edx,[rcx+8]
       dec       edx
       test      edx,edx
       jl        short M00_L00
       xor       ecx,ecx
       mov       [rsp+30],ecx
       mov       [rsp+34],edx
       mov       rdx,[rsp+30]
       lea       rcx,[rsp+38]
       call      Library.Extensions.GetEnumerator(System.Range)
       mov       rcx,[rsp+38]
       mov       [rsp+20],rcx
       mov       ecx,[rsp+40]
       mov       [rsp+28],ecx
       lea       rcx,[rsp+20]
       
       
; Windows' JIT preferred call
       call      Benchmarks.<ForeachWithRangeEnumeratorRawWithLocal>g__EnumerateItAll|14_0(Library.RangeEnumerator)
       
       
       nop
       add       rsp,48
       ret
M00_L00:
       call      System.ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException()
       int       3
; Total bytes of code 78
; Benchmarks.<ForeachWithRangeEnumeratorRawWithLocal>g__EnumerateItAll|14_0(Library.RangeEnumerator)
       mov       eax,[rcx]
       mov       edx,[rcx+4]
       mov       ecx,[rcx+8]
       xor       r8d,r8d
       add       ecx,edx
       cmp       ecx,eax
       je        short M02_L01
       
       
; Windows' JIT managed to use registers for the struct
M02_L00:
       add       r8d,ecx
       add       ecx,edx
       cmp       ecx,eax
       jne       short M02_L00
       
       
M02_L01:
       mov       eax,r8d
       ret
; Total bytes of code 30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment