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