Tagged Pointer is introduced

Tagged Pointer features

  1. Tagged Pointer is used to store small objects, such as NSNumber and NSDate
  2. The Tagged Pointer value is no longer an address, but a real value. So, it’s not really an object anymore, it’s just a normal variable in an object’s skin. Therefore, its memory is not stored in the heap and does not require malloc and free.
  3. Three times more efficient at memory reads and 106 times faster at creation.

Why Tagged Pointer

The iPhone5s has a 64-bit processor. For 64-bit applications, the length of our data type is cpu-dependent.

This results in some objects taking up twice as much memory.

At the same time, maintaining objects in your program requires allocating memory, maintaining reference counts, and managing life cycles. Using objects adds to the burden of running your program.

Tagged Pointer

To address the memory footprint and efficiency issues mentioned above, Apple introduced Tagged Pointer. Since the value of the variables such as NSNumber and NSDate usually does not need 8 bytes of memory, take the integer as an example, the signed integer represented by 4 bytes can reach more than 2 billion (note: 2^31=2147483648, another 1 bit as a sign bit), which can be handled in most cases.

We can split a pointer to an object into two parts: one holds the data directly, and the other is a special marker indicating that this is a special pointer that does not point to any address. Therefore, after the Tagged Pointer object is introduced, the memory graph of the NSNumber on the 64-bit CPU becomes Tagged Pointer

test

#import int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... NSNumber *number1 = @1; NSNumber *number2 = @2; NSNumber *number3 = @3; NSNumber *numberFFFF = @(0xFFFF); NSNumber *numberLager = @(MAXFLOAT); NSLog(@"number1 pointer is %p", number1); NSLog(@"number2 pointer is %p", number2); NSLog(@"number3 pointer is %p", number3); NSLog(@"numberLager pointer is %p", numberLager); /* 2017-03-10 12:07:50.731726 TaggedPoint[1690:50438] Number1 Pointer is 0x127 2017-03-10 12:07:50.731992 TaggedPoint[1690:50438] Number2 Pointer is 0x227 2017-03-10 12:07:50.732011 TaggedPoint[1690:50438] Number3 Pointer is 0x327 2017-03-10 12:07:50.732043 TaggedPoint[1690:50438] numberLager Pointer is 0x1002006A0 */} Return 0; }Copy the code

Take 0x127 as an example and remove tag27(assuming 27 is the flag). 0x1 is the value of number. 0x227, 0x327

NumberLager stores a value of MAXFloat that is clearly beyond what Tagged Pointer can store. So the printed address is a pure pointer address that points to the memory address where numberLager is stored.

Impact on isa Pointers

Since tagged Pointer is not a real object, an error will be reported during compilation if an ISA pointer is used. As shown in figure:





Since object_getClass() has no corresponding implementation, you can only peek at objc-weak.mm from other places

weak_read_no_lock(weak_table_t *weak_table, id *referrer_id) 
{
    objc_object **referrer = (objc_object **)referrer_id;
    objc_object *referent = *referrer;
    if (referent->isTaggedPointer()) return (id)referent;
    / /...
}Copy the code
inline bool 
objc_object::isTaggedPointer() 
{
#if SUPPORT_TAGGED_POINTERS
    return ((uintptr_t)this & TAG_MASK);
#else
    return false;
#endif
}Copy the code

So we’re making a little bit of a judgment about the value of the object if it’s tagged pointer, the value of the object is a pointer and if it’s not tagged pointer, the value of the object is the value of the memory region that the pointer points to