6 ms·
Objc_msgSend(), instruction by instruction
- 0x0 15y agoWould be interesting to see an updated writeup with focus on iOS on ARM.
- pmjordan 15y agoHere's the disassembly for objc_msgSend on ARMv6, iOS4.2.1 (sorry no ARMv7 devices on my desk at the moment). I'll try to annotate it: 0x32d98f0c <objc_msgSend+0>: teq r0, #0 ; 0x0 0x32d98f10 <objc_msgSend+4>: moveq r1, #0 ; 0x0 0x32d98f14 <objc_msgSend+8>: bxeq lr Tests if r0 (the receiver) is nil, and if so, sets r1 selector to 0x0 and returns. I guess there's no nil handler on ARM. Simple function return values are in registers r0-r3, so I guess r1 is set to 0 in case the caller is expecting a long long. If receiver is non-nil: 0x32d98f18 <objc_msgSend+12>: push {r3, r4, r5, r6} 0x32d98f1c <objc_msgSend+16>: ldr r4, [r0] ^ this loads the class pointer (isa) into r4 This looks similar to the bit twiddling x86 cache lookup in the class; it's somewhat harder to read than the x86 due to ARM's bit packing shortcuts[1]: 0x32d98f20 <objc_msgSend+20>: ldr r5, [r4, #8] 0x32d98f24 <objc_msgSend+24>: ldr r6, [r5] 0x32d98f28 <objc_msgSend+28>: add r3, r5, #8 ; 0x8 0x32d98f2c <objc_msgSend+32>: and r5, r6, r1, lsr #2 0x32d98f30 <objc_msgSend+36>: ldr r4, [r3, r5, lsl #2] Check if the method is NULL, and if so, jump to the cache miss at the end: 0x32d98f34 <objc_msgSend+40>: teq r4, #0 ; 0x0 0x32d98f38 <objc_msgSend+44>: add r5, r5, #1 ; 0x1 0x32d98f3c <objc_msgSend+48>: beq 0x32d98f60 <objc_msgSend+84> This would appear to be the part checking if this is the cache entry we're looking for: 0x32d98f40 <objc_msgSend+52>: ldr r12, [r4] 0x32d98f44 <objc_msgSend+56>: teq r1, r12 0x32d98f48 <objc_msgSend+60>: and r5, r5, r6 If it isn't, loop: 0x32d98f4c <objc_msgSend+64>: bne 0x32d98f30 <objc_msgSend+36> If it is, restore the registers and do an indirect jump into the method we found (I'm not sure what the teq r4,r4 is for): 0x32d98f50 <objc_msgSend+68>: ldr r12, [r4, #8] 0x32d98f54 <objc_msgSend+72>: teq r4, r4 0x32d98f58 <objc_msgSend+76>: pop {r3, r4, r5, r6} 0x32d98f5c <objc_msgSend+80>: bx r12 Tail call into the slow version with full lookup (after restoring the clobbered registers and the stack pointer): 0x32d98f60 <objc_msgSend+84>: pop {r3, r4, r5, r6} 0x32d98f64 <objc_msgSend+88>: b 0x32d98f68 <objc_msgSend_uncached> [1] A lazy excuse of course. I just haven't read or written anywhere near as much ARM assembly as x86.
- 0xced 15y agoThe source code of the Objective-C runtime is actually open source. See http://opensource.apple.com/source/objc4/objc4-493.11/runtime/Messengers.subproj/objc-msg-arm.s http://opensource.apple.com/source/objc4/objc4-493.11/runtim... for another commented version of objc_msgSend on ARM.
- pmjordan 15y agoAh, indeed. I checked the iOS section of opensource.apple.com and didn't find it there and falsely assumed that meant the ARM version was proprietary.
- losethos 15y agoGod says... C:\LoseThos\www.losethos.com\text\BIBLE.TXT t all clean. 13:12 So after he had washed their feet, and had taken his garments, and was set down again, he said unto them, Know ye what I have done to you? 13:13 Ye call me Master and Lord: and ye say well; for so I am. 13:14 If I then, your Lord and Master, have washed your feet; ye also ought to wash one another's feet. 13:15 For I have given you an example, that ye should do as I have done to you. 13:16 Verily, verily, I say unto you, The servant is not greater than his lord; neithe