Runtime: JIT debe reconocer un patrón de verificación de tipo popular

Creado en 3 nov. 2018  ·  3Comentarios  ·  Fuente: dotnet/runtime

Encontré el truco en @GrabYourPitchforks https://github.com/dotnet/coreclr/pull/20386
JIT podría reconocer el patrón y generar código optimizado para tipos sellados.
`` C #
[MethodImpl (MethodImplOptions.NoInlining)]
public static int Is (objeto obj)
{
si (obj es cadena str)
return 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
; ============================================================

Y para ahorrar rax sería bueno tener

cmp      qword ptr [rcx], 0x7FFE960AF500

en lugar de

mov      rax, 0x7FFE960AF500
cmp      qword ptr [rcx], rax

Comentario más útil

Es útil tener (y recordar) este tipo de ejemplos.

Por favor, no se retrase de informar cosas porque le preocupa informar algo ya conocido. A veces, las cosas de apariencia similar no son tan similares al final.

Todos 3 comentarios

Ésta es un área conocida para mejorar (consulte dotnet / runtime # 9117).

La mayoría de las instrucciones x64 no pueden manejar grandes operandos constantes literales, por lo que ve el mov; cmp como lo hace arriba.

La semana de los dups :)
Clausura.

Es útil tener (y recordar) este tipo de ejemplos.

Por favor, no se retrase de informar cosas porque le preocupa informar algo ya conocido. A veces, las cosas de apariencia similar no son tan similares al final.

¿Fue útil esta página
0 / 5 - 0 calificaciones