An Illustrated History of objc_msgSend

<<   Leopard   |   index   |   Lion   >>

x86-64: Snow Leopard

Leopard Snow Leopard
// 107 instruction bytes                                               
_objc_msgSend:                                                         
        cmpq    $0xfffffffffffeb010, %rsi  if (_cmd is ignored)        
        je      IGNORED                        return self             
        testq   %rdi, %rdi                 if (self == nil)            
        je      NIL                            return zero             
        movq    (%rdi), %r11               class = self->isa           
        movq    %rcx, -32(%rsp)            save non-volatile registers 
        movq    %r8,  -24(%rsp)                                        
        movq    %r9,  -16(%rsp)                                        
        movq    16(%r11), %rcx             cache = class->cache        
        leaq    8(%rcx), %r8               buckets = cache->buckets    
        movl    (%rcx), %r9d               mask = cache->mask          
        shlq    $3, %r9                    mask *= 8                   
        movq    %rsi, %rcx                                             
        andq    %r9,  %rcx                 offset = _cmd & mask        
 LOOP:  movq    (%r8, %rcx), %r11          method = buckets[index]     
        testq   %r11, %r11                 if (method == nil)          
        je      MISS                           goto cache miss         
        addq    $8, %rcx                   offset += 8                 
        andq    %r9,  %rcx                 offset &= mask              
        cmpq    (%r11), %rsi               if (method->sel != _cmd)    
        jne     LOOP                           scan more               
        movq    -32(%rsp), %rcx            restore saved registers     
        movq    -24(%rsp), %r8                                         
        movq    -16(%rsp), %r9                                         
        movq    16(%r11), %r11             imp = method->imp           
                                                                       
        jmpq    *%r11                      jump to imp                 
// 104 instruction bytes                                                   
_objc_msgSend:                                                             
        cmpq    $0xfffffffffffeb010, %rsi  if (_cmd is ignored)            
        je      IGNORED                        return self                 
        testq   %rdi, %rdi                 if (self == nil)                
        je      NIL                            return zero                 
        movq    (%rdi), %r11               class = self->isa               
        movq    %rcx, -32(%rsp)            save non-volatile registers     
        movq    %r8,  -24(%rsp)                                            
        movq    %r9,  -16(%rsp)                                            
        movq    16(%r11), %r8              cache = class->cache            
                                                                           
        movl    (%r8), %r9d                mask = cache->mask              
        shlq    $3, %r9                    mask *= 8                       
        movq    %rsi, %rcx                                                 
        andq    %r9,  %rcx                 offset = _cmd & mask            
 LOOP:  movq    16(%r8, %rcx), %r11        method = cache->buckets[offset] 
        testq   %r11, %r11                 if (method == nil)              
        je      MISS                           goto cache miss             
        addq    $8, %rcx                   offset += 8                     
        andq    %r9,  %rcx                 offset &= mask                  
        cmpq    (%r11), %rsi               if (method->sel != _cmd)        
        jne     LOOP                           scan more                   
        movq    -32(%rsp), %rcx            restore saved registers         
        movq    -24(%rsp), %r8                                             
        movq    -16(%rsp), %r9                                             
        movq    16(%r11), %r11             imp = method->imp               
        cmpq    %r11, %r11                 set non-struct for forwarding   
        jmpq    *%r11                      jump to imp                     

Changes in Snow Leopard:

<<   Leopard   |   index   |   Lion   >>