An Illustrated History of objc_msgSend

<<   Snow Leopard   |   index   |   Mavericks   >>

x86-64: Lion and Mountain Lion

Snow Leopard Lion, Mountain Lion
// 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                     
// 47 instruction bytes                                                   
_objc_msgSend:                                                            
                                                                          
                                                                          
        testq   %rdi, %rdi               if (self == nil)                 
        je      NIL                          return zero                  
        testb   $1, %dil                 if (self & 1 != 0)               
        jne     TAGGED                       goto tagged pointer handler  
        movq    (%rdi), %r11             class = self->isa                
        pushq   %rax                     save non-volatile register       
                                                                          
                                                                          
        movq    16(%r11), %r10           cache = class->cache             
                                                                          
                                                                          
        movl    %esi, %eax                                                
 LOOP:  andl    (%r10), %eax             index = _cmd & cache->mask       
        movq    16(%r10, %rax, 8), %r11  method = cache->buckets[index]   
        incl    %eax                     index++                          
        testq   %r11, %r11               if (method == nil)               
        je      MISS                         goto cache miss              
                                                                          
                                                                          
        cmpq    (%r11), %rsi             if (method->sel != _cmd)         
        jne     LOOP                         scan more                    
        popq    %rax                     restore saved register           
                                                                          
                                                                          
                                                                          
                                                                          
        jmpq    *16(%r11)                jump to method->imp              

Changes in Lion:

objc_msgSend was unchanged in Mountain Lion.

<<   Snow Leopard   |   index   |   Mavericks   >>