mulle-objc: removing superflous ifs
Continued from mulle-objc: a meta calling convention
Now that the three parameter message sending function has been introduced, lets try to milk some benefit out of it.
mulle-objcis conceptually based off the Apple/NeXT runtime, my apologies for ignoring the GNU-Runtimes in all these little expositions.
The current 64 bit Intel implementation of the Apple runtime
objc_msgSend starts like this:
libobjc.A.dylib`objc_msgSend: 0x7fff90ef9080: testq %rdi, %rdi 0x7fff90ef9083: je 0x7fff90ef90f8 0x7fff90ef9086: testb $0x1, %dil 0x7fff90ef908a: jne 0x7fff90ef910f
That is basically the nil check against self
if( ! self) return( self);
followed by a tagged pointer check
if( (intptr_t) self & 1) goto is_tagged_pointer;
These checks are always done. Tagged pointers and their merit may be discussed at a later time. Here I focus solely on the nil check, which very often is superflous.
Often self is known to be non-nil
Let’s see when and why it is superflous, by looking at a regular ObjC loop:
The compiler knows, that obj is non-nil, when it is calling
-doStuff, since it just checked for non-nilness in the while statement.
Because methods are now uniform, one can use a static inline function as a trampoline to the actual extern function. This is not possible without severe performance degradations in normal ObjC:
The optimizing compiler can now optimize the
! self check away. The result will be less overhead spent in message sending, since
mulle_objc_object_call_2 would not have this check. The expense is two additional instructions are inlined per method call, when the nil check can not be optimized away.
Generally all calls inside methods to self also should be optimizable, since self is (or should be) known to be non-nil.
Food for thought
- Maybe there is even more to inline ? :)
- How many method calls are actually in a typical program ?
- Can the compiler use different inlining strategies based on compiler flags ?
- What happens when an object is messaged again ?
Continue to mulle-objc: inlined messaging