摘要:為什么要將字節(jié)碼翻譯為代碼字節(jié)碼是基于棧的一種編碼。最近在研究,由于的目的是對(duì)字節(jié)碼做優(yōu)化,所以里面也有將字節(jié)碼翻譯為的邏輯。但是不明白為什么需要類型推導(dǎo),目前我感覺(jué)將字節(jié)碼翻譯為完全不需要推導(dǎo)類型。
為什么要將Java字節(jié)碼翻譯為C代碼?
Java字節(jié)碼是基于棧的一種編碼。這種編碼方式十分方便解釋器的設(shè)計(jì),但同時(shí)不利于程序分析,因此一些高效的代碼優(yōu)化技術(shù)無(wú)法方便的Java字節(jié)碼上實(shí)現(xiàn)。
先大體說(shuō)說(shuō)Java字節(jié)碼的特點(diǎn)。目前版本的Java大概有200+的字節(jié)碼指令,其中大部分都是1字節(jié)指令,這也是為什么叫做字節(jié)碼。少部分指令是多字節(jié)或不定長(zhǎng)指令。
對(duì)于解釋器來(lái)說(shuō),解釋指令時(shí)一般都是在操作兩個(gè)區(qū)域。一個(gè)是棧,一個(gè)是局部變量表。舉例來(lái)說(shuō),iload1指令,就是從局部變量表的1號(hào)槽位的數(shù)據(jù)放入操作數(shù)棧中,即*stack++ = locals[1]。
與C或者其他常用的編程語(yǔ)言不同的是,Java字節(jié)碼的操作數(shù)類型是隱含的,操作的類型的顯示的,而C語(yǔ)言中操作數(shù)類型都是顯示的,但是操作是多態(tài)的。比如“+”,在C語(yǔ)言中“+”兩邊的操作數(shù)類型可以是int型,可以是double。Java字節(jié)碼中iadd指令明確表示了要操作相加的兩個(gè)數(shù)一定是int型。但是當(dāng)拋開(kāi)iadd指令而直接觀測(cè)操作數(shù)棧時(shí),并不知道棧上操作數(shù)的類型。
直接說(shuō)結(jié)論。
Java字節(jié)碼在每一條指令執(zhí)行時(shí),操作數(shù)棧的深度,局部變量表的大小,以及它們上面的操作數(shù)類型都是可以確定的。而且,無(wú)論從何種路徑執(zhí)行到某一條指令,操作數(shù)棧深度及操作數(shù)類型都是確定的[1]。Java虛擬機(jī)規(guī)范的4.10.2章節(jié)介紹了字節(jié)碼校驗(yàn)的一個(gè)算法,可以參考。
以一個(gè)簡(jiǎn)單的a=b+c的例子來(lái)說(shuō)明這個(gè)翻譯過(guò)程。
對(duì)應(yīng)的Java字節(jié)碼如下:
iload1 iload2 iadd istore1
我們可以暫時(shí)將操作數(shù)棧和局部變量表的每一個(gè)槽位看成一個(gè)局部變量。上面的代碼就翻譯為:
s0 = l1; s1 = l2; s0 = s0 + s1; l1 = s0;
其中局部變量的類型都是已知的。可以看到s0,s1跟Java操作數(shù)棧的功能一樣,是為了存放臨時(shí)的計(jì)算結(jié)果。上面的代碼完全可以化簡(jiǎn)為“l(fā)1 = l1 + l2”。但前期沒(méi)有必要引入這種復(fù)雜性,這種化簡(jiǎn)完全可以由后續(xù)的各種優(yōu)化完成。
上面的例子實(shí)際上的存在一些問(wèn)題的。雖然Java操作數(shù)棧和局部變量表里面存放的數(shù)據(jù)都是有類型,但是棧和局部變量表本身只是一個(gè)存儲(chǔ)空間罷了,并沒(méi)有規(guī)定里面必須存放什么類型的數(shù)據(jù)。所以每次在給??臻g或者局部變量賦值的時(shí)候,我們有必要新聲明一個(gè)局部變量。上面的例子翻譯為:
s0 = l1; s1 = l2; s0_1 = s0 + s1; l1_1 = s0;
通過(guò)數(shù)據(jù)流分析可以求出def-use,方便做上面的這種變量分裂,這里不詳細(xì)說(shuō)了。
最近在研究Soot,由于Soot的目的是對(duì)字節(jié)碼做優(yōu)化,所以里面也有將字節(jié)碼翻譯為Jimple的邏輯。但是不明白Soot為什么需要類型推導(dǎo),目前我感覺(jué)將Java字節(jié)碼翻譯為Jimple完全不需要推導(dǎo)類型。
[1] Toba: Java For ApplicationsA Way Ahead of Time (WAT) Compiler
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/69223.html
摘要:為什么要將字節(jié)碼翻譯為代碼字節(jié)碼是基于棧的一種編碼。最近在研究,由于的目的是對(duì)字節(jié)碼做優(yōu)化,所以里面也有將字節(jié)碼翻譯為的邏輯。但是不明白為什么需要類型推導(dǎo),目前我感覺(jué)將字節(jié)碼翻譯為完全不需要推導(dǎo)類型。 為什么要將Java字節(jié)碼翻譯為C代碼? Java字節(jié)碼是基于棧的一種編碼。這種編碼方式十分方便解釋器的設(shè)計(jì),但同時(shí)不利于程序分析,因此一些高效的代碼優(yōu)化技術(shù)無(wú)法方便的Java字節(jié)碼上實(shí)現(xiàn)...
摘要:本文已收錄修煉內(nèi)功躍遷之路我們寫的方法在被編譯為文件后是如何被虛擬機(jī)執(zhí)行的對(duì)于重寫或者重載的方法,是在編譯階段就確定具體方法的么如果不是,虛擬機(jī)在運(yùn)行時(shí)又是如何確定具體方法的方法調(diào)用不等于方法執(zhí)行,一切方法調(diào)用在文件中都只是常量池中的符號(hào)引 本文已收錄【修煉內(nèi)功】躍遷之路 showImg(https://segmentfault.com/img/bVbuesq?w=2114&h=12...
Hello World!應(yīng)用程序 下面列出的小節(jié)提供了編譯和運(yùn)行一個(gè)簡(jiǎn)單的Hello World!應(yīng)用程序的詳細(xì)說(shuō)明,第一部分提供了關(guān)于使用NetBeans IDE入門的信息,集成開(kāi)發(fā)環(huán)境極大地簡(jiǎn)化了軟件開(kāi)發(fā)過(guò)程。NetBeans IDE運(yùn)行在下面列出的所有平臺(tái)上,其余部分提供了特定于平臺(tái)的指示,用于在沒(méi)有集成開(kāi)發(fā)環(huán)境的情況下啟動(dòng)。如果遇到問(wèn)題,一定要參考常見(jiàn)問(wèn)題部分,它為新用戶遇到的許多問(wèn)題提供...
摘要:零預(yù)備知識(shí)字符編碼計(jì)算機(jī)只能處理數(shù)字,所以為文本需要轉(zhuǎn)化為數(shù)字才能被計(jì)算機(jī)處理,計(jì)算機(jī)里八個(gè)比特作為一個(gè)字節(jié),這是數(shù)據(jù)的存儲(chǔ)基礎(chǔ)單位。 零、預(yù)備知識(shí) 0.1 字符編碼計(jì)算機(jī)只能處理數(shù)字,所以為文本需要轉(zhuǎn)化為數(shù)字才能被計(jì)算機(jī)處理,計(jì)算機(jī)里八個(gè)比特(bit)作為一個(gè)字節(jié)(byte),這是數(shù)據(jù)的存儲(chǔ)基礎(chǔ)單位。計(jì)算機(jī)為了處理文本,有以下三種編碼方式: ASCII碼:只有大小寫英文字母,數(shù)字...
摘要:建模語(yǔ)言建模語(yǔ)言是可用于表達(dá)信息或知識(shí)或系統(tǒng)的任何人造語(yǔ)言,該結(jié)構(gòu)由一組一致的規(guī)則定義,目標(biāo)是可視化,推理,驗(yàn)證和傳達(dá)系統(tǒng)設(shè)計(jì)。將這些文件安排到不同的地方稱為源代碼樹。源代碼樹的結(jié)構(gòu)通常反映了軟件的體系結(jié)構(gòu)。 大綱 軟件構(gòu)建的一般過(guò)程: 編程/重構(gòu) 審查和靜態(tài)代碼分析 調(diào)試(傾倒和記錄)和測(cè)試 動(dòng)態(tài)代碼分析/分析 軟件構(gòu)建的狹義過(guò)程(Build): 構(gòu)建系統(tǒng):組件和過(guò)程 構(gòu)建變體...
閱讀 3623·2021-11-24 10:19
閱讀 3754·2021-09-30 09:47
閱讀 1319·2019-08-30 15:56
閱讀 822·2019-08-29 15:11
閱讀 929·2019-08-29 13:43
閱讀 3610·2019-08-28 18:25
閱讀 2180·2019-08-26 13:27
閱讀 1456·2019-08-26 11:44