zoukankan      html  css  js  c++  java
  • CLI与Rotor中JIT(x86)的函数调用协定

    CLI Calling Conventions [in ECMA-335]

    CLI函数调用协定精确地描述了托管代码函数调用方Caller与被调用方Callee之间是如何利用堆栈来传递调用参数的。由于CLI采用了完全基于堆栈的简易虚拟机模型,因此,托管函数调用中所有的实参均通过CLI堆栈来传递。下面给出了在调用call指令之前,托管堆栈帧的构造步骤及示例:

    1. this引用压栈,如果是方法调用的话
    2. 函数调用实参从左到右进栈
    3. 如果最后一个实参是可变数量参数的话,仅需其数组引用进栈即可
    4. call/calli/callvirt等call指令返回之后,返回值或引用处于栈顶,函数调用参数全部退栈


    JIT Calling Conventions of x86
    [in Rotor 1.x]

    JIT函数调用协定主要适用于JIT生成的本地代码(Jitted Native Code)之间、及其与执行引擎内部函数之间的参数传递过程。事实上,在真实的本地代码执行过程中并不存在着一个优美而又简单的CLI虚拟堆栈。在进行即时编译时,JIT Compiler需要将抽象的CLI函数调用协议转换成为具体的面向x86本地代码的JIT函数调用方式。在Rotor 1.x与Rotor 2.0中采用了不同的JIT调用协定,后者比前者更为简洁、高效。Rotor 1.x中的JIT调用协定不仅饶舌,而且让人看起来非常费解,其设计者David Stutz在公开演讲中曾多次提到了这一点,他指出:之所以采用这种令人困惑的参数传递方式,主要是为了尽可能避免和减少对执行引擎中已有的非托管代码部分(如Stub/JIT Prestub等处)的修改,貌似有偷懒之虞...

    Rotor 1.x中的JIT函数调用协定主要分为两种类型,其步骤与示例分别如下:

    A.无可变数量参数时:
    1. 函数调用实参从左到右进栈
    2. 将栈中的实参进行重排(Reordering)
      2.1 挑选出调用参数列表中最左边的两个可放置在4字节寄存器中的实参(如类型为byte/int的变量等)
      2.2 将其值分别存进ECX和EDX寄存器
      2.3 从堆栈中删除挑选出的实参,并压缩堆栈
      2.4 EDX进栈,然后ECX进栈
    3. 函数返回缓冲区指针(Return buffer ptr)进栈,如果需要的话

    B.存在可变数量参数时:
    1. 函数调用实参从左到右进栈
    2. 栈中实参无需进行Reordering
    3. 将可变数量实参的实际参数数量压栈
    4. 将可变数量实参的元数据类型Token压栈
    5. Return buffer ptr进栈,如果需要有的话
    6. this指针进栈,如果是对象方法调用的话


    JIT Calling Conventions of x86
    [in Rotor 2.0]

    Rotor 2.0对JIT函数调用协定进行了再次的整理,其参数传递方式类似于__fastcall的改版,同时还利用了寄存器和浮点堆栈来实现整型及浮点类型的返回。相对整洁的流程及寄存器的使用令整个JIT函数调用过程得到了进一步的优化。其基本流程和2个实例如下:

    1. this指针进栈(如果是方法调用的话),然后Return buffer ptr进栈(如果需要的话)
    2. 所有非可变实参以从左至右的次序进栈
    3. 如果存在可变数量参数,则所有可变实参从左至右进栈,然后再将可变实参的类型Token压栈
    4. 从上述压栈次序中挑选出最前面两个可放置在4字节寄存器中的参数,分别存进ECX、EDX并将它们从栈中删除,然后压缩堆栈
    5. 如果返回值为浮点数,该返回值将放置在FP堆栈的栈顶返回(非调用栈栈顶!)
    6. 如果返回值为32位整数(或者是可扩充为32bit的类型),则通过EAX寄存器返回
    7. 如果返回值为64位整数,则通过EAX:EDX寄存器返回
    8. 其他返回类型一律通过Return buffer ptr返回

  • 相关阅读:
    Struts2-Spring和Hibernate整合
    windows下使用Eclipse编译执行MapReduce程序 Hadoop2.6.0/Ubuntu
    Android 基于Netty的消息推送方案之对象的传递(四)
    基于JQuery实现表单元素值的回写
    iOS 从UITableViewController中分离数据源
    navicat premium 的使用——navicat 连接MySQL数据库
    【甘道夫】Ubuntu14 server + Hadoop2.2.0环境下Sqoop1.99.3部署记录
    罗永浩和锤子手机:对不起,我被你打动了
    用C语言解决迷宫问题
    Android利用reative_layout生成梅花界面
  • 原文地址:https://www.cnblogs.com/neoragex2002/p/372720.html
Copyright © 2011-2022 走看看