preface
In the last Runtime Method Quick Lookup (part 1), we got the class first when we read the cache. This article will continue the lookup.
CacheLookup
When we get the class, LGetIsaDone means code down
A new function is mentioned in the continuing codeCacheLookup
With three argumentsNORMAL
._objc_msgSend
. __objc_msgSend_uncached
, we enter the method and then analyze:
To obtainbucket
And findindex
- There are several main steps:
-
- To obtain
cache_t
:ldr p11, [x16, #CACHE]
Here,x16
isp16
We know the addressp16
isclass
And the#CACHE
is16 bytes
, so here is:class
Address translation16 bytes
I just got itcache_t
.
- To obtain
-
- To obtain
buckets
:#0x0000fffffffffffe
ismaskShift
.p11 & maskShift
getbuckets
Assigned top10
.
- To obtain
-
- Gets the first lookup
index
:p1
is_cmd
.LSR
is>>
.eor
is^ (exclusive or)
. First of all,p12 = p1 ^ (p1 >> 7)
Again,p12 = p12 & mask
I get the index I’m looking forindex
.
- Gets the first lookup
-
Traversal search
bucket >= buckets
- You get what you’re looking for
bucket
, where we getbucket
The way isTranslation memory
, which is equivalent tob[i]
Same thing, and then we go through it and look for it. ldp
Is to operate both registers simultaneously, first willBuckets the address moves one bucket unit to the left
And then you getimp
andsel
Assign values top17
andp9
.p1
Are you want to depositsel
When andp9
Different time, take steps3
whensel
If it doesn’t exist, goMissLabelDynamic
whenThe first bucket to look for is the address of the buckets
When,The buckets address is moved another bucket unit to the left
Keep comparing.- when
p1 = p9
,A cache hit
Go,CacheHit
.
// CacheHit: x17 = cached IMP, x10 = address of buckets, x1 = SEL, x16 = isa
.macro CacheHit
.if $0 == NORMAL
TailCallCachedImp x17, x10, x1, x16 // authenticate and call imp
//
.macro TailCallCachedImp
// $0 = cached imp, $1 = address of cached imp, $2 = SEL, $3 = isa
// CacheHit: x17 = cached IMP, x10 = address of buckets, x1 = SEL, x16 = isa
eor $0, $0, $3 // EOR is bitwise XOR or X17 ^ class encoding IMP
br $0
Copy the code
- Here is the
Imp to decode
, and then directly returnimp
. - The search process is as follows:
- How this judgment is not found, will continue to search in the following judgment
bucket > first_probed
- There are three steps:
-
- Get the last one
bucket
- Get the last one
-
- To obtain
index
Place thebucket
- To obtain
-
- From the last one
bucket
toindex
Place thebucket
Traverse.
- From the last one
-
Find the diagram below:
- If I finish it, I still can’t find it, I’ll go
__objc_msgSend_uncached
Methods:
Cache lookup process
- The entire cache lookup process is as follows:
Assembly correlation symbol
The assembler notation | |
---|---|
cmp | To compare |
b.le | Less than |
b.eq | equal |
ldr | Reads the instruction to the target register |
mov | Store data in a register |
and | &(by bit and) |
tbnz | The jump is not 0 |
LSR | > > (right) |
eor | ^(bitwise xOR) |
LSL | < < (left) |
ldp | Operate two registers |
b.ne | Not equal to the |
cbz | Whether there is a jump or not |
br | Jump instruction |
b.hs | Greater than or equal to |
b.hi | Is greater than |
ccmp | A condition |
conclusion
- Began to go to the assembly, the heart is still more terrified, after all, there are a lot of symbols do not know. But calm down to analyze carefully, slowly simplify a lot of steps, follow the symbol step by step, and finally completed the process.