iOS 底层原理探索 之 objc_msgSend

前言: iOS底层原理探究是本人在平时的开发和学习中不断积累的一段进阶之
路的。 记录我的不断探索之旅,希望能有帮助到各位读者朋友。

目录如下:

  1. iOS 底层原理探索 之 alloc
  2. iOS 底层原理探索 之 结构体内存对齐
  3. iOS 底层原理探索 之 对象的本质 & isa的底层实现
  4. iOS 底层原理探索 之 isa - 类的底层原理结构(上)
  5. iOS 底层原理探索 之 isa - 类的底层原理结构(中)
  6. iOS 底层原理探索 之 isa - 类的底层原理结构(下)
  7. iOS 底层原理探索 之 Runtime运行时&方法的本质

前言

在上一篇,我们探索了 Runtime 以及与 Runtime 交互的三种方式,和总结了 方法的本质其实是消息发送的过程。今天接着上一篇继续 objc_msgSend汇编分析

objc_msgSend汇编分析

  1. cmp p0, #0 : p0为此次的消息接受者,拿来和0比较,判断消息接受者是否为0,如果没有消息接受者,则此次 objc_msgSend 没有意义。

  2. #if SUPPORT_TAGGED_POINTERS 判断是否为 SUPPORT_TAGGED_POINTERS 类型,如果是,则执行 b.le LNilOrTagged, 否则, 执行 b.eq LReturnZero,即返回此次消息为空。

  3. ldr p13, [x0]x0存入到p13,x0receiver,即类,即类的首地址,即isa,也就是说p13=isa

  4. 进入 GetClassFromIsa_p16 带入参数 src=p13, needs_auth=1, auth_address=x0. 判断是不是 SUPPORT_INDEXED_ISA (32位isa),不满足此条件,接下来会进入 __LP64__ (这份源码里指的是Mac OS X)分支。

  5. 由于_need_auth=1,进入分支 ExtractISA p16, \src, \auth_address ,此ExtractISA 为宏,操作是将\src(isa)、#ISA_MASK做与操作,得到了Class,结果存入到p16中。

  6. LGetIsaDone:获取isa完成。接下来执行CacheLookup NORMAL, _objc_msgSend, __objc_msgSend_uncached

6.1 `mov    x15, x16`   隐藏isa,将x16寄存器赋值到 x15 

6.2  `ldr   p11, [x16, #CACHE]`  #define CACHE 8,那么p11=x16+0x8,等同于 isa+0x8, 即isa向右偏移了8字节,拿到了cache_t,即 p11=cache_t (我们探索真机环境也就是arm64的汇编,所以是CACHE_MASK_STORAGE == CACHE_MASK_STORAGE_HIGH_16分支)

6.3 在 `CONFIG_USE_PREOPT_CACHES` 分支中,我们探索非A12及以后芯片,所以 不进入到 `#if __has_feature(ptrauth_calls)` 分支, 所以 执行 `and    p10, p11, #0x0000fffffffffffe` 将p11与上#0x0000fffffffffffe (preoptBucketsMask) 得到 buckets() 的地址,存储在 p10中。 然后执行 `tbnz  p11, #0, LLookupPreopt\Function` , 作用是验证p11, 也就是 cache_t 是不是为0, 如果为0, 则证明没有缓存, 没有向下继续查找 bucket的必要, 跳转至 `LLookupPreopt`。

6.4 `eor    p12, p1, p1, LSR #7`  , 因为 p0 寄存器是 receiver, p1 寄存器为第二个参数, SEL _cmd, 所以p1 = _cmd,对应上面的指令就是得出, p12 = (_cmd >> 7) ^ _cmd

6.5 `and    p12, p12, p11, LSR #48` , p11 = cache_t = _bucketsAndMaybeMaske, 可以翻译成 p12 = p12 & (_bucketsAndMaybeMask >> 48), 这个指令最终的结果是找到已知buckets的index。

6.6 `add    p13, p10, p12, LSL #(1+PTRSHIFT)` , PTRSHIFT 在 `__LP64__` 下的值为3,否则为2, 我们探索的64位的,所以, PTRSHIFT=3,p10 是 buckets, p12 是 index, 那么可以将上述指令翻译为 : p13 = p10 + (p12 << (1+3)), 将 index 左移4位, 然后将得到结果n, 在buckets的首地址上移动相应n个步长,找到最终的bucket_t。

6.7 `1: ldp p17, p9, [x13], #-BUCKET_SIZE`将 x13 寄存器的值取出来放在 p17和p9, 因为x13 为bucket_t结构体,在arm64架构下,第一个值是imp,第二个值是sel,所以p17=imp,p9=sel。

6.8 `cmp    p9, p1` 比较p1和p9,即比较在缓存中取出来的sel和objec_msgSend的第二个参数——cmd,如果不等,向后跳转,执行命令 `b.ne    3f` ,将执行三条指令: 

  6.8.1 `cbz    p9, \MissLabelDynamic` :找不到sel 所以 MissLabelDynamic

6.8.2 `cmp  p13, p10` 循环查找的条件,当要查找的bucket_t的地址大于buckets的首地址的时候,继续查找

6.8.3 `b.hs 1b` 重新回到 1 执行sel的比较,如果相等,`2:CacheHit \Mode` 即命中了缓存中的方法,找到了缓存,进入到 CacheHit

6.7 `CacheHit` 分为 三种模式,`NORMAL`,`GETIMP`,`LOOKUP`;无论哪种,最终结果都是将去查找sel对应的imp,然后将其返回。

流程图

objc_msgSend.001.jpeg
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容