1. Review of problems
Shouldn’t _maybeMask logically be 3 after a function call? Why is _maybeMask=7?Method 1: The cache calls insert when a function is inserted, so print it in insertTo debugYou can see that when you call saySomething, the system automatically calls respondsToSelector and class
Method 2: Filter print in insertThe resultsThe first one is empty, the second one is response to Selector, the third one is class, and what’s the fourth one? The imp of the last bucket is the same address as the buckets of the first bucket. The set method is used when buckets are insertedWhich function is going to call set? Reallocate is going to callAllocateBuckets functionFinally, as you can see from the comment, bucket inserts one at the last position and has a value of 1… The last one is the boundary notation, which explains why mask=capacity-1, okay
Just printed in the LLDB environment, so the code directly call is the same? The results are obvious…
Compile objc_msgSend analysis
First determine if receive is taggedPoint or nilAfter obtaining the ISA, go to
CacheLookup NORMAL, _objc_msgSend, __objc_msgSend_uncached Definition of CACHE (size of __SIZEOF_POINTER__ pointer 8) CACHE = 16
#define CACHE (2 * SIZEOF_POINTER)
LLookupPreopt \ Function: definitionLLookupStart \ Function: definitionThe macro CacheHit definitionThe macro TailCallCachedImp definition
Conclusion:
1. Check whether receive exists
2. Through receive -> ISA -> class
3. Class -> memory translation -> cache (bucket mask)
4. Bucket mask -> bucket
Mask Mask -> Mask
6. Insert hash function (mask_t)(value & mask)
7. Index of the first search
8. Bucket + index Number of buckets in the entire cache
9.bucket{imp sel}
Sel == _cmd -> cacheHit -> imp^isa = imp(br
11. If you can’t find it, bucket– pan again
12. Loop endlessly until you find it
__objc_msgSend_uncached