当前开源的OC运行时中的_OBJC_TAG_MASK很奇怪

时间:2018-07-18 17:29:35

标签: objective-c runtime

我正在从here阅读OC运行时源代码,尤其是有关标记指针的信息。

麻烦的是运行时确定值的方式 _OBJC_TAG_MASK。

#if OBJC_MSB_TAGGED_POINTERS
#   define _OBJC_TAG_MASK (1UL<<63)
#else
#   define _OBJC_TAG_MASK 1UL
#endif

OBJC_MSB_TAGGED_POINTERS定义如下

#if TARGET_OS_OSX && __x86_64__
    // 64-bit Mac - tag bit is LSB
#   define OBJC_MSB_TAGGED_POINTERS 0
#else
    // Everything else - tag bit is MSB
#   define OBJC_MSB_TAGGED_POINTERS 1
#endif

本质上是指

#if TARGET_OS_OSX && __x86_64__
    // 64-bit Mac - tag bit is LSB
    // We know that we have 64 bits and use LSB?
#   define _OBJC_TAG_MASK 1UL
#else
    // Everything else - tag bit is MSB
    // Won't this be problematic on 32 bits iOS 
devices?
#   define _OBJC_TAG_MASK (1UL<<63)
#endif 

我真的很困惑,任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

事实证明这很简单,标记指针当前仅具有64位功能。

#if __LP64__
#define OBJC_HAVE_TAGGED_POINTERS 1
#endif

#if OBJC_HAVE_TAGGED_POINTERS

// All related codes here.

#endif

涉及MSB和LSB

  • TARGET_OS_OSX && x86_64 :LSB将保证至少有4位可用,因为malloc将返回16字节对齐的内存地址。
  • 否则,ARM64仅使用64位中的48位,因此无论如何都浪费了MSB,将MASK移到MSB似乎是很合理的。