2015-08-20 85 views
0

請考慮以下情況。 正如您在Main()執行之前所知CLR爲Main()中的每個引用類型分配內部數據結構,其中包含引用類型中定義的每個方法的條目。隨後,每個條目將參考(存根)保存到存儲相應本地代碼的存儲器塊中。 假設在執行Main()內的代碼時JITter遇到方法SomeClass1.M1()。 SomeClass1被引用來查找相關的IL代碼。
所以這裏的問題是:
- 當CLR撞到M1()內部的另一個方法調用時會發生什麼,比如SomeClass2.M2()。這是否意味着包含SomeClass2方法的第二個數據結構被創建,然後本地代碼的地址將被綁定到相應的方法?如果是,那麼:
- 什麼將被存儲在第一個數據結構中?
- 如果M1()的描述立即開始調用M2(),並且M1()內部還有一些跟隨M2()的代碼,那麼將存儲在第一個數據結構中的內容是什麼。當JITter在方法的定義中遇到另一個方法調用時會發生什麼?

不幸的是,我在網上找到的所有內容都是一種說法,稱該方法的IL代碼只是編譯爲本地代碼,然後執行。

因此,如果我的假設不正確,請提供您的意見。
謝謝!

+0

這個問題很難回答。你可能想看看JIT [源代碼](https://github.com/dotnet/coreclr/tree/master/src/jit)。 –

回答

0

在進行了一些額外的研究之後,我遇到了「Essential .NET:通用語言運行時」中提供的詳細說明。 最初,程序中初始化的每種類型都由一個數據結構表示,由一個方法表組成。通過調用JITter過程(JITter)來初始化表的每個條目。

所以調用SomeClass1.M1()意味着控件被傳遞給JITter過程(通過JMP指令),該過程將各自的IL代碼編譯成機器代碼。如果M1()中有其他子方法(如SomeClass2.M2()),它們將通過「調用」指令從機器代碼中引用(每個調用指令將引用前面提到的方法表中的相應方法條目)。

已編譯IL代碼JITter將本地指令的存儲位置返回到方法表的相應條目。




之後,執行一段剛剛編譯的代碼片段,一旦CLR遇到子方法調用,它將引用方法表的相應條目以查看它是否包含本機指令的地址或JITer調用。如果是後者,則再次調用JITter,否則使用JMP指令(帶地址引用)來執行本地代碼塊。

相關問題