《你必須知道的.NET》讀書筆記:方法表初窺


一、窺探准備工作

    public class Base
    {
        public void M()
        {
            Console.WriteLine("M in Base");
        }

        public virtual void N()
        {
            Console.WriteLine("N in Base");
        }
    }

    public class Three : Base
    {
        private static int ID
        {
            get;
            set;
        }

        public override void N()
        {
            // Something new in class Three
            Console.WriteLine("N in Three");
        }

        public void M()
        {
            Console.WriteLine("M in Three");

            M1();
        }

        public void M1()
        {
            Console.WriteLine("M1 in Three");
        }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            Base three = new Three();
            three.M();
            three.N();

            Console.ReadKey();
        }
    }

  調試運行,執行結果如下圖所示:

      

二、窺探方法表執行過程

2.1 方法表的創建

  執行Main方法調用時,Three實例的創建與相應類型的加載也隨之發生。然而,類型加載是在實例創建之前完成的,也就是我們常常說到的方法表創建。當程序執行到three.N()處時,Three類型的方法表如下圖所示:

2.2 總體執行過程

  (1)class loader 從元數據表加載相關元數據信息,根據信息創建方法表(這里主要是指CORINFO_CLASS_STRUCT結構

  (2)加載后,方法表槽都保存了應該執行的行為邏輯,這些信息保存在方法描述(Method Desc)結構中,MethodDesc被初始化為指向IL代碼,同時還包含一個指向觸發JIT編譯的PreJitStub地址

2.3 具體執行過程

  這里以N()方法來看看其具體的執行過程:

  (1)任何方法第一次執行時都會首先觸發執行JIT編譯,JIT編譯的主要工作就是將IL代碼翻譯為本地代碼,並插入指向本地代碼的jmp指令地址覆蓋原來的Call JIT Complier指令

  (2)當該方法再次被執行,因為方法描述(MethodDesc結構)中保存了機器碼地址,以后的執行將不會執行JIT編譯過程而直接執行機器碼,實現整個執行過程。

三、小結

  Metadata描述了靜態的結構,而IL闡述了動態的執行,一靜一動承載着很多的技術奧秘。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM