Edit me

Create a tagged pointer (TPS) class

A tagged pointer class is great, if you have a lot of instances that are extremely small. Let’s say you want to encode a 24 bit color in a tagged pointer, here’s how to do it.

Choose a free index

On 32 bit you have 1-3 available, on 64 bit it is 1-7. You can use this function to search for a free index:

i =  mulle_objc_universe_search_free_taggedpointerclass( universe);
if( ! i)
   return( i);

Let the TPS class inherit your class

Subclass your color class and adorn your @interface declaration with the MulleObjCTaggedPointer protocol: Your class must be abstract and not contain any instance variables. Use #ifdef __MULLE_OBJC_TPS__ around your code, as the user can turn off TPS code with a compiler option. Your code should run fine without TPS enabled (just don’t use the TPS class then).

#ifdef __MULLE_OBJC_TPS__

@interface MyTPSColor : MyColor <MulleObjCTaggedPointer>
@end

#endif

Create a +load method

This will hookup your class into the TPS system at runtime. It’s assumed you are using a fixed number scheme here and the TPS index chosen is ‘3’.

#ifdef __MULLE_OBJC_TPS__

@implementation MyTPSColor

+ (void) load
{
   if( MulleObjCTaggedPointerRegisterClassAtIndex( self, 0x3))
   {
      perror( "Need tag pointer aware runtime for MyTPSColor with empty slot #3\n");
      abort();
   }
}
@end

#endif

Create TPS instance depending on input

Convert you color to a 24 bit value and create the instance with the C function MulleObjCCreateTaggedPointerWithUnsignedIntegerValueAndIndex. Do not use +alloc!

static inline MyColor   *TPSColorNew( unsigned char r, unsigned char g , unsigned char b)
{
   NSUInteger   value;

   value = (((NSUInteger) << 16) | ((NSUInteger) g << 8) | (NSUInteger) b);
   return( (MyColor *) MulleObjCCreateTaggedPointerWithUnsignedIntegerValueAndIndex( value, 0x3));
}

Retrieve value from TPS instance

@implementation MyTPSColor

...

- (unsigned char) getRedComponent
{
   NSUInteger   value;

   value = MulleObjCTaggedPointerGetUnsignedIntegerValue( self);
   return( value >> 16);
}

And that’s about it.

Tags: runtime 8.0.0