<< Tiger PowerPC | index | Leopard >>
Tiger |
---|
_objc_msgSend: movl 0x4(%esp), %eax load self testl %eax, %eax if (self == nil) je NIL return zero movl (%eax), %eax class = self->isa movl 8(%esp), %ecx load _cmd pushl %edi save non-volatile register movl 32(%eax), %eax cache = class->cache pushl %esi save non-volatile register leal 8(%eax), %edi buckets = cache->buckets movl (%eax), %esi mask = cache->mask movl %ecx, %edx shrl $2, %edx index = _cmd * 4 LOOP: andl %esi, %edx index &= mask movl (%edi, %edx, 4), %eax method = buckets[index] testl %eax, %eax if (method == nil) je MISS goto cache miss cmpl (%eax), %ecx if (method->sel == _cmd) je HIT goto cache hit addl $1, %edx index++ jmp LOOP scan more [...] HIT: movl 8(%eax), %eax imp = method->imp popl %esi restore saved registers popl %edi movl $1, %edx set non-struct return for forwarding jmpl *%eax jump to imp |
Tiger introduced the 32-bit Intel architecture. This architecture was previously supported at NeXT, and the Mac OS X code was based on that implementation. The code was probably originally written for NeXT by an engineer who was familiar with load-store architectures like PowerPC but not so familiar with register-memory architectures like x86, and was later adapted to Mac OS X by someone who also did not know x86 well (/me raises his hand).
Those of you who do know x86 better may be able to identify some of the inefficiencies in this code. 32-bit x86 was quickly overtaken by 64-bit, so this code received little attention after Tiger and many of those inefficiencies remain to this day. We will not follow it further.
<< Tiger PowerPC | index | Leopard >>