objc_msgSend() Tour Part 2: Setting the Stage

Table of Contents

  1. objc_msgSend() Tour Part 1: The Road Map
  2. objc_msgSend() Tour Part 2: Setting the Stage
  3. objc_msgSend() Tour Part 3: The Fast Path
  4. objc_msgSend() Tour Part 4: Method Lookup & Some Odds and Ends

Objective-C is, ultimately, a simple set of extensions to C that provide an object oriented coding and runtime model. Objective-C fully embraces C and leverages the C calling ABI throughout. Every method call is really just a C function call with objc_msgSend() acting as the preamble that figures out exactly which C function — which method — to call!

Thus, it is helpful to understand how objc_msgSend() is called and how that relates to C. That is, how does the compiler translate [someObject doSomething: 0x2a] into a call.

What follows is a bit of code that makes a [totally bogus] simple method call followed by the assembly generated.

Code:
@interface NSObject(foo)
- (id) doSomething: (NSUInteger) index;
@end
...
    NSObject *b;
    NSArray *a;
    b = [a doSomething: 0x2a]; // line 11
Assembly:
    .loc 1 11 0
    movq	-16(%rbp), %rdi
    movq	L_OBJC_SELECTOR_REFERENCES_0(%rip), %rsi
    movl	$42, %edx
    call	_objc_msgSend
    movq	%rax, -8(%rbp)

If you went and poked about in the x86_64 ABI specification (either of those links will work), you would recognize the above as code that sets up a call to a function — to _objc_msgSend() — and then stores the return value a local variable.

That is, objc_msgSend() and, by inference of being tail call optimized and not screwing with registers or stack layout, the method implementations themselves are just standard C functions that follow standard C ABI conventions.

Or, to put it another way, any method can be rewritten as an equivalent C function. The equivalent C function for the doSomething: method above could be declared as:

id doSomething(id self, SEL _cmd, NSUInteger index) { ... }

And, sure enough, if we call that function, we get functionally equivalent assembly code generated:

    b = doSomething(a, @selector(doSomething:), 0x2b); // line 16
    .loc 1 16 0
    movq	L_OBJC_SELECTOR_REFERENCES_0(%rip), %rsi
    movq	-16(%rbp), %rdi
    movl	$43, %edx
    call	_doSomething
    movq	%rax, -8(%rbp)

In particular, on the x86_64 architecture for this particular simple function or method call, the arguments (again, this is only for a simple set of non-struct arguments and return values) will fall into a series of registers in the CPU across the call boundary.

Specifically, the self parameter will be found in %rdi, _cmd in %rsi, and the first declared argument in %edx, followed by %ecx, %r8d, %r9d, and then arguments are pushed onto the stack. Once again, this assumes that the arguments are all of simple type — integers, ids, pointers, etc… — and the rules change with structures and other non-trivial types. Actually, this is another good reason for objc_msgSend to not mess with the stack and registers as the ABI rules are both rather complex and there simply isn’t enough information available at runtime to go off changing argumentation across the messaging boundary (much less do so efficiently)!

We now have enough information to know what state the CPU is in when the call to objc_msgSend() is made. Next up will be the most typical method dispatch.



4 Responses to “objc_msgSend() Tour Part 2: Setting the Stage”

  1. bbum’s weblog-o-mat » Blog Archive » objc_msgSend() Tour Part 1: The Road Map says:

    [...] 2.5 License. Amazon.com Widgets « DE Razor Review: BIC Chrome Platinum objc_msgSend() Tour Part 2: Setting the Stage [...]

  2. bbum's weblog-o-mat » Blog Archive » objc_msgSend() Tour Part 3: The Fast Path says:

    [...] Commons Attribution-NonCommercial-ShareAlike 2.5 License. Amazon.com Widgets « objc_msgSend() Tour Part 2: Setting the Stage DE Razor Review: Dorco New Platinum ST-301 [...]

  3. bbum's weblog-o-mat » Blog Archive » objc_msgSend() Tour Part 4: Method Lookup & Some Odds and Ends says:

    [...] objc_msgSend() Tour Part 2: Setting the Stage [...]

  4. Kaitlin Duck Sherwood says:

    What is cmd? I do not see a cmd in doSomething:. Or is cmd just a holder for the selector “doSomething:”, and the C pseudo-method could be called anything, e.g.
    id blortfrobnotz(id self, SEL _cmd, NSUInteger index) { … }

Leave a Reply

Line and paragraph breaks automatic.
XHTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>