不知接口方法和虚方法分发有什么区别?似乎在CIL中都是callvirt指令。

对,MSIL里都是callvirt,但JIT的时候得到了不同的处理:
对虚方法的分发是编译成这样:

  1. mov  ecx, esi              ; 假设现在ESI是一个指向对象实例的指针,复制到ECX里
  2. mov  eax, dword ptr [ecx]  ; 对象实例的第一项是指向方法表的指针,复制到EAX里
  3. 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是我随便写的一个偏移量。这个在加载类的时候就可以确定

对接口方法的分发是编译成:

  1. mov  ecx, esi             ; 跟上面一样,ESI是指向对象的指针,复制到ECX
  2. call dword ptr [0099EEA0h] ; JIT的时候指向一个固定地址的stub(这里数字是随便编的,别在意)
mov  ecx, esi             ; 跟上面一样,ESI是指向对象的指针,复制到ECX
call dword ptr [0099EEA0h] ; JIT的时候指向一个固定地址的stub(这里数字是随便编的,别在意)

这个call是对一个固定地址做间接调用。一开始是调用到一个通用的resolver stub,去找具体的方法的地址。如果在同一个调用点出现两次相同类型的被调用对象,则间接调用会指向为该类型特化的一个dispatch stub上,样子类似这样:

  1. cmp dword ptr [ecx], 009A3377h ; 后面的常量是特定类型的方法表地址
  2. jne 0091A012                   ; 比较不相等的话,跳转到一个特定的resolver stub上
  3. jmp 00EBD070                   ; 相等的话则直接跳转到目标方法的地址
cmp dword ptr [ecx], 009A3377h ; 后面的常量是特定类型的方法表地址
jne 0091A012 ; 比较不相等的话,跳转到一个特定的resolver stub上
jmp 00EBD070 ; 相等的话则直接跳转到目标方法的地址

这段代码被称为monomorphic inline method cache,怎么翻译好呢……单态内联方法缓存? 比较失败时会跳转到一个resolver stub;它会维护一个“不命中计数器”。如果在某个调用点累计失败了100次,就会再次更新之前的间接调用为直接指向通用的resolver stub。
这样,如果在一个接口方法的调用点上总是同一个类型的实例被调用,则分发效率跟虚方法调用差不多快。如果被调用对象的类型经常变,速度就会慢下来了……

CLR 虚方法调用和接口方法调用的更多相关文章

  1. 30分钟入门Java8之默认方法和静态接口方法

    30分钟入门Java8之默认方法和静态接口方法 前言 上一篇文章30分钟入门Java8之lambda表达式,我们学习了lambda表达式.现在继续Java8新语言特性的学习,今天,我们要学习的是默认方 ...

  2. Java8之默认方法和静态接口方法

    前言 上一篇文章30分钟入门Java8之lambda表达式,我们学习了lambda表达式.现在继续Java8新语言特性的学习,今天,我们要学习的是默认方法和静态接口方法. 这一Java8的新语言特性, ...

  3. Java调用webservice接口方法

                             java调用webservice接口   webservice的 发布一般都是使用WSDL(web service descriptive langu ...

  4. 关于使用axis调用webservice接口方法

    1.概述: 我们有时候会调用webserviec接口,我们向接口发送请求参数,从接口接收返回值. 2.形式: package client; import org.apache.axis.client ...

  5. Java调用webservice接口方法(SOAP message、xfire、axis)

    webservice的 发布一般都是使用WSDL(web service descriptive language)文件的样式来发布的,在WSDL文件里面,包含这个webservice暴露在外面可供使 ...

  6. 三种方法实现调用Restful接口

    1.基本介绍 Restful接口的调用,前端一般使用ajax调用,后端可以使用的方法比较多, 本次介绍三种: 1.HttpURLConnection实现 2.HttpClient实现 3.Spring ...

  7. HTTP调用接口方法

    1.创建接口调用方法类 package cn.com.victorysoft.sjzx.Message; import java.io.BufferedReader; import java.io.I ...

  8. JNI-Thread中start方法的调用与run方法的回调分析

    前言 在java编程中,线程Thread是我们经常使用的类.那么创建一个Thread的本质究竟是什么,本文就此问题作一个探索. 内容主要分为以下几个部分 1.JNI机制的使用 2.Thread创建线程 ...

  9. Java调用第三方接口工具类(json、form)

    1.JSON值访问 /** * 调用对方接口方法 * @param path 对方或第三方提供的路径 * @param data 向对方或第三方发送的数据,大多数情况下给对方发送JSON数据让对方解析 ...

随机推荐

  1. vue 实现的评分小星星组件,包括半星

    github源码地址:https://github.com/13476075014/node-vue/blob/master/mynodeproject/13.sell/sell/src/compon ...

  2. 全面聊聊JavaScript的浅拷贝和深拷贝

    一.背景      首先我们可以看下面这段简单的代码: var obj = {name:'程序猿',sex:'男'}; var arr = ['程序猿','程序媛']; var copyobj = o ...

  3. python 操作Hbase 详解

    博文参考:https://www.cnblogs.com/tashanzhishi/p/10917956.html 如果你们学习过Python,可以用Python来对Hbase进行操作. happyb ...

  4. php+redis一步一步测试秒杀

    1.普通的秒杀查库减库存: <?php /** 100个用户同时访问100次会出现超卖 **/ //连接数据库 $dsn = "mysql:host=localhost;dbname= ...

  5. ubuntu---记录.简单一句话安装tf

    卸载 sudo pip3 uninstall tensorflow sudo pip3 uninstall tensorflow-gpu sudo pip3 uninstall tensorflow- ...

  6. windwos服务器 无法与本地电脑进行复制粘贴解决办法

    之前复制粘贴功能可以使用  现在突然间不能使用了 1.打开任务管理器,查看进程,如果有 rdpclip.exe 进程,先关闭该进程2.开始->运行->rdpclip.exe,重新运行此程序 ...

  7. request.querystring和request.form的区别

    1,request.querystring和request.form的区别 request.querystring是用来接收地址里面问号“?”后面的参数的内容,  用get方法读取的 不安全 requ ...

  8. Django REST framework+Vue 打造生鲜电商项目(笔记二)

    (转自https://www.cnblogs.com/derek1184405959/p/8768059.html)(有修改) 接下来开始引入django resfulframework,体现它的强大 ...

  9. 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 ...

  10. .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: ...