blog
recent
archive
twitter

projects
Mac OS X
Keyboard
  backlight
CSC Menu
Valgrind
Fringe Player
pssh
Peal
Frankenmouse

   

Hamster Emporium archive

<<   [objc explain]: return value of message to nil   |   archive   |   Dr. Gregory Parker, Department of Diagnostic Engineering   >>

(link) [objc explain]: objc_msgSend_vtable   (2011-06-17 4:42 PM)
 

objc_msgSend_vtable is a version of objc_msgSend used to optimize a few of the most commonly called methods.

Most Objective-C methods are dispatched using a hash table lookup inside objc_msgSend. On x86_64, a few selectors can be dispatched using a C++-style virtual table: an array lookup, not a hash table.

The compiler knows which selectors are optimized by the runtime. It compiles the call site differently, calling objc_msgSend_fixup via a function pointer. At runtime, objc_msgSend_fixup replaces the function pointer with one of the objc_msgSend_vtable functions, if the called selector is one of the optimized selectors.

C++ vtables are notoriously fragile: the array offsets for each virtual method are hardcoded into the generated code. Objective-C's vtables are not fragile. Each vtable is built at runtime and updated when method lists change. In theory even the set of optimized methods could be changed. The non-fragile flexibility costs an extra memory load during dispatch.

Dispatch via vtable is faster than a hash table, but would consume tremendous amounts of memory if used everywhere. Objective-C's vtable implementation limits its use to a few selectors that are (1) implemented everywhere, but (2) rarely overridden. That means most classes share their superclass's vtable, which keeps memory costs low.

A crash in any objc_msgSend_vtable function should be debugged exactly like a crash in objc_msgSend itself. They both crash for all of the same reasons, like incorrect memory management or memory smashers.

Currently, the runtime uses sixteen different objc_msgSend_vtable functions, one for each slot in the sixteen-entry vtable.

objc_msgSend_vtable0allocWithZone:
objc_msgSend_vtable1alloc
objc_msgSend_vtable2class
objc_msgSend_vtable3self
objc_msgSend_vtable4isKindOfClass:
objc_msgSend_vtable5respondsToSelector:
objc_msgSend_vtable6isFlipped
objc_msgSend_vtable7length
objc_msgSend_vtable8objectForKey:
objc_msgSend_vtable9count
objc_msgSend_vtable10objectAtIndex:
objc_msgSend_vtable11isEqualToString:
objc_msgSend_vtable12isEqual:
objc_msgSend_vtable13retain (non-GC)
hash (GC)
objc_msgSend_vtable14release (non-GC)
addObject: (GC)
objc_msgSend_vtable15autorelease (non-GC)
countByEnumeratingWithState:objects:count: (GC)

The vtable's contents differ for GC and non-GC, for obvious reasons. -isFlipped is part of NSView. -countByEnumeratingWithState:objects:count: is the fast enumeration implementation, including for (x in y). Together these methods make up roughly 30-50% of calls in typical Objective-C applications.


seal! Greg Parker
gparker-web@sealiesoftware.com
Sealie Software