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 codeCacheLookupWith three argumentsNORMAL._objc_msgSend. __objc_msgSend_uncached, we enter the method and then analyze:

To obtainbucketAnd findindex

  • There are several main steps:
      1. To obtaincache_t:ldr p11, [x16, #CACHE]Here,x16isp16We know the addressp16isclassAnd the#CACHEis16 bytes, so here is:classAddress translation16 bytesI just got itcache_t.
      1. To obtainbuckets:#0x0000fffffffffffeismaskShift.p11 & maskShiftgetbucketsAssigned top10.
      1. Gets the first lookupindex:p1is_cmd.LSRis>>.eoris^ (exclusive or). First of all,p12 = p1 ^ (p1 >> 7)Again,p12 = p12 & maskI get the index I’m looking forindex.

Traversal search

bucket >= buckets

  • You get what you’re looking forbucket, where we getbucketThe way isTranslation memory, which is equivalent tob[i]Same thing, and then we go through it and look for it.
  • ldpIs to operate both registers simultaneously, first willBuckets the address moves one bucket unit to the leftAnd then you getimpandselAssign values top17andp9.
  • p1Are you want to depositselWhen andp9Different time, take steps3whenselIf it doesn’t exist, goMissLabelDynamicwhenThe first bucket to look for is the address of the bucketsWhen,The buckets address is moved another bucket unit to the leftKeep comparing.
  • whenp1 = p9,A cache hitGo,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 theImp 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:
      1. Get the last onebucket
      1. To obtainindexPlace thebucket
      1. From the last onebuckettoindexPlace thebucketTraverse.

Find the diagram below:

  • If I finish it, I still can’t find it, I’ll go__objc_msgSend_uncachedMethods:

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.