美文网首页
Objective-C Tagged Pointer

Objective-C Tagged Pointer

作者: 一半晴天 | 来源:发表于2018-06-16 16:39 被阅读34次

    此文实际成于 2015/07/30

    目前在 objc4/runtime/objc-internal.h 中描述以以下 Tagged pointer 对象。

    {
        OBJC_TAG_NSAtom            = 0, 
        OBJC_TAG_1                 = 1, 
        OBJC_TAG_NSString          = 2, 
        OBJC_TAG_NSNumber          = 3, 
        OBJC_TAG_NSIndexPath       = 4, 
        OBJC_TAG_NSManagedObjectID = 5, 
        OBJC_TAG_NSDate            = 6, 
        OBJC_TAG_7                 = 7
    };
    

    Tagged pointer 的位分布

    // Tagged pointer layout and usage is subject to change 
    // on different OS versions. The current layout is:
    // (MSB)
    // 60 bits  payload
    //  3 bits  tag index
    //  1 bit   1 for tagged pointer objects, 0 for ordinary objects
    // (LSB)
    

    下面是对应生成 Tagged Pointer 的函数:

    static inline void *
    _objc_makeTaggedPointer(objc_tag_index_t tag, uintptr_t value)
    {
        // assert(_objc_taggedPointersEnabled());
        // assert((unsigned int)tag < 8);
        // assert(((value << 4) >> 4) == value);
    
        // 0xf << 60:      1111000000000000000000000000000000000000000000000000000000000000
        // ~(0xf << 60)    0000111111111111111111111111111111111111111111111111111111111111
        // tag << 60:      0001000000000000000000000000000000000000000000000000000000000000
        // 1 << 63  :      1000000000000000000000000000000000000000000000000000000000000000
        // 假充 value:      0000000000000000000000000000000000000111101010111100001100000000
        // tagged pointer: 1001000000000000000000000000000000000111101010111100001100000000
        // ox80            1000000000000000000000000000000000000000000000000000000000000000
        return (void*)((1UL << 63) | ((uintptr_t)tag << 60) | (value & ~(0xFUL << 60)));
    }
    

    判断的时候是将其先转成一个 int型来判断:

    
    static inline bool 
    _objc_isTaggedPointer(const void *ptr) 
    {
        return (intptr_t)ptr < 0;  // a.k.a. ptr & 0x8000000000000000
    }
    

    获得 Tagged Pointer 在某一个指针上的Tag

    static inline objc_tag_index_t 
    _objc_getTaggedPointerTag(const void *ptr) 
    {
        // assert(_objc_isTaggedPointer(ptr));
        return (objc_tag_index_t)(((uintptr_t)ptr >> 60) & 0x7);
    }
    

    获得 Tagged Pointer 实际用作指针的值。

    static inline uintptr_t
    _objc_getTaggedPointerValue(const void *ptr) 
    {
        // assert(_objc_isTaggedPointer(ptr));
        return (uintptr_t)ptr & 0x0fffffffffffffff;
    }
    

    是否是 Tagged Pointer 的判断。

    经常的 objc4 开源代码看到对下面方法的调用:

    inline bool 
    objc_object::isTaggedPointer() 
    {
    #if SUPPORT_TAGGED_POINTERS
       return ((uintptr_t)this & TAG_MASK);
    #else
       return false;
    #endif
    }
    

    根据上面的学习 TAG_MASK 应该等于 0x8000000000000000
    这在函数: _objc_isTaggedPointer 中有说明。

    目前只有上面提到的6种类的对象是使用的 TaggedPointer

    参考

    1. http://stackoverflow.com/questions/20362406/tagged-pointers-in-objective-c

    相关文章

      网友评论

          本文标题:Objective-C Tagged Pointer

          本文链接:https://www.haomeiwen.com/subject/hnybeftx.html