1, iOS bottom Analysis - alloc Analysis

A, alloc init explore

Summary:

iOS application for the object in alloc is sent us to open up the memory, initialization of the most used is shown below.

[[xxx alloc] init];

problem:

1, you want to analyze alloc where to start, how to analyze?

2, alloc at the bottom of what has been done? In the bottom of how to achieve?

3, alloc when the object has been created, which have nothing to write init (read the source code to know of), init in the end to do it?

 

analysis:

Explore common method alloc


Explore alloc start from int main function

There are three common techniques to explore, briefly

1), the next breakpoint: control + in found objc_alloc

2), the symbolic break: libobjc.A.dylib` + [NSObject alloc]

Breakpoint - symbolic Breakpoint - corresponding method name

3), assembler view the process (Note the use of device debugging)

Debug - Debug workflow - Always show Disassembly

Download the source code and configuration environment

Need to download and compile the source code, to further explore alloc. Configuration is as follows

objc4-750 source + Xcode11 + MacOS 10.15

Download the official source

iOS_objc4-756.2 latest source compiler debugging

 

Start Analysis

alloc init

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"LG_Cooci: alloc 探索");
    // alloc 探索
    // alloc 已经创建了对象 init
    // alloc 怎么创建的呢?
    // alloc 实现 - 原理 - 源码实现
    // 介绍三种方式
    // libobjc.A.dylib
    // 1: 下断点 : control + in - objc_alloc
    // 2: 下符号断点 : libobjc.A.dylib`+[NSObject alloc]:
    // 3: 汇编  libobjc.A.dylib`objc_alloc:
    
    LGPerson *p1 = [LGPerson alloc];
    LGPerson *p2 = [p1 init];
    LGPerson *p3 = [p1 init];
    LGNSLog(@"%@ - %p",p1,&p1);
    LGNSLog(@"%@ - %p",p2,&p2);
    LGNSLog(@"%@ - %p",p3,&p3);

//打印出来的结果是p1 p2 p3结果一样,地址不一样

有三个指针,有三个指针地址。但是这三个指针指向的地址是相同给的。

3个指针指向同一个空间

}

This time you can know p1 p2 p3 three pointer are [LGPerson alloc] opened up space

This time there will be a doubt the very beginning, it would have created an object alloc, init what it has done it? alloc analysis, this is about to begin

alloc analysis

Starting from int main function, break points, then command + left- click to go step by step analysis (analysis of source code)

1、alloc

NSObject.mm (and so is the bottom layer is mixed .mm)

+ (id)alloc {
    return _objc_rootAlloc(self);
}

 2、_objc_rootAlloc

NSObject.mm return a callAlloc

// Base class implementation of +alloc. cls is not nil.
// Calls [cls allocWithZone:nil].
id
_objc_rootAlloc(Class cls)
{
    return callAlloc(cls, false/*checkNil*/, true/*allocWithZone*/);
}

3、callAlloc(cls,falsee,true)

NSObject.mm

// Call [cls alloc] or [cls allocWithZone:nil], with appropriate 
// shortcutting optimizations.
static ALWAYS_INLINE id
callAlloc(Class cls, bool checkNil, bool allocWithZone=false)
{
    if (slowpath(checkNil && !cls)) return nil;//容错无用

#if __OBJC2__
    if (fastpath(!cls->ISA()->hasCustomAWZ())) {
        上边的都不重要,判断一下非自定义的类的话都走这,下边的这些是重点
        // No alloc/allocWithZone implementation. Go straight to the allocator.
        // fixme store hasCustomAWZ in the non-meta class and 
        // add it to canAllocFast's summary
        if (fastpath(cls->canAllocFast())) {
            // No ctors, raw isa, etc. Go straight to the metal.
            bool dtor = cls->hasCxxDtor();
            id obj = (id)calloc(1, cls->bits.fastInstanceSize());
            if (slowpath(!obj)) return callBadAllocHandler(cls);
            obj->initInstanceIsa(cls, dtor);
            return obj;
        }
        else {
            // Has ctor or raw isa or something. Use the slower path.
            id obj = class_createInstance(cls, 0);
            if (slowpath(!obj)) return callBadAllocHandler(cls);
            return obj;
        }
    }
#endif
目前真机使用的都是objc—2,所以下边的不会走省略不是重点
}

4, class_createInstance (CLS, 0) (create instance)

Its internal calls _class_createInstanceFromZone methods and calculations which the size, memory allocation, initialization and isa

id 
class_createInstance(Class cls, size_t extraBytes)
{
    return _class_createInstanceFromZone(cls, extraBytes, nil);
}

5、_class_createInstanceFromZone

Depending on the conditions, use calloc or malloc_zone_calloc for memory applications, and initializes isa pointer, size of the object to complete the application size (size about the size of 5.1) has the obj, and returns

static __attribute__((always_inline)) 
id
_class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone, 
                              bool cxxConstruct = true, 
                              size_t *outAllocatedSize = nil)
{
    // Read class's info bits all at once for performance
    bool hasCxxCtor = cls->hasCxxCtor();
    bool hasCxxDtor = cls->hasCxxDtor();
    bool fast = cls->canAllocNonpointer();

    size_t size = cls->instanceSize(extraBytes);
    if (outAllocatedSize) *outAllocatedSize = size;

    id obj;
    if (!zone  &&  fast) {
        obj = (id)calloc(1, size);
        if (!obj) return nil;
        obj->initInstanceIsa(cls, hasCxxDtor);
    } 
    else {
        if (zone) {
            obj = (id)malloc_zone_calloc ((malloc_zone_t *)zone, 1, size);
        } else {
            obj = (id)calloc(1, size);
        }
        if (!obj) return nil;
        obj->initIsa(cls);
    }

    if (cxxConstruct && hasCxxCtor) {
        obj = _objc_constructOrFree(obj, cls);
    }

    return obj;
}

5.1, CLS-> instanceSize (extraBytes) , calculate the size,

In order to facilitate and improve the performance of the read byte aligned, then calculate the size of the actual alignment required after
a minimum 64-bit system memory, wherein, the size of the object using the 8-byte aligned, but alloc actual application is 16 bytes, i.e. said system allocates 16-byte aligned memory allocation according to

8 byte space for time alignment is to ensure the access speed.

// 此方法,用来字节对齐
uint32_t alignedInstanceSize() {
        return word_align(unalignedInstanceSize());
    }
// 字节对齐的详细方法,WORD_MASK在64位下为7,32位下为3,用来进行字节对齐
static inline size_t word_align(size_t x) {
    return (x + WORD_MASK) & ~WORD_MASK;
}

// 申请地址,此处有16字节限制
size_t instanceSize(size_t extraBytes) {
        size_t size = alignedInstanceSize() + extraBytes;
        // CF requires all objects be at least 16 bytes.
        if (size < 16) size = 16;
        return size;
}

to sum up:

alloc

–>_objc_rootAlloc

-> callAlloc

-> class_ createInstance (create an instance)

-> _ class_ createInstanceFromZone (create an instance from a proprietary zone)

{1, _class_instanceSize (open space, 64-bit 8-byte aligned, 32-bit 4-byte alignment while greater than or equal 16)

2、calloc

. 3, objc_ initInstanceIsa (Example Isa)

Great God attach a flow chart that summarizes

 

Expand and extend the knowledge of other

1, breakpoint debugging console command section

All Variables   all variables

register read read register

 

2, OC compiled into lower when the call is still the OC method, and then call the function to handle the lower mixed. Is lower when mixed

 

 

3, alloc create objects application memory space - Pointer (Pointer is no longer with the depletion of class LGPerson)

alloc the object is created, it will return the corresponding target address, return address of the object will have a capacity of application memory space, there is the return value x0.

X0 transfer port of both the first parameter, where the value is returned is stored.

Opening a first memory space (memory space is opened up to a multiple of 8 bytes (64-bit machines), while greater than 16), open after successfully associated memory.

isa is a consortium points to its address space.

 

4、alloc

  1. Open application memory
  2. Accompanied initialized isa

5、init

  1. _objc_rootInit(obj)
  2. return obj

Plant design, to the subclass to override the freedom to customize

init is the norm

 

6、new

Equivalent alloc init

[callAlloc() init]

 

7, the system allocated objects algorithm

Open memory size (and, negated)

(x+WORO_MASK)&~ WORO_MASK

64位#define WORO_MASK 7UL    32位  3UL

64 is a multiple of 32-bit 8 is a multiple of 4 or greater satisfying 16

if(size < 16) size = 16;

 

8, the memory alignment

SHIFT_NANO_QUANTUM 16
K = (size + NANO_REGIME_QUANTA_SIZE - 1) >> SHIFT_NANO_QUANTUM


slot_bytes = k << SHIFT_NANO_QUANTUM

Open system memory to 16 multiples.

 

9, compilation, analysis, part of the code compiler optimization

 

1、     build setting

  1. optimization
  2. Fastsamallest

 

2, compiler optimizations role

  1. Compile time
  2. Link Time
  3. operation hours
  4. free time

 

LLDB objc4 malloc debug configuration source

Debugging is really needed because

We need real machine

Arm64 X0- X30

Simulator is

X86

 

 

Published 83 original articles · won praise 12 · views 180 000 +

Guess you like

Origin blog.csdn.net/shengdaVolleyball/article/details/104028275