Introduction: isa isa very magical, very powerful, very low-key role, she is up and down, in the iOS development process has many times appeared in our world, quietly, no regrets for us to provide a variety of services! If you know NSObject, then you must know that Isa, so to speak, is the soul of an object, without which everything would lose its color……

Explore ISA from the object’s alloc

PS: Friendship links

OC Object Principle Exploration (PART 1) — Object Alloc

OC Object Principle Exploration (PART 2) — Union (Common Body) and Bit Field

1, isa and object alloc

  • The process analysis of alloc, which involves object creation and association, is described as follows:
.if(! zone && fast) { obj->initInstanceIsa(cls, hasCxxDtor);
    } else {
        // Use raw pointer isa on the assumption that they might be
        // doing something weird with the zone or RR.
        obj->initIsa(cls); }...Copy the code

When it comes to the memory allocation part of the object, trace the core code obj->initIsa(CLS).

.union isa_t {
    isa_t() {}isa_t(uintptr_t value) : bits(value) { }

    uintptr_t bits;

private: Class cls; .#if defined(ISA_BITFIELD)
    struct {
        ISA_BITFIELD;  // defined in isa.h}; .Copy the code
  • Analysis shows that the storage structure of isa isa consortium structure. For the consortium and bitfield, you can see the associated article –OC Object Principle Exploration (PART 2) — Union (Common Body) and Bit Field

2. Definition of ISA_BITFIELD

After analyzing the nature of OC objects, we know that there is at least one ISA member variable inside the object. Isa occupies 8 bytes, that is, 8×8=64 bits.

If we used all that space to store Pointers, the waste of space would be huge. There may be other things in a class that need to be stored besides Pointers, and a series of optimizations for this 8-byte space can save a lot of memory overhead.

  • A storage-related type of the class is nonPointerIsa, which involves storing variable information in the following ways:

① Is it being released? C/C++ = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

  • View the definition of nonPointerIsa:
# if __arm64__
#     define ISA_MASK        0x0000000ffffffff8ULL
#     define ISA_MAGIC_MASK  0x000003f000000001ULL
#     define ISA_MAGIC_VALUE 0x000001a000000001ULL
#     define ISA_HAS_CXX_DTOR_BIT 1
#     define ISA_BITFIELD 
        uintptr_t nonpointer        : 1;                                       \
        uintptr_t has_assoc         : 1;                                       \
        uintptr_t has_cxx_dtor      : 1;                                       \
        uintptr_t shiftcls          : 33; /*MACH_VM_MAX_ADDRESS 0x1000000000*/ \
        uintptr_t magic             : 6;                                       \
        uintptr_t weakly_referenced : 1;                                       \
        uintptr_t unused            : 1;                                       \
        uintptr_t has_sidetable_rc  : 1;                                       \
        uintptr_t extra_rc          : 19
#     define RC_ONE   (1ULL<<45)
#     define RC_HALF  (1ULL<<18)
#   endif


Copy the code

In isa.h, the type of ISA under ARM64 is defined, where we focus on the structure of ISA_BITFIELD: as you can see, ISA_BITFIELD is defined as a bit-field structure.

3. Roles of different bit fields in ISA_BITFIELD

0 0 0 0 0 0 0 0
7 ~ 0

0: indicates that the isa pointer is pure. 1: indicates that the ISA pointer contains not only the address of the class object, but also the reference count of the object. 2 has_ASsoc: indicates the flag bit of the associated object. 3 has_cxx_dtor: whether the object has a destructor of C++ or Objc. If it has a destructor, it needs to do the destructor logic. If it does not, it can release the object faster.


0 0 0 0 0 0 0 0
15 ~ 8
0 0 0 0 0 0 0 0
23 ~ 16
0 0 0 0 0 0 0 0
31 ~ 24

④ Shiftcls: Stores the value of the class pointer. With pointer optimization turned on, 33 bits are used to store class Pointers in the ARM64 architecture.

0 0 0 0 0 0 0 0
39 ~ 32
0 0 0 0 0 0 0 0
47 ~ 40

⑤ Magic: used for the debugger to determine whether the current object is a real object or no initialized space ⑥ Weakly_referenced: Whether the object is pointed to or has been pointed to an ARC weak variable, no weak reference object can be released faster. Deallocating: Indicates whether the object is freeing memory. ⑦ has_SIDETABLE_rc: When the object reference technique is greater than 10, you need to borrow this variable to store the carry

0 0 0 0 0 0 0 0
56 ~ 48
0 0 0 0 0 0 0 0
64-57

Extra_rc: When representing the reference count of this object, the reference count is actually subtracted by 1. For example, if the object’s reference count is 10, the extra_rc is 9. If the reference count is greater than 10, the following has_sideTABLE_rc is used.

4, Isa and class

YTPerson = YTPerson; 5 = 0x00000001000080e8 YTPerson ② get isa address 0x001D8001000080E9 ③ use ISA address and ISA_MASK & to get the calculated address: 6 = 0x00000001000080E8 ④ Compare addresses 5 and 5 with those 5 and 6 and find the following relationship: The object address = ISA address & ISA_MASK

Isa and class assignment

1. Get the core content of the class from class

  • According to the above analysis, we know that the core information of ISA class is stored in uintptr_t shiftcls, so we can get the actual address value of CLS through displacement operation according to the address of a class.
#   define ISA_MASK        0x00007ffffffffff8ULL
#   define ISA_MAGIC_MASK  0x001f800000000001ULL
#   define ISA_MAGIC_VALUE 0x001d800000000001ULL
#   define ISA_HAS_CXX_DTOR_BIT 1
#   define ISA_BITFIELD                                                        \
      uintptr_t nonpointer        : 1;                                         \
      uintptr_t has_assoc         : 1;                                         \
      uintptr_t has_cxx_dtor      : 1;                                         \
      uintptr_t shiftcls          : 44; /*MACH_VM_MAX_ADDRESS 0x7fffffe00000*/ \
      uintptr_t magic             : 6;                                         \
      uintptr_t weakly_referenced : 1;                                         \
      uintptr_t unused            : 1;                                         \
      uintptr_t has_sidetable_rc  : 1;                                         \
      uintptr_t extra_rc          : 8
#   define RC_ONE   (1ULL<<56)
#   define RC_HALF  (1ULL<<7)

Copy the code

2. Get the value of isa from class

  • Process analysis

① Obtain the address of YTPerson object P 0x001D8001000080e9

$8 = 0x0003b0002000101D $8 = 0x0003b0002000101d

③ Move the address of 8 20 bits to the right, get the address of 8 20 bits to the right, get the address of 8 20 bits to the right, get 9 = 0x0002000101D00000

④ Move the address of 9 17 bits to the left, get the address of 9 17 bits to the left, get the address of 9 17 bits to the left, get 10 = 0x00000001000080E8

⑤ Check the address of YTPerson 11= 0x00000001000080E8 =11 = 0x00000001000080E8 =11 = 0x00000001000080E8 =10

Conclusion:
1. The core information of a class actually exists in ISA_BITFIELD. Because the bitfield shares a piece of memory, the address of shiftcls, the bitfield storing the class information, can be obtained according to the offset of the address, which is also the ISA address of YTPerson in the example.
2. The storage structure of the commonwealth bit domain in the class optimizes the storage space and improves the computing power. It is of great significance to the software development under the limited memory space.
This article is about the isa and class relationship analysis, involving the commonwealth bitfield concept, if you have questions, please refer to the article –OC Object Principle Exploration (PART 2) — Union (Common Body) and Bit Field