@GrabYourPitchforks https://github.com/dotnet/coreclr/pull/20386 ์์ ํธ๋ฆญ์ ์ฐพ์์ต๋๋ค.
JIT๋ ํจํด์ ์ธ์ํ๊ณ ๋ด์ธ๋ ์ ํ์ ๋ํด ์ต์ ํ๋ ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
```C#
[MethodImpl(MethodImplOptions.NoInlining)]
public static int Is(๊ฐ์ฒด obj)
{
if (obj๋ ๋ฌธ์์ด str)
๋ฐํ str.Length;
return 7;
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static int As(object obj)
{
string str = obj as string;
if (str != null)
return str.Length;
return 7;
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static int SafeUnsafe(object obj)
{
if (obj != null && obj.GetType() == typeof(string))
return Unsafe.As<string>(obj).Length;
return 7;
}
<details><summary>See the generated code</summary><p>
```ASM
; Assembly listing for method Program:Is(ref):int
; Emitting BLENDED_CODE for X64 CPU with AVX
; optimized code
; rsp based frame
; partially interruptible
; Final local variable assignments
;
; V00 arg0 [V00,T01] ( 3, 3 ) ref -> rcx class-hnd
; V01 loc0 [V01,T02] ( 3, 2.50) ref -> rax class-hnd
;# V02 OutArgs [V02 ] ( 1, 1 ) lclBlk ( 0) [rsp+0x00]
; V03 tmp1 [V03,T00] ( 5, 6.74) ref -> rax class-hnd
;
; Lcl frame size = 0
G_M12761_IG01:
0F1F440000 nop
G_M12761_IG02:
488BC1 mov rax, rcx
4885C0 test rax, rax
7411 je SHORT G_M12761_IG03
48BA00F50A96FE7F0000 mov rdx, 0x7FFE960AF500
483910 cmp qword ptr [rax], rdx
7402 je SHORT G_M12761_IG03
33C0 xor rax, rax
G_M12761_IG03:
4885C0 test rax, rax
7404 je SHORT G_M12761_IG05
8B4008 mov eax, dword ptr [rax+8]
G_M12761_IG04:
C3 ret
G_M12761_IG05:
B807000000 mov eax, 7
G_M12761_IG06:
C3 ret
; Total bytes of code 45, prolog size 5 for method Program:Is(ref):int
; ============================================================
; Assembly listing for method Program:As(ref):int
; Emitting BLENDED_CODE for X64 CPU with AVX
; optimized code
; rsp based frame
; partially interruptible
; Final local variable assignments
;
; V00 arg0 [V00,T01] ( 3, 3 ) ref -> rcx class-hnd
; V01 loc0 [V01,T02] ( 3, 2.50) ref -> rax class-hnd
;# V02 OutArgs [V02 ] ( 1, 1 ) lclBlk ( 0) [rsp+0x00]
; V03 tmp1 [V03,T00] ( 5, 6.74) ref -> rax class-hnd
;
; Lcl frame size = 0
G_M12497_IG01:
0F1F440000 nop
G_M12497_IG02:
488BC1 mov rax, rcx
4885C0 test rax, rax
7411 je SHORT G_M12497_IG03
48BA00F50A96FE7F0000 mov rdx, 0x7FFE960AF500
483910 cmp qword ptr [rax], rdx
7402 je SHORT G_M12497_IG03
33C0 xor rax, rax
G_M12497_IG03:
4885C0 test rax, rax
7404 je SHORT G_M12497_IG05
8B4008 mov eax, dword ptr [rax+8]
G_M12497_IG04:
C3 ret
G_M12497_IG05:
B807000000 mov eax, 7
G_M12497_IG06:
C3 ret
; Total bytes of code 45, prolog size 5 for method Program:As(ref):int
; ============================================================
; Assembly listing for method Program:SafeUnsafe(ref):int
; Emitting BLENDED_CODE for X64 CPU with AVX
; optimized code
; rsp based frame
; partially interruptible
; Final local variable assignments
;
; V00 arg0 [V00,T00] ( 5, 4 ) ref -> rcx class-hnd
;# V01 OutArgs [V01 ] ( 1, 1 ) lclBlk ( 0) [rsp+0x00]
;
; Lcl frame size = 0
G_M6777_IG01:
0F1F440000 nop
G_M6777_IG02:
4885C9 test rcx, rcx
7413 je SHORT G_M6777_IG04
48B800F50A96FE7F0000 mov rax, 0x7FFE960AF500
483901 cmp qword ptr [rcx], rax
7504 jne SHORT G_M6777_IG04
8B4108 mov eax, dword ptr [rcx+8]
G_M6777_IG03:
C3 ret
G_M6777_IG04:
B807000000 mov eax, 7
G_M6777_IG05:
C3 ret
; Total bytes of code 35, prolog size 5 for method Program:SafeUnsafe(ref):int
; ============================================================
rax
๋ฅผ ์ ์ฝํ๋ ค๋ฉด
cmp qword ptr [rcx], 0x7FFE960AF500
๋์ ์
mov rax, 0x7FFE960AF500
cmp qword ptr [rcx], rax
์ด๊ฒ์ ๊ฐ์ ์ด ํ์ํ ๊ฒ์ผ๋ก ์๋ ค์ง ์์ญ์ ๋๋ค(dotnet/runtime#9117 ์ฐธ์กฐ).
๋๋ถ๋ถ์ x64 ๋ช
๋ น์ด๋ ํฐ ๋ฆฌํฐ๋ด ์์ ํผ์ฐ์ฐ์๋ฅผ ์ฒ๋ฆฌํ ์ ์์ผ๋ฏ๋ก ์์ ๊ฐ์ด mov; cmp
๊ฐ ํ์๋ฉ๋๋ค.
๋ฐ๋ณด๊ฐ์ ์ผ์ฃผ์ผ :)
ํ์.
์ด๋ฌํ ์ข ๋ฅ์ ์๋ฅผ ๊ฐ๋(๊ทธ๋ฆฌ๊ณ ์๊ธฐํ๋ ๊ฒ์ด) ์ ์ฉํฉ๋๋ค.
์ด๋ฏธ ์๋ ค์ง ๋ด์ฉ์ ์ ๊ณ ํ๋ ๊ฒ์ด ๊ฑฑ์ ๋๋ค๊ณ ํด์ ์ ๊ณ ๋ฅผ ๋ฏธ๋ฃจ์ง ๋ง์ธ์. ๋๋ก๋ ๋น์ทํด ๋ณด์ด๋ ๊ฒ๋ค์ด ๊ฒฐ๊ตญ ๋น์ทํ์ง ์์ต๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ด๋ฌํ ์ข ๋ฅ์ ์๋ฅผ ๊ฐ๋(๊ทธ๋ฆฌ๊ณ ์๊ธฐํ๋ ๊ฒ์ด) ์ ์ฉํฉ๋๋ค.
์ด๋ฏธ ์๋ ค์ง ๋ด์ฉ์ ์ ๊ณ ํ๋ ๊ฒ์ด ๊ฑฑ์ ๋๋ค๊ณ ํด์ ์ ๊ณ ๋ฅผ ๋ฏธ๋ฃจ์ง ๋ง์ธ์. ๋๋ก๋ ๋น์ทํด ๋ณด์ด๋ ๊ฒ๋ค์ด ๊ฒฐ๊ตญ ๋น์ทํ์ง ์์ต๋๋ค.