HGraphBuilder方法分析一

2021-08-02 04:09:06 字數 3376 閱讀 7403

在~/android-6.0.1_r62/art/compiler/optimizing/builder.cc中為類hgraphbuilder的具體資訊:

1/首要分析的方法為:

bool analyzedexinstruction(const instruction& instruction, uint32_t dex_pc);

該方法的主要功能是分析dex instruction,將hinstruction新增到graph中以可以執行該dex instruction。返回值意為,該dex instruction是否能被處理。

具體實現:

a.1317 if (current_block_ == nullptr)

先檢查current_block_ == nullptr,若相等,則直接返回真。

b. switch (instruction.opcode())

根據opcode的不同進行不同的處理,類instruction中定義了dex instruction,opcode()方法返回的是instruction的opcode field,也就是instruction的前16位。

下面以const_4為例,總共只有三行**。

1322

case instruction::const_4:

其中const_4為dalvik指令const/4:

const/4 va,#+b 將數值符號擴充套件為32位後賦值給暫存器va。

關於dalvik指令更詳細的介紹在~/android-6.0.1_r62/art/runtime/dex_instruction_list.h中,例如對於const_4:

#define dex_instruction_list(v) \

v(0x12, const_4, "const/4", k11n, true, knone, kcontinue | kregbfieldorconstant, kverifyrega)

①int32_t register_index = instruction.vrega();

57

inline int32_t instruction::vrega() const

關於dalvik指令的一些知識:

暫存器有兩種不同的命名方法:v字命名法和p字命名法;以小寫字母v開頭的方式表示方法中使用的區域性變數和引數;以小寫字母p開頭的方式表示引數,引數名稱從p0開始,依次增大.區域性變數能夠使用的暫存器仍然是以v開頭.

以指令格式「a|g|op bbbb f|e|d|c」為例:

指令中間有兩個空格,每個分開的部分大小為16位,所以這條指令由三個16位的字組成。第乙個16位是「a|g|op」,高8位由a與g組成,低位元組由操作碼op組成。第二個16位由bbbb組成,它表示乙個16位的偏移值。第三個16位分別由f,e,d,c共四個4位組成,在這裡它們表示暫存器引數。

11n有特殊的含義:

1:指令有多少個16位的字組成

1:指令最多使用暫存器的個數

n:4位的立即數

以指令 「op vaa, string@bbbb」 為例:指令用到了1個暫存器引數 vaa,並且還附加了乙個字串常量池索引 string@bbbb,其實這條指令格式代表著 const-string 指令。

指令格式標示等的參考文獻:

根據dex_ instruction_ list中的定義可知:const_ 4屬於k11n,所以返回的是vrega_11n(),該函式的具體實現如下:

244   uint4_t vrega_11n() const 

532 uint16_t fetch16(size_t offset) const

556 uint4_t insta(uint16_t inst_data) const

②hintconstant* constant = graph_ ->getintconstant(instruction.vregb_11n());

getintconstant函式的具體實現為:

(在~/android-6.0.1_r62/art/compiler/optimizing/nodes.h的class:art::hgraph中)

266   hintconstant* getintconstant(int32_t value) 

//首先試著在cache中尋找給定value的已有的常量,如果沒有找到,或者已經被刪掉了,那麼就建立並cache乙個新的指令,最後返回常量。

301 instructiontype* createconstant(valuetype value,

302 arenasafemap*

cache)

309310// if not found or previously deleted, create and cache a new instruction.

311if (constant == nullptr || constant->getblock() == nullptr)

316return constant;

317 }

③updatelocal(register_index, constant);

(在~/android-6.0.1_r62/art/compiler/optimizing/builder.cc中)

2295

void hgraphbuilder::updatelocal(int register_index, hinstruction* instruction) const

2291 hlocal* hgraphbuilder::getlocalat(int register_index) const

//hstorelocal的建構函式

2190 hstorelocal(hlocal*

local, hinstruction* value) : htemplateinstruction(sideeffects::none())

//~/android-6.0.1_r62/art/compiler/optimizing/nodes.cc中實現:

483void hbasicblock::addinstruction(hinstruction* instruction)

472 static void add(hinstructionlist* instruction_list,

473 hbasicblock* block,

474 hinstruction* instruction)

方法的呼叫 this方法 構造方法

1 呼叫者和被呼叫者方法位於同一類中,呼叫形式如下 this 方法名 在大多數情況下,關鍵字this可以忽略 呼叫者位於被呼叫方法所在類的外部 物件名.方法名或者類名.方法名 抽象類只能作為父類,不能例項化。只能被繼承 抽象方法是一種只有方法宣告而沒有方法體定義的特殊方法,最後有乙個分號 而沒有方法...

例項方法 靜態方法 類方法

首先新建乙個日期date類,屬性為年,月,日,tomorrow 是例項方法,這個最常見,比較簡單,例項方法的第乙個引數是例項物件self 當我們傳入的年月日是2018 6 4這樣的形式,我們就需要先進行字串處理,在這裡使用了元組的拆包 這是最基本的方式,但是這樣寫會有乙個問題,每次傳參都需要進行字串...

類方法 物件方法 原型方法

js類方法,物件方法,原型的理解 function people name 類方法 people.run function 原型方法 people.prototype.introducechinese function 測試 var p1 new people windking p1.introdu...