Archive for the 'Apple' Category

objc_msgSend() Tour Part 3: The Fast Path

Friday, December 18th, 2009

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

In any case, with the foundation set — with the id of the object to be targeted in %rdi and the selector of the method to be invoked in %rsi — we can jump into objc_msgSend() and understand exactly what happens instruction by instruction. Or more specifically, the compiler issues a call into objc_msgSend() (which sets up a stackframe for objc_msgSend() which, through tail call optimization, turns into the stackframe for the called method) and the method implementation that objc_msgSend() jumps to will issue a ret instruction to unwind the stack back to the original caller’s frame.

It is pretty easy to correlate the disassembly with the comments and code in the original source file. However, if you ever need to step through the messenger (si steps by instruction in gdb), this will be easier to follow as this is closer to the reality during a debug session.

For almost all method dispatches, dispatch takes what is called the “fast path”. That is, objc_msgSend() finds the implementation in the method cache and passes control to the implementation. Since this is the most common path, it is a good opportunity to break the tour of objc_msgSend() into two parts; the fast path and the slow path (with administrivia).

Read the rest of this entry »

objc_msgSend() Tour Part 2: Setting the Stage

Friday, December 18th, 2009

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)

Read the rest of this entry »

objc_msgSend() Tour Part 1: The Road Map

Friday, December 18th, 2009

What follows (across this and 3 more posts, maybe more) is a rather detailed tour of objc_msgSend() as implemented in Mac OS X 10.6.2. Rather detailed in that every instruction will be explained. Even though it is relatively few instructions, there is a considerable amount of background information that is helpful to understanding the objc_msgSend() instruction stream.

The motivation behind these posts is entirely selfish. I find the best way for me to learn something is to know it well enough to be able to explain any detail to a room full of folks in full-blown student mode.

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

Read the rest of this entry »

DPhyllotaxis

Sunday, October 25th, 2009
Screenalicious - DPhyllotaxis - 200910298 205041.539.png

Ultimately, the whole point of resurrecting my old screensaver code was to finally port DPhyllotaxis to Snow Leopard.

Beyond being, perhaps, the most over-engineered screen saver ever for what ultimately draws colored dots, I wrote this as a sort of virtual flower for my then-girlfriend, now-wife-of-more-than-a-decade, Christine.

The underlying algorithm on this one is based entirely on phyllotaxis and the phyllotactic pattern of growth seen across so much of the plant world. The most well known example being the layout of seeds in a sunflower and that particular form of phyllotaxis is exactly what this screensaver mimics.

The color calculation in this particular screen saver is, frankly, goofy. Every floret — every dot — is actually rendered. The brightness is determined by calculating a color once, grabbing the red component and then calculating the color again using a slightly different algorithm and using the previous red value as the new brightness. Rather silly, but the results are pleasant enough.

Screenalicious - DPhyllotaxis - 200910298 205114.991.png

When I originally wrote this in 1994-ish, it used Display PostScript to do all the drawing. Specifically:

/* this should not be done here */
PSarc(cp.x, cp.y, 15. + (11. * pp.r), 0, 360);
PSgsave();
PSfill();
PSgrestore();
NXSetColor(NX_COLORBLACK);
PSstroke();

I have no idea why, 15 years ago, I thought it important to note that “this should not be done here”. None. So, in the ported code, the comment is gone.

CGFloat floretDiameter = 10. + (11. * pp.r);
CGFloat floretRadius = floretDiameter / 2.;
NSRect floretRect = 
    NSMakeRect(cp.x - floretRadius,
    cp.y - floretRadius,
    floretDiameter, floretDiameter);
NSBezierPath *floretPath = [NSBezierPath 
    bezierPathWithOvalInRect: floretRect];
        
[floretPath fill];
        
[[NSColor blackColor] set];
[floretPath stroke];

There are, of course, many ways to make the above a ton faster. Save for reducing power usage by going a more efficient route, it just doesn’t matter for this particular use case as I already had to slow down the animation rate considerably.

Seems there has been a bit of performance jump between the 25MHZ 68040 this was originally written on and the 2GHZ Core 2 Duo machine I used for the porting work.

Code is in the same repository as the other screen savers. I also tossed a pre-built binary on the server. Only tested on 64-bit Snow Leopard, but it might should also work on 10.5 ppc/i386.

+initialize Can Be Executed Multiple Times (+load not so much)

Sunday, September 6th, 2009

Some confusion on StackOverflow led to a massive string of comments. This is a question that comes up often, so here is some google fodder.

In Objective-C, a class can implement +initialize. This method will be invoked the first time the class is touched, prior to any other methods (other than +load).

The documentation says:

The runtime sends initialize to each class in a program exactly one time just before the class, or any class that inherits from it, is sent its first message from within the program.

Which is exactly true. But your +initialize methods can still be executed more than once!

Specifically, if a subclass does not implement +initialize but its superclass does, then that superclass’s +initialize will be invoked once per non-implementing subclass and once for itself.

An example (Foundation Tool, Garbage Collected):

@interface Abstract: NSObject
@end
@implementation Abstract
+ (void) initialize
{
    NSLog(@"Initializing %@", self);
}

+ (void) load
{
    NSLog(@"Loading");
}
@end

@interface Sub : Abstract
@end
@implementation Sub
@end

int main (int argc, const char * argv[]) {
    [Sub class];
    return 0;
}

This will output:

ArgyBargy[3720:903] Loading
ArgyBargy[3720:903] Initializing Abstract
ArgyBargy[3720:903] Initializing Sub

Which is why most +initialize methods are implemented as:

@implementation MyClass
+ (void) initialize
{
    if (self == [MyClass class]) {
        // ... do +init stuff here ...
    }
}
...
@end

Now, categories can seriously screw things up (as usual). Namely, if you implement +initialize in a category, it will override the classes +initialize. However, a category provided +load will not; both the category’s and the class’s +load methods will be invoked.

If you were to add the following category to the Sub/Abstract/NSObject example above:

@interface Abstract(Cat)
@end
@implementation Abstract(Cat)
+ (void) load
{
    NSLog(@"Category +load");
}
+ (void) initialize
{
    NSLog(@"Category +initialize %@", self);
}
@end

The program will spew:

ArgyBargy[3919:903] Loading
ArgyBargy[3919:903] Category +load
ArgyBargy[3919:903] Category +initialize Abstract
ArgyBargy[3919:903] Category +initialize Sub

Keep in mind, as well, that the runtime sends +initialize “in a thread-safe manner”. That implies that there is a lock involved somewhere within which then also implies that you better not block on a lock in your +initialize because whoever is supposed to unlock the lock might end up blocking on +initializes lock.

Or, to put it more bluntly, do not do any heavy lifting in +initialize. Keep it super simple & fast.

For me, +initialize is to be used only as a method of last resort. Well, 2nd to last. Last resort is a constructor attributed function (or +load). Read the rest of this entry »

Basic Blocks

Saturday, August 29th, 2009

Now that Snow Leopard has shipped, the Blocks Programming Topics is available from developer.apple.com. Go have a read; it is a great primer for Blocks.

This post is focused solely on the core syntax of Blocks; declaring a block and calling a block.

Blocks are closures for C.

That is, a block is an anonymous inline collection of code that (Note: lexical scope means function or method or {}-surrounded collection of statements:

  • has a typed argument list just like a function
  • has an inferred or declared return type
  • can capture state from the lexical scope within which it is defined
  • can optionally modify the state of the lexical scope
  • can share the potential for modification with other blocks defined within the same lexical scope
  • can continue to share and modify state defined within the lexical scope [the stack frame] after the lexical scope [the stack frame] has been destroyed

Blocks is available in GCC and Clang as shipped with the Snow Leopard Xcode developer tools. The Blocks runtime is open source and can be found within LLVM’s compiler-rt subproject repository. Blocks have also been presented to the C standards working group as N1370: Apple’s Extensions to C (which also includes Garbage Collection).

As Objective-C and C++ are both derived from C, Blocks are designed to work fine with all three languages. Thus, the syntax reflects this goal.

A block is introduced using the ^ — the caret — character. The ^ was chosen as it had no unary form (and C++ couldn’t operator overload it).

For the purposes of an excruciatingly simple example, how about a block that multiplies two numbers?

Read the rest of this entry »

AT&T U-Verse: Configuring for Back To My Mac

Sunday, August 16th, 2009

Upon switching to AT&T’s U-Verse service, I had a bit of “fun” configuring the 2wire modem.

At the end of it, the Mobile Me Back To My Mac feature didn’t work. That bummed me out; it is an incredibly useful feature.

The problem is that the 2wire modems don’t support either NAT-PMP (NAT Port Mapping Protocol) or UPnP (Universal Plug and Play). A bit surprising.

To fix, the key is to make the 2wire modem as dumb and invisible as possible. Treat it like the incapable box that it is.

You will need a UPnP or NAT-PMP capable router (or a machine that you can configure as a router– Mac OS X’s built in “Internet Sharing” works just fine).

Read the rest of this entry »

Booting a MacBook Pro from an SDHC Card

Friday, August 7th, 2009

I recently picked up an ExpressCard/34 SD reader along with a Transcend 16GB SDHC card. The reader was to ease the transfer of photos from a digital camera and the high-cap SDHC card ensures I can take plenty of photos without shuffling about cards.

With the recent announcement of SD-slot-ness MacBook Pros (drool) that can boot from the SD slot, it made me wonder if a previous generation MacBook Pro could do so, too.

And it can! Which isn’t totally surprising. SD ExpressCard readers effectively act like USB drives and most (all?? I don’t know) Intel macs can boot from USB devices.

On the click through is instructions for formatting an SD car correctly and slapping down a bootable image.

Given the relatively low prices of SD cards, I’m making a habit of carrying around a “rescue card”. Tiny enough to not be noticeable, can be reformatted to use as photo-space trivially, one hell of a lot of tougher than optical media, and will prove to be indispensable if I ever need it.


Read the rest of this entry »

Lizard Saver!

Thursday, May 21st, 2009
Screenshot on 2009-05-20 at 10.33.19 PM.png

Out of the blue, I received a tweet from Steven Blackford:

@bbum Wanted to say thanks the old BackSpace Module LizardView. Still using it after all these years on all my NeXT systems.

Wow. That took me back nearly 20 years! From the moment I started writing Objective-C code on a NeXT in 1989, I have taken a break every couple of years to write a screensaver or five. They have always been fairly simple, always geometric in nature, and generally with a bit of fractally goodness.

At left is a screenshot of LizardView. It was one of the first screensavers I wrote for the NeXT. Fortunately, Steven still had the source for LizardView (I likely still do, too, on one of the optical discs in my garage) and it took me about 10 minutes to port it to Mac OS X Leopard.

Blast from the past.

If you’d like to experience this awzzum zele-bra-shun of k0l0rfull moiré patterns, I dropped Lizard.saver.zip on friday.com.

Funny story; in about 1996 or 97, I found myself at a rather random (and not that terribly good) rave like party in St. Louis, MO. There was a video projector that was running some “rave animations” loop. Lizard was used throughout as 5 or so second interstitial between different animation sequences!

CardRaider: $20 Stupidity Compensator that Just Works

Friday, February 13th, 2009
Climbing the Hill to the Great Blue
Tossing a Log

Consider the two images at right. Neat images. Nothing spectacular, but special to my family in that they tell a story of part of an adventure to Bean Hollow State Beach (an awesome beach near Pescadero, CA).

And I would have neither those two pictures are a slew of others from the same trip if I hadn’t had CardRaider. Entirely due to PEBKAC (i.e. bbum was a dumbass), I reformatted the compact flash card after downloading only half the images — downloading just the images from the first beach we went to.

Now, fortunately, “reformatting” a compact flash card does very little other than mark the space as free for a variety of reasons that are quite interesting but more than I’ll reiterate here (including that the flash filesystem tends to be a lot less “chatty” than, say, a hard drive with log files, caches, VM, and the like).

End result? $20 and a short download later my photos were recovered via CardRaider .

Not much to say about the product. I have no knowledge about the competitors. CardRaider seemed highly ranked on various review sites and a search of weblogs revealed other folk who lost images for less stupid reasons than me who were quite happy.

It just worked.

And it just worked again. My wife has been dragging around a camera full of photos for over a year now. For whatever reason, all the normal means of downloading the photos didn’t work — i/o errors or some such nonsense.

CardRaider had no problem finding all the photos, including a couple that had been deleted that were save-worthy, and downloading them, apparently intact.