An Illustrated History of objc_msgSend

<<   Tiger   |   index   |   Snow Leopard   >>

x86-64: Leopard

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                 

Leopard introduced 64-bit Intel. This implementation was structured in the same way as the PowerPC code, instead of being adapted directly from the 32-bit Intel code. The cache scanning loop in particular is structured like the PowerPC version rather than the i386 version. Like the i386 version, this code does not take advantage of the x86-64 instruction set's register-memory architecture.

<<   Tiger   |   index   |   Snow Leopard   >>