An Illustrated History of objc_msgSend

<<   Jaguar   |   index   |   Tiger   >>

PowerPC: Panther

Jaguar Panther
_objc_msgSend:                                                     
        cmplwi r3,  0         if (self == nil)                     
        beq    NIL                return zero                      
        stw    r9,  48(r1)    save non-volatile registers          
        stw    r10, 52(r1)                                         
        lwz    r12, 0(r3)     class = self->isa                    
        lwz    r12, 32(r12)   cache = class->cache                 
                                                                   
                                                                   
        lwz    r11, 0(r12)    mask = cache->mask                   
        addi   r9,  r12, 8    buckets = cache->buckets             
        slwi   r11, r11, 2                                         
        and    r12, r4,  r11  offset = (_cmd * 4) & mask           
 LOOP:  lwzx   r10, r9,  r12  method = buckets[offset]             
        addi   r12, r12, 4    offset += 4                          
        cmplwi r10, 0         if (method == nil)                   
        beq    MISS               goto cache miss                  
        lwz    r0,  0(r10)    sel = method->sel                    
        and    r12, r12, r11  offset &= mask                       
        cmplw  r0,  r4        if (sel != _cmd)                     
        bne    LOOP               scan more                        
        lwz    r10, 8(r10)    imp = method->imp                    
        mr     r12, r10       r12 = imp                            
        mtctr  r10            ctr = imp                            
        lwz    r9,  48(r1)    restore saved registers              
        lwz    r10, 52(r1)                                         
        li     r11, 0         set non-struct return for forwarding 
        bctr                  jump to imp                          
_objc_msgSend:                                                     
        cmplwi r3,  0         if (self == nil)                     
        beq    NIL                return zero                      
                                                                   
                                                                   
        lwz    r12, 0(r3)     class = self->isa                    
        lwz    r12, 32(r12)   cache = class->cache                 
        stw    r9,  48(r1)    save non-volatile registers          
                                                                   
        lwz    r11, 0(r12)    mask = cache->mask                   
        addi   r9,  r12, 8    buckets = cache->buckets             
        slwi   r11, r11, 2                                         
        and    r12, r4,  r11  offset = (_cmd * 4) & mask           
 LOOP:  lwzx   r2,  r9,  r12  method = buckets[offset]             
        addi   r12, r12, 4    offset += 4                          
        cmplwi r2,  0         if (method == nil)                   
        beq    MISS               goto cache miss                  
        lwz    r0,  0(r2)     sel = method->sel                    
        and    r12, r12, r11  offset &= mask                       
        cmplw  r0,  r4        if (sel != _cmd)                     
        bne    LOOP               scan more                        
        lwz    r12, 8(r2)     imp = method->imp                    
                                                                   
        mtctr  r12            ctr = imp                            
        lwz    r9,  48(r1)    restore saved registers              
                                                                   
                                                                   
        bctr                  jump to imp                          

Changes in Panther:

<<   Jaguar   |   index   |   Tiger   >>