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数据让对方解析 ...
随机推荐
- vue 实现的评分小星星组件,包括半星
github源码地址:https://github.com/13476075014/node-vue/blob/master/mynodeproject/13.sell/sell/src/compon ...
- 全面聊聊JavaScript的浅拷贝和深拷贝
一.背景 首先我们可以看下面这段简单的代码: var obj = {name:'程序猿',sex:'男'}; var arr = ['程序猿','程序媛']; var copyobj = o ...
- python 操作Hbase 详解
博文参考:https://www.cnblogs.com/tashanzhishi/p/10917956.html 如果你们学习过Python,可以用Python来对Hbase进行操作. happyb ...
- php+redis一步一步测试秒杀
1.普通的秒杀查库减库存: <?php /** 100个用户同时访问100次会出现超卖 **/ //连接数据库 $dsn = "mysql:host=localhost;dbname= ...
- ubuntu---记录.简单一句话安装tf
卸载 sudo pip3 uninstall tensorflow sudo pip3 uninstall tensorflow-gpu sudo pip3 uninstall tensorflow- ...
- windwos服务器 无法与本地电脑进行复制粘贴解决办法
之前复制粘贴功能可以使用 现在突然间不能使用了 1.打开任务管理器,查看进程,如果有 rdpclip.exe 进程,先关闭该进程2.开始->运行->rdpclip.exe,重新运行此程序 ...
- request.querystring和request.form的区别
1,request.querystring和request.form的区别 request.querystring是用来接收地址里面问号“?”后面的参数的内容, 用get方法读取的 不安全 requ ...
- Django REST framework+Vue 打造生鲜电商项目(笔记二)
(转自https://www.cnblogs.com/derek1184405959/p/8768059.html)(有修改) 接下来开始引入django resfulframework,体现它的强大 ...
- 15、Spring Boot 2.x 集成 Swagger UI
1.15.Spring Boot 2.x 集成 Swagger UI 完整源码: Spring-Boot-Demos 1.15.1 pom文件添加swagger包 <swagger2.versi ...
- .NET调用AS/400上的程序(.NET CALL AS/400 PGM)
http://www.3rgb.com/entry/dotnet_call_as400_program2 .NET连接AS400出现[Safe handle has been closed http: ...