什麼時候有資格被 CLR 內聯的方法?
我在應用程序中觀察到很多“堆棧內省”程式碼,這些程式碼通常隱含地依賴於它們的包含方法,而不是為了它們的正確性而內聯。此類方法通常涉及呼叫:
MethodBase.GetCurrentMethodAssembly.GetCallingAssemblyAssembly.GetExecutingAssembly現在,我發現圍繞這些方法的資訊非常混亂。我聽說執行時不會內聯呼叫 GetCurrentMethod 的方法,但我找不到任何相關文件。我曾多次在 StackOverflow 上看到過文章,例如這個,表明 CLR 沒有內聯跨彙編呼叫,但
GetCallingAssembly文件強烈表明並非如此。還有飽受詬病的
[MethodImpl(MethodImplOptions.NoInlining)],但我不確定 CLR 是否認為這是“請求”或“命令”。請注意,我從合同的角度詢問內聯資格,而不是關於 JITter 的目前實現何時因實施困難而拒絕考慮方法,或者 JITter在評估交易後最終最終選擇內聯合格方法的時間 -關閉。我讀過這個和這個,但他們似乎更關注最後兩點(有提到 MethodImpOptions.NoInlining 和“exotic IL instructions”,但這些似乎是作為啟發式而不是作為義務提出的)。
什麼時候允許CLR內聯?
這是一個抖動實現細節,x86 和 x64 抖動有細微的不同規則。這在處理抖動的團隊成員的部落格文章中隨意記錄,但團隊當然保留更改規則的權利。看起來你已經找到它們了。
肯定支持來自其他程序集的內聯方法,如果不是這種情況,許多 .NET 類的工作將非常糟糕。當您查看為 Console.WriteLine() 生成的機器程式碼時,您可以看到它在工作,當您傳遞一個簡單的字元串時,它通常會被內聯。要親自查看此內容,您需要切換到 Release 版本並更改調試器選項。工具 + 選項,調試,正常,取消勾選“在模組載入時抑制 JIT 優化”。
否則沒有充分的理由考慮 MethodImpOptions.NoInlining 誹謗,這就是它首先存在的原因。事實上,它是有意在 .NET 框架中用於呼叫內部輔助方法的許多小型公共方法上的。它使異常堆棧跟踪更容易診斷。