淺談把Java字節碼譯爲C代碼的意義

Java字節碼是基於棧的一種編碼。這種編碼方式十分方便解釋器的設計,但同時不利於程序分析,所以一些高效的代碼優化技術沒法方便的Java字節碼上實現。程序員

先大致說說Java字節碼的特色。目前版本的Java大概有200+的字節碼指令,其中大部分都是1字節指令,這也是爲何叫作字節碼。少部分指令是多字節或不定長指令。對於解釋器來講,解釋指令時通常都是在操做兩個區域。一個是棧,一個是局部變量表。舉例來講,iload1指令,就是從局部變量表的1號槽位的數據放入操做數棧中,即*stack++ = locals。編程

與C或者其餘經常使用的編程語言不一樣的是,Java字節碼的操做數類型是隱含的,操做的類型的顯示的,而C語言中操做數類型都是顯示的,可是操做是多態的。好比「+」,在C語言中「+」兩邊的操做數類型能夠是int型,能夠是double。尚學堂•百戰程序員陳老師指出Java字節碼中iadd指令明確表示了要操做相加的兩個數必定是int型。可是當拋開iadd指令而直接觀測操做數棧時,並不知道棧上操做數的類型。編程語言

Java字節碼在每一條指令執行時,操做數棧的深度,局部變量表的大小,以及它們上面的操做數類型都是能夠肯定的。並且,不管從何種路徑執行到某一條指令,操做數棧深度及操做數類型都是肯定的,以一個簡單的a=b+c的例子來講明這個翻譯過程。優化

其中局部變量的類型都是已知的。能夠看到s0,s1跟Java操做數棧的功能同樣,是爲了存放臨時的計算結果。上面的代碼徹底能夠化簡爲「l1 = l1 + l2」。但前期沒有必要引入這種複雜性,這種化簡徹底能夠由後續的各類優化完成。編碼

上面的例子實際上的存在一些問題的。雖然Java操做數棧和局部變量表裏面存放的數據都是有類型,可是棧和局部變量表自己只是一個存儲空間罷了,並無規定裏面必須存放什麼類型的數據。因此每次在給棧空間或者局部變量賦值的時候,咱們有必要新聲明一個局部變量。翻譯

經過數據流分析能夠求出def-use,方便作上面的這種變量分裂,這裏不詳細說了。最近在研究Soot,因爲Soot的目的是對字節碼作優化,因此裏面也有將字節碼翻譯爲Jimple的邏輯。可是不明白Soot爲何須要類型推導,目前我感受將Java字節碼翻譯爲Jimple徹底不須要推導類型。設計

相關文章
相關標籤/搜索