Series of articles: Alloc, retain, isKindOfClass, and other AWZ, RR, and CORE methods do not follow their own IMP iOS low-level exploration, iOS malloc memory allocation principles .

⭐ : Core logical content

🐈 stands for branch knowledge expansion

 stands for “Apple official documentation or source code”

Resources used in this analysis:

 objc4 – the source code

Compilable objC4 source code (Cooci)

 LLVM source

LLVM optimization results 🌰

The most common way to initialize an object in a project is to alloc init new, Objc_alloc objC_alloc_init objC_OPt_new _ (:з “Angle) _ other words from withwith-with-alloc IOS Low-level Exploration ① OC object initialization process

The debugging code is as follows:

Use CLang (the front end of LLVM) to compile the compiled CPP file in the output step 1: Open the terminal CD to the main.m folder Step 2: Clang-rewrite-objc main.m -o main. CPP -o main. CPP.

You can see the above code compiled by Clang as follows:

The OC methods before ⭐ are converted to objc_msgSend, and this step is not the final machine code executed. The code generated by the front end of the Clang compiler can be optimized by LLVM IR and then converted to assembly for the target CPU architecture, which is then converted to the final machine code executed. So the code compiled by the Clang front end is not necessarily the final code executed, and LLVM IR optimization may have been handled in the middle

Assembler to see the essence — the final code executed:

What exactly is going on in LLVM

Open the downloaded LLVM source code with VSCode and search the objc_opt_new just optimized to find g_opt_dispatch_names

⭐ g_opt_dispatch_names is a C++ method used for global set optimization. LLVM also commented at the top: the purpose is to speed up method distribution and increase efficiency. The reason is that the AWZ, RR, and CORE methods are rarely overridden, and the compiler has replaced them to execute the corresponding methods in one step (avoiding the lengthy method lookup process of the OC inheritance chain, which should be the longest method lookup chain). Of course, there is conditional detection, and if any method is overwritten it will go to the original objc_msgSend

Optimize the function call flow:

Core method in CGObjC. CPP tryGenerateSpecializedMessageSend () function, function declarations and comments are as follows:

The content of the comment is basically the same as above. In order to make the message processing faster, if there is an override method exception, go to the original objc_msgSend

⭐ analysis source code can be seen, finally in cgF. EmitObjcAlloc method completed OC method alloc into optimization method objc_alloc as shown below:

Other LLVM IR optimization method call processing, it is worth mentioning OC [[MyClass alloc] init] such writing is not a single function code is optimized optimization method in tryEmitSpecializedAllocInit source code for a lot of check, Including whether it is alloc init of the same Class and so on, it can be seen that compiler level optimization is very careful, which can be used for reference in writing projects and SDK performance optimization.

What are the ways to supplement the AWZ, RR and CORE series

AWZ is short for allocWithZone, contains the alloc/allocWithZone method RR is short for retain Release, Mainly contains retain/release/autorelease method some methods of the CORE is a CORE OC object contains new/self/class/respondsToSelector/isKindOfClass method

The definition can be found at objC4 source objc-runtime-new.h

// class or superclass has default alloc/allocWithZone: implementation
// Note this is is stored in the metaclass.
#define FAST_CACHE_HAS_DEFAULT_AWZ    (1<<14)

// class or superclass has default retain/release/autorelease/retainCount/
// _tryRetain/_isDeallocating/retainWeakReference/allowsWeakReference
#define FAST_HAS_DEFAULT_RR     (1UL<<2)

// class or superclass has default new/self/class/respondsToSelector/isKindOfClass
#define FAST_CACHE_HAS_DEFAULT_CORE   (1<<15)
Copy the code

Write in the last

The code environment of this article is based on Apple objC4-818.2 source code and Xcode12. The content is structured and refined as far as possible in order to save readers’ reading time and cost. If there is any wrong writing or supplement, please timely communicate with us ~~

Finally, thank you for reading everything. Have a nice codding