![](/img/trans.png)
[英]How to get class files or Dalvik byte code of standard java libraries that are used by Dalvik VM?
[英]How does mterp (Dalvik VM) organize its byte-code interprete loop?
我正在研究Android Dalvik VM,當我在文件vm / mterp / out / InterpC-portable.cpp中讀取mterp代碼時會遇到一個問題。 實際上它是dalvik vm的主要解釋器循環來解釋dex文件中的字節代碼。 如果我寫了這個文件,我會選擇一個switch-case結構來做這樣的事情:
while (hasMoreIns()) {
int ins = getNextIns();
switch(ins) {
case MOV:
//interprete this instruction
...
break;
case ADD:
...
break;
...
default: break;
}
}
然而,mterp使用的與我的想法非常不同,它使用了一些神奇的代碼(對我而言),如下所示:
FINISH(0);
HANDLE_OPCODE(OP_NOP)
FINISH(1);
OP_END
HANDLE_OPCODE(OP_MOVE)
...
OP_END
...
我谷歌它發現它似乎是一個修改過的“線程”式執行,它與switch-case風格不同,並且具有更好的性能,因為它刪除了while循環中的分支操作。 但我仍然無法理解這段代碼以及為什么它在性能上更好。 它是如何找到解釋器的下一個代碼的?
作為一個簡短的指導, out
目錄中填充了預處理文件,如果你想弄清楚代碼的話,那就不是我想要讀的好東西了。 與InterpC-portable.cpp
對應的源(本身)是portable
和c
目錄的內容。
就代碼如何進行操作碼調度而言,您需要在portable/stubdefs.cpp
FINISH
宏的定義:
# define FINISH(_offset) { \
ADJUST_PC(_offset); \
inst = FETCH(0); \
if (self->interpBreak.ctl.subMode) { \
dvmCheckBefore(pc, fp, self); \
} \
goto *handlerTable[INST_INST(inst)]; \
}
此宏在每個操作碼定義的末尾使用,並用作switch (opcode)
語句的等效項。 簡而言之,它讀取PC指向的指令代碼單元 - inst = FETCH(0)
- 從其中獲取操作碼 - INST_INST(inst)
- 並使用該操作碼作為所有操作碼的地址表的索引。 地址直接用goto
語句分支。
goto
是一個“計算goto”,它是一個非標准的GCC擴展。 您可以在GCC手冊中閱讀相關內容,您也可以在2008年我在Google IO上的Dalvik內部演示文稿中找到有關該主題的內容。(在https://sites.google.com/site上查找) / io / dalvik-vm-internals 。)
我的演講還談到了這項技術的性能特征。 簡而言之,它節省了一些分支並且在分支預測方面起到了相對較好的作用。 但是,有更好的方法來編寫解釋器(正如我在演講中所介紹的那樣,以及特定於CPU的Dalvik解釋器實際上工作)。
而對於更大的上下文,將字節碼編譯為本機CPU指令通常會導致執行速度比最精心調整的解釋器更快,假設您有足夠的RAM來保存編譯結果。 在Froyo中引入的基於跟蹤的Dalvik JIT旨在進行權衡,其中使用適量的額外RAM來實現合理有效的性能提升。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.