review
Why do a review?
The reason:
Because the previous blog is too long, and about the method search this piece, a lot of points are concentrated together, it is not easy to comb, now jump out of the specific implementation of each step of the steps, to overview of the process of the whole method search steps, and also review the old to learn new.
Nil can send messages to nil objects, but that doesn’t work. Typically, if you declare a button or label, you don’t need to create it, and you assign it to it at compile time.
2. Then get the isa pointer of the object, and get the message of the class through &mask.
3. Go to cacheLookup-> LLookupStart, and proceed to a different process depending on the architecture. For real machines, Config_USER_PREOPT_CACHES are 1, and proceed to a different process depending on the A12 architecture. But the two processes are just in a different order, so from a normal non-A12 perspective, the first step is to fetch the class cache by translation. TBNZ p11, #0, LLookupPreopt\Function TBNZ p11, #0, LLookupPreopt\Function If I go down. So why judge here? In the whole 64-bit environment, bucket is 48 bits lower and mask is 16 bits higher, and four maskZeroBits are reserved for objc_msgSend to determine preopT_cache_t. Then (and p10, p11, # 0x0000FFFFfffffe), 0x0000FFfffffffe Namely p10jiushi bucket. The whole third step is to fetch the cache and then the bucket from the class.
4. The next step is to obtain the corresponding index and find the bucket. Personally, THERE are many things that are not clear here, but as a process, I think understanding comes first. The whole index is obtained by moving sel 7 bits to the right (because when the hash is inserted, it is 7 bits to the right) and then &mask to obtain the index. The mask is removed from the bucket, which is 48 bits to the right to obtain the index.
Ptrshift = 3; ptrshift = 3; ptrshift = 416, the index16 is the number of displacement, which is also the bucket searched for the first time. By obtaining the bucket and then obtaining SEL and IMP in the bucket, we can compare the sel with our current sel. If yes, the cache hits, if not continue the loop.
Cachehit (‘ imp ‘); cachehit (‘ sel ‘); cachehit (‘ sel ‘); cachehit (‘ sel ‘); Until either the second step is found or MissLabelDynamic is not found.
Loop through
P9: p9: p9: p9: p9: p9: p9: p9: p9: p9: p9: p9: p9: p9: p9: p9 Also compare sel to see if it is greater than the frist_probed of bucket to prevent repeated comparisons after the loop.
If not, MissLabelDynamic is used and __objc_msgSend_uncached.
Explore __objc_msgSend_uncached
The next question is, what does the system do if it doesn’t find a method in the cache?
The first step:
The first way: We used __objc_msgSend_uncached to find the _lookUpImpOrForward method on the table, cached and cached. LookUpImpOrForward returns to C. The second way is to break the point directly in the code, go to the breakpoint will also end up in this method…
The second step:
Assembly search fast, can facilitate users to quickly find the corresponding method, however, some parameters unknown, C language can be unknown parameters definition
LookUpImpOrForward — Traversal — Slow lookup.
Initialize the
First, it will determine whether the class isInitialized (isInitialized), and then determine whether the parent class and metaclass are initialized. As long as there is an initialization, other related parent classes and metaclass will be initialized, and find methods from them (methods are in ro and rw).
recursive
The first thing to look for is the shared cache, Config_USER_PREOPT_CACHES. Then we move on to method lookup, which starts with getMethodNoSuper_nolock. CLS ->data()->methods() to get the list of methods for the class. Follow the query method respectively, search_method_list_inline – > findMethodInSortedMethodList – > M1 to go small, regular go big, in general, for example – > findMethodInSortedMethodList
Dichotomous search of apple’s brilliance co sb’s brilliance (explain)!! ~
For example, if the number is 8 (1000), then the probe = 0 + 4 = 4, (1000>>1 == 4), if the comparison method is the same, then we need to compare again, if the classification method is the same as this class, then return the current probe–; Probe = 5+ (0010>>1=1) = 6. The intermediate number changes from 4(0-8) to 6 (4-8). If it is less than, then the recirculation lookup is always a half-assed lookup, and base is only assigned if it is greater than, otherwise it is always zero.
Cache_getImp is called. If not, noIMAL is not used, and __objc_msgSend_uncached is not called. I’m going LGetImpMissDynamic, I’m going to jump out, and IMP is nil at this point, which means it’s not found in the parent class, and I’m going to loop through NSObject to find it.
LGetImpMissDynamic:
mov p0, #0
ret
Copy the code
Slow search after processing
If it does, the system calls the cache inert method, inserts it into the cache, and then reads it from the cache next time, by calling fill_log and then insert.
If not found, imp = forward_imp.