gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: CoreFoundation


From: David Chisnall
Subject: Re: CoreFoundation
Date: Sat, 24 Oct 2009 11:42:31 +0100

On 24 Oct 2009, at 02:14, Stef Bidi wrote:

I guess I should explain, I was only going to use the CLS_GETNUMBER () macro in objc-api.h (that is, only the top half of the info field). I also noticed that this macros, when written out, doing: ((sizeof(long)*8)/2)... wouldn't ((sizeof(long)<<3)>>1) be a lot faster? Specially on RISC archtectures? My C programming book suggests that when multiplying or dividing by a multiple of 2^x a shift is often better than a multiply/divide.

The CLS_GETNUMBER() macro should be considered private, and won't be exposed in future versions of the runtime. With regard to your optimization question, you might be interested in my article How Not To Optimize:

http://www.informit.com/articles/article.aspx?p=1390173

In this case, if it is faster to use shifts then any compiler written in the last 20 years (including the toy that I wrote as an undergrad coursework assignment) will emit shifts for you. However, because this is an expression where all values are known at compile time, the compiler will simply evaluate it at compile time and if you look in the generated assembly you will find that it has become either 16 or 32.

Note that, because shifts are relatively rare operations, most modern processors aren't optimized for shift-heavy instruction streams (except ARM, which lets you add a free shift to almost any instruction, which is pretty shiny). Older versions of GCC would expand multiplications to sequences of shift and add instructions, but on a modern x86 chip this will be the same speed in the best case and slower in the worst.

With regard to the CFTypeID, this should be the address of the class structure. For those unfamiliar with how CoreFoundation works:

That includes me... the only thing I have to go by is CF-Lite's CFRuntime.h and the CF docs.

You might be interested in this example, which talks in a lot more detail:

http://ridiculousfish.com/blog/archives/2006/09/09/bridge/

Don't pay too much attention to it though; you want to duplicate the behaviour, not the implementation. Given that Apple now link CF with libobjc, I suspect that they are somewhat unconvinced by the benefit of this approach in the long run. It's only real advantage is that it will work in ObjC++ code if statics are initialized with CF calls and these happen to run before the relevant ObjC load functions (which, I think, can't happen on OS X because they hacked the linker to enforce some stricter ordering).

I was going with objc_msg_lookup, I figured I could do everything in pure C that way. But I guess this will work, too. This is why I put it out at this stage, so I don't follow the wrong path for too long.

I'd prefer you not to use objc_msg_lookup(), because it's deprecated in the new ABI. There's an objc_msgSend() macro in the new runtime.h that generates a correct lookup-and-call sequence for either ABI. Or just use Objective-C and let the compiler sort it out for you.

And here's where I ran into some problems... apparently, CFAllocatorRef is considered a class (responds to CFGetTypeID()), but isn't one in GNUstep. Also, it allows users to define they're own with CFAllocatorCreate(), which takes a CFAllocatorContext. I might just have to not allow that if this is the case.


Oh yes, I forgot about that. On OS X, NSZone is an opaque structure. On GNUstep, it is not, and corresponds very closely to the CFAllocator initializer thingy. Of course, you could just create a new, private, CFAllocator class that has a single, public, NSZone ivar.

At this point, I'm really not sure what the correct way ahead should be. I'm hoping I'll get some more feedback so that I can make an informed decision.

As Richard said, don't be afraid of modifying -base. It might be necessary to modify some of the existing GNUstep classes to better support CF.

Stuart was also right that I oversimplified the TypeID thing. This does not change with inheritance; it's the same for any all objects that inherit from it, and only used as the isa pointer on the (opaque) leaf CF classes (this allows them to function before libobjc exists, and to be statically initialized). It's probably best to implement this with a -_cfTypeID method that returns a constant, and only override it in classes like NSArray, not any of their subclasses.

Stefan



-- Sent from my STANTEC-ZEBRA





reply via email to

[Prev in Thread] Current Thread [Next in Thread]