An Illustrated History of objc_msgSend

<<   Lion   |   index

x86-64: Mavericks

Lion, Mountain Lion Mavericks
// 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               _cmd                             
 LOOP:  andl    (%r10), %eax             index = cache->mask & _cmd       
        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              
// 44 instruction bytes                                                  
_objc_msgSend:                                                           
        testq   %rdi, %rdi       if (self == nil)                        
        je,pn   NIL                  return zero                         
        testb   $1, %dil         if (self & 1 != 0)                      
        jne,pn  TAGGED               goto tagged pointer handler         
        movq    (%rdi), %r11     class = self->isa                       
                                                                         
                                                                         
        movq    %rsi, %r10       _cmd                                    
        andl    24(%r11), %r10d  index = class->cache_mask & _cmd        
        shlq    $4, %r10         offset = index * 16                     
        addq    16(%r11), %r10   bucket = class->cache_buckets + offset  
                                                                         
                                                                         
        cmpq    (%r10), %rsi     if (bucket->sel != _cmd)                
        jne     LOOP                 scan more                           
                                                                         
        jmpq    *8(%r10)         jump to bucket->imp                     

Changes in Mavericks:

<<   Lion   |   index