天天看點

ART世界探險(15) - CompilerDriver,ClassLinker,Runtime三大元件ART世界探險(15) - CompilerDriver,ClassLinker,Runtime三大元件

調用編譯器的接口是compilerdriver。

我們看一看compilerdriver的結構圖吧:

ART世界探險(15) - CompilerDriver,ClassLinker,Runtime三大元件ART世界探險(15) - CompilerDriver,ClassLinker,Runtime三大元件

這是我們在art裡能遇見的第一個複雜的大類。但凡編譯相關,都要通過它來打交道。結果,它就把自己搞成了一個大雜燴。

java是門面向對象的語言,導緻類相關的操作比較複雜。

在應用層有classloader,在運作環境層就有classlinker。

我們看一下classlinker的公開方法,私有的還有同樣多的,汗。

ART世界探險(15) - CompilerDriver,ClassLinker,Runtime三大元件ART世界探險(15) - CompilerDriver,ClassLinker,Runtime三大元件

classlinker相對于compilerdriver,邏輯上更為集中一些。

它主要是提供跟類相關的操作,包括類級的配置設定對象等。

compilerdriver提供的主要是編譯期底層代碼的功能,而classlinker在面向對象的邏輯層提供服務。

art是android runtime的縮寫,我們終于可以揭開android runtime的面紗了。

ART世界探險(15) - CompilerDriver,ClassLinker,Runtime三大元件ART世界探險(15) - CompilerDriver,ClassLinker,Runtime三大元件

runtime主要是提供一些運作時的服務,最重要的當然就是gc。另外,還有多線程和線程安全相關的支援,事務相關的支援等。

有了上面三個大元件的支援,不管是編譯期還是運作時,我們都可以找到支援java方法運作的基礎設施。

最後,我們再複習一下上節最後出現的編譯單元類:

ART世界探險(15) - CompilerDriver,ClassLinker,Runtime三大元件ART世界探險(15) - CompilerDriver,ClassLinker,Runtime三大元件

compilationunit的作用是連接配接前端和後端。

将前端的dexfile通過compilerdriver進行編譯之後,我們先得到中間層中間代碼mir,mirgraph就是這一步要做的工作。很多優化也是在這一步完成的。

然後,再通過mir2lir,将mir轉化成更接近于機器指令的低層中間代碼lir。

最後,再将lir落地成目标機器的指令。

首先我們複習一下之前學到的,dex2oat做為入口點,會調用compilerdriver的方法對dex檔案進行編譯。

ART世界探險(15) - CompilerDriver,ClassLinker,Runtime三大元件ART世界探險(15) - CompilerDriver,ClassLinker,Runtime三大元件

下面該開始compilerdriver的compileclass,看了compilerdriver的大圖之後,對于它是不是更親切了呢?

編譯類的重頭戲還在于編譯方法。

compileclass類的主要邏輯,就是針對直接方法和虛拟方法,分别周遊然後編譯。

我們将前面的判斷和校驗等細節都略過,這個函數的架構如下面所示:

從這裡開始,我們終于深入到可以生成代碼的程度了。

首先是對jni調用的處理,我們之前曾經看到過的序列。這裡會調用jnicompile函數。下面開始處理jni:

抽象方法不需要生成代碼:

下面再開始編普通方法,通過調用compile方法來完成。

如上一講我們所介紹的,art有兩種compiler,quickcompiler和optimizationcompiler。

是以,根據dex2oat參數的不同,分别調用這兩種compiler的compile方法來實作真正的編譯。

我們看一個圖來複習一下:

ART世界探險(15) - CompilerDriver,ClassLinker,Runtime三大元件ART世界探險(15) - CompilerDriver,ClassLinker,Runtime三大元件

繼續閱讀