CLR 虚方法调用和接口方法调用
对,MSIL里都是callvirt,但JIT的时候得到了不同的处理:
对虚方法的分发是编译成这样:
- mov ecx, esi ; 假设现在ESI是一个指向对象实例的指针,复制到ECX里
- mov eax, dword ptr [ecx] ; 对象实例的第一项是指向方法表的指针,复制到EAX里
- call dword ptr [eax + 7Ch] ; EAX现在指向方法表,0x7C是我随便写的一个偏移量。这个在加载类的时候就可以确定
mov ecx, esi ; 假设现在ESI是一个指向对象实例的指针,复制到ECX里
mov eax, dword ptr [ecx] ; 对象实例的第一项是指向方法表的指针,复制到EAX里
call dword ptr [eax + 7Ch] ; EAX现在指向方法表,0x7C是我随便写的一个偏移量。这个在加载类的时候就可以确定
对接口方法的分发是编译成:
- mov ecx, esi ; 跟上面一样,ESI是指向对象的指针,复制到ECX
- call dword ptr [0099EEA0h] ; JIT的时候指向一个固定地址的stub(这里数字是随便编的,别在意)
mov ecx, esi ; 跟上面一样,ESI是指向对象的指针,复制到ECX
call dword ptr [0099EEA0h] ; JIT的时候指向一个固定地址的stub(这里数字是随便编的,别在意)
这个call是对一个固定地址做间接调用。一开始是调用到一个通用的resolver stub,去找具体的方法的地址。如果在同一个调用点出现两次相同类型的被调用对象,则间接调用会指向为该类型特化的一个dispatch stub上,样子类似这样:
- cmp dword ptr [ecx], 009A3377h ; 后面的常量是特定类型的方法表地址
- jne 0091A012 ; 比较不相等的话,跳转到一个特定的resolver stub上
- jmp 00EBD070 ; 相等的话则直接跳转到目标方法的地址
cmp dword ptr [ecx], 009A3377h ; 后面的常量是特定类型的方法表地址
jne 0091A012 ; 比较不相等的话,跳转到一个特定的resolver stub上
jmp 00EBD070 ; 相等的话则直接跳转到目标方法的地址
这段代码被称为monomorphic inline method cache,怎么翻译好呢……单态内联方法缓存? 比较失败时会跳转到一个resolver stub;它会维护一个“不命中计数器”。如果在某个调用点累计失败了100次,就会再次更新之前的间接调用为直接指向通用的resolver stub。
这样,如果在一个接口方法的调用点上总是同一个类型的实例被调用,则分发效率跟虚方法调用差不多快。如果被调用对象的类型经常变,速度就会慢下来了……
CLR 虚方法调用和接口方法调用的更多相关文章
- 30分钟入门Java8之默认方法和静态接口方法
30分钟入门Java8之默认方法和静态接口方法 前言 上一篇文章30分钟入门Java8之lambda表达式,我们学习了lambda表达式.现在继续Java8新语言特性的学习,今天,我们要学习的是默认方 ...
- Java8之默认方法和静态接口方法
前言 上一篇文章30分钟入门Java8之lambda表达式,我们学习了lambda表达式.现在继续Java8新语言特性的学习,今天,我们要学习的是默认方法和静态接口方法. 这一Java8的新语言特性, ...
- Java调用webservice接口方法
java调用webservice接口 webservice的 发布一般都是使用WSDL(web service descriptive langu ...
- 关于使用axis调用webservice接口方法
1.概述: 我们有时候会调用webserviec接口,我们向接口发送请求参数,从接口接收返回值. 2.形式: package client; import org.apache.axis.client ...
- Java调用webservice接口方法(SOAP message、xfire、axis)
webservice的 发布一般都是使用WSDL(web service descriptive language)文件的样式来发布的,在WSDL文件里面,包含这个webservice暴露在外面可供使 ...
- 三种方法实现调用Restful接口
1.基本介绍 Restful接口的调用,前端一般使用ajax调用,后端可以使用的方法比较多, 本次介绍三种: 1.HttpURLConnection实现 2.HttpClient实现 3.Spring ...
- HTTP调用接口方法
1.创建接口调用方法类 package cn.com.victorysoft.sjzx.Message; import java.io.BufferedReader; import java.io.I ...
- JNI-Thread中start方法的调用与run方法的回调分析
前言 在java编程中,线程Thread是我们经常使用的类.那么创建一个Thread的本质究竟是什么,本文就此问题作一个探索. 内容主要分为以下几个部分 1.JNI机制的使用 2.Thread创建线程 ...
- Java调用第三方接口工具类(json、form)
1.JSON值访问 /** * 调用对方接口方法 * @param path 对方或第三方提供的路径 * @param data 向对方或第三方发送的数据,大多数情况下给对方发送JSON数据让对方解析 ...
随机推荐
- docker系列之六容器数据卷
docker之容器数据卷 一.容器数据卷 docker容器运行的时候,会产生一系列的文件,那么我们希望容器产生的数据能提供给其他的容器使用,也就是说怎么实现容器间的数据的共享呢?这就需要用到我们所提到 ...
- leetcode-29.两数相除(不用乘除法和mod)
如题,不用乘除法和mod实现两数相除. 这里引用一位clever boy 的解法. class Solution { public: int divide(int dividend, int divi ...
- WordPress,SAP Kyma和微信三者的集成
我们来继续学习如何在实战中使用SAP Kyma. Jerry在之前的文章里,分别介绍了如何本地搭建WordPress实例: 什么?在SAP中国研究院里还需要会PHP开发? 以及如何把这个本地搭建的Wo ...
- 1.volatile关键字 内存可见性
Java JUC 简介 在 Java 5.0 提供了 java.util.concurrent (简称JUC )包,在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自定义子系统,包括 ...
- 用java代码实现
用java代码实现(1)珠穆朗玛峰高度为8848米,有一张足够大的纸,厚度为0.001米. (2)请问,我折叠多少次,可以折成珠穆朗玛峰的高度/** * @author 18269 * @date 2 ...
- 初识cv
验证码识别的一般套路: 灰度化.图像处理.二值化.选算法.训练.评估调整参数.预测,当然,我在这里二值化与处理的顺序换了一下,灵活处理哈 1 显示图片轮廓 img = cv2.Canny(img,25 ...
- Android休眠唤醒机制
有四种方式可以引起休眠 ①在wake_unlock()中, 如果发现解锁以后没有任何其他的wake lock了, 就开始休眠 ②在定时器到时间以后, 定时器的回调函数会查看是否有其他的wake loc ...
- Linux命令——umask、setuid、setgid、sticky bit、chmod、chown
umask 权限遮罩码,用于控制文件,文件夹的默认权限 文件默认权限: 666-umask 文件夹默认权限: 777-umask 管理员root: umask= ...
- 通过Chrome控制台详细查看ajax请求
1.F12打开浏览器开发者工具 2.如图所示
- 第六章 Flask-WTF(二)
Flask-WTF Flask-WTF是简化了WTForms操作的一个第三方库. WTForms表单的两个主要功能是验证用户提交数据的合法性以及渲染模板. 当然还包括一些其他的功能:CSRF保护,文件 ...