freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

樹(shù)遍歷解釋器,基于棧與基于寄存器,大雜燴(參考版)

2025-05-11 21:14本頁(yè)面
  

【正文】 發(fā)表于 2021年 04月 27日 00: 15: 00||| 特別聲明: 1:資料來(lái)源于互聯(lián)網(wǎng),版權(quán)歸屬原作者 2:資料內(nèi)容屬于網(wǎng)絡(luò)意見(jiàn),與本賬號(hào)立場(chǎng)無(wú)關(guān) 3:如有侵權(quán),請(qǐng)告知,立即刪除。我修改了圖更新到正文了。我是畫成多幀 PNG 然后轉(zhuǎn)換為 GIF發(fā)出來(lái)的。我的收藏里還有v8和 tamarin 等標(biāo)簽的,資料有的是 ^^能有耐心讀到結(jié)尾的同學(xué)們,歡迎提出意見(jiàn)和建議,以及指出文 中的錯(cuò)漏 ^_^不像抓到蟲(chóng)就給美分的大師,我沒(méi)那種信心…錯(cuò)漏難免,我也需要進(jìn)一步學(xué)習(xí)。關(guān)于推薦資料,在 我的收藏 的 virtual machine 標(biāo)簽里就有不少值得一讀的資料。根據(jù)拆分的現(xiàn)狀,下一篇應(yīng)該是討論動(dòng)態(tài)語(yǔ)言與編譯的問(wèn)題,然后再下一篇會(huì)看看解釋器的演化方法,再接著會(huì)看看 JavaScript 引擎的狀況(主要針對(duì) V8 和 Nitro,也會(huì)談?wù)?Tamarin。上面寫的都還 沒(méi)撓上癢癢,心虛。弄得太長(zhǎng)了,只好在這里先拆分一次…有些東西想寫的,洗個(gè)澡又忘記了。實(shí)現(xiàn) VM時(shí)可以采用許多優(yōu)化技巧去減少性能損失,使得實(shí)際的運(yùn)行方式與概念中的不完全相符,只要最終的運(yùn)行結(jié)果滿足原本概念上的 VM所實(shí)現(xiàn)的語(yǔ)義就行。很可惜目前還沒(méi)有正式發(fā)布的 JVM 支持直接加載 Pack200 格式 的歸檔,畢竟網(wǎng)絡(luò)傳輸才是 Pack200 最初構(gòu)想的應(yīng)用場(chǎng)景。它的主要應(yīng)用場(chǎng)景是作為 JAR 的網(wǎng)絡(luò)傳輸格式,以更高的壓縮比來(lái)減 少文件傳輸時(shí)間。相比之下, .jar 文件中每個(gè)類都持有自己的常量池,諸如 Ljava/lang/Object; 這種常見(jiàn)的字符串會(huì)被重復(fù)多次。題外話 2: Dalvik的 .dex 文件在未壓縮狀態(tài)下的體積通常比同等內(nèi)容的 .jar 文件在 deflate 壓縮后還要小。 而 x86 程序在調(diào)用函數(shù)時(shí)要考慮清楚 calling convention,調(diào)用方在調(diào)用前要不要保護(hù)某些寄存器的當(dāng)前狀態(tài),還是說(shuō)被調(diào)用方會(huì)處理好這些問(wèn)題,麻煩事不少。題外話 1: Dalvik VM 是基于寄存器的, x86 也是基于寄存器的,但兩者的 寄存器 卻相當(dāng)不同:前者的寄存器是每個(gè)方法被調(diào)用時(shí)都有自己一組私有的,后者的寄存器則是全局的。這是其一。上面一段的分析用一句話描述就是:由于 foo()里沒(méi)有產(chǎn)生外部可見(jiàn)的副作用,所以foo()的整個(gè)方法體都可以被優(yōu)化為空。上面的例子經(jīng)過(guò)常量傳播與折疊后,我們可以分析得知變量 a、 b、 c 都只被定義而沒(méi)有被使用。這樣就可以對(duì)它們應(yīng)用常量傳播,將 Java 代碼 int c=(a+b)*5;替換為 Java 代碼 int c=(1+2)*5;然后可以再對(duì) c 的初始化表達(dá)式應(yīng)用常量折疊,進(jìn)一步替換為: Java 代碼 int c=15;把變量 的每次狀態(tài)更新 (包括初始賦值在內(nèi) )稱為變量的一次 定義 (definition),把每次訪問(wèn)變量 (從變量讀取值 )稱為變量的一次 使用 (use),則可以把代碼整理為 使用 定義鏈 (簡(jiǎn)稱 UD 鏈, usedefine chain)。你可能會(huì)抱怨:上面兩個(gè)版本的代碼明明不對(duì)應(yīng): JVM 版到 return 前完好持有 a、 b、 c三個(gè)變量的值;而 Dalvik 版到 returnvoid 前只持有 b 與 c 的值 (分別位于 v0 與 v1),a 的值被刷掉了。方法的參數(shù)按源碼中從左到右的順序保存在末尾的幾個(gè)虛擬寄存器里。常用 v0v15這 16個(gè),也有少數(shù)指令可以訪問(wèn) v0v255 范圍內(nèi)的 256個(gè)虛擬寄存器。與JVM不同的是, Dalvik VM 的 棧幀中沒(méi)有局部變量區(qū)與求值棧,取而代之的是一組虛擬寄存器。與 JVM相似,在 Dalvik VM中每個(gè)線程都有自己的 PC和調(diào)用棧,方法調(diào)用的活動(dòng)記錄以幀為單位保存在調(diào)用棧上。 Dalvik VM:說(shuō)明: Dalvik 字節(jié)碼以 16位為單元 (或許叫 雙字節(jié)碼 更準(zhǔn)確 =_=|||)。從類型安全的角度看,只要對(duì)某個(gè) slot 的一次 load 的 類型與最近一次對(duì)它的 store 的類型匹配, JVM 的字節(jié)碼校驗(yàn)器就不會(huì)抱怨。對(duì)了,想提醒一下:Java 的局部變量區(qū)并不需要把某個(gè)局部變量固定分配在某個(gè) slot 里;不僅如此,在一個(gè)方法內(nèi)某個(gè) slot 甚至可能保存不同類型的數(shù)據(jù)??梢杂^察到 Java 字節(jié)碼是如何指示 JVM將數(shù)據(jù)壓入或彈出棧,以及數(shù)據(jù)是如何在棧與局部變量區(qū)之前流動(dòng)的;可以看到數(shù)據(jù)移動(dòng)的次數(shù)特別多。在上面的例子中, ()方法所需要的局部變量區(qū)大小為 3 個(gè) slot,需要的求值棧大小為 2個(gè) slot。兩者都 以字長(zhǎng) (32 位的字 )為單位,每個(gè) slot 可以保存 byte、 short、 char、 int、 float、 reference 和returnAddress 等長(zhǎng)度小于或等于 32 位的類型的數(shù)據(jù);相鄰兩項(xiàng)可用于保存long 和 double 類型的數(shù)據(jù)。局部變量區(qū)用于存儲(chǔ)方法的參數(shù)與局部變量,其中參數(shù)按源碼中從左到右順序保存在局部變量區(qū)開(kāi)頭的幾個(gè) slot。 Java 棧以幀 (frame)為單位線程的運(yùn)行狀態(tài),每調(diào)用一個(gè)方法就會(huì)分配一個(gè)新的棧幀壓入 Java棧上,每從一個(gè)方法返回則彈出并撤銷相應(yīng)的棧幀。 PC 以字節(jié)為單位記錄當(dāng)前運(yùn)行位置里方法開(kāi)頭的偏移量。程序計(jì)數(shù)器是用于記錄程序當(dāng)前執(zhí)行的位置用的。下同 )說(shuō)明:Java 字節(jié)碼以 1字節(jié)為單元。其中字節(jié)碼的一列表示的是字節(jié)碼指令的實(shí)際數(shù)值,后面跟著的助記符則是其對(duì)應(yīng)的文字形式。 )讓我們看看兩個(gè)版本在概念上是如何工作的。轉(zhuǎn)換時(shí)可以直接以文本形式 dump 出 dex 文件的內(nèi)容。創(chuàng)建 文件,內(nèi)容為: Java 代碼 publicclass Demo{publicstaticvoid foo(){int a=1; int b=2;int c=(a+b)*5; }}通過(guò) javac 編譯,得到 。要自己動(dòng)手感受一下該例子,請(qǐng)先確保已經(jīng)正確安裝 JDK 6,并從官網(wǎng)獲取 Android SDK 。這個(gè)演講中 Dan特別提到了 Dalvik VM 與 JVM 在字節(jié)碼設(shè)計(jì)上的區(qū)別,指出Dalvik VM的字節(jié)碼可以用更少指令條數(shù)、更少內(nèi)存訪問(wèn)次數(shù)來(lái)完成操作。 ARM9 有 16 個(gè) 32 位通用寄存器, Dalvik VM 的架構(gòu)也常 用 16個(gè)虛擬寄存器 (一樣多…沒(méi)辦法把虛擬寄存器全部直接映射到硬件寄存器上了 );這樣 Dalvik VM 就不用太顧慮可移植性的問(wèn)題,優(yōu)先考慮在 ARM9上以高效的方式實(shí)現(xiàn),發(fā)揮基于寄存器架構(gòu)的優(yōu)勢(shì)。為了能正確實(shí)現(xiàn)語(yǔ)義, Dalvik VM 的許多設(shè)計(jì)都考慮到與 JVM的兼容性;但它卻采用了基于寄存器的架構(gòu),其字節(jié)碼主要是二地址 /三地址混合形式的,乍一看可能讓人納悶。 JVM的字節(jié)碼主要是零地址形式的,概念上說(shuō) JVM 是基于棧的架構(gòu)。 基于棧與基于寄存器架構(gòu)的 VM 的一組圖解要是拿兩個(gè)分別實(shí)現(xiàn)了基于棧與基于寄存器架構(gòu)、但沒(méi)有直接聯(lián)系的 VM 來(lái)對(duì)比,效果或許不會(huì)太好。雖說(shuō)內(nèi)部具體實(shí)現(xiàn)的顯著差異使得先進(jìn)的 JVM 比簡(jiǎn)單的 JVM 快很多,而 JVM又 普遍比 Python 和 Ruby快很多。其實(shí)它們都是由 編譯器 +VM構(gòu)成的,概念上就像是 Java 編譯器與 JVM融為一體一般。對(duì) Java編譯器來(lái)說(shuō),代碼生成就到字節(jié)碼的層次就結(jié)束了;而對(duì)native 編譯器來(lái)說(shuō),這里剛到生成中間表示的部分,接下去是優(yōu)化與最終的代碼生成。它里面主要包含掃描器與解析器,語(yǔ)義分析器 (包括類型檢查器 /類型推導(dǎo)器等 ),代碼生成器等幾大部分。如果想在 JVM 上開(kāi)發(fā)一種語(yǔ)義能直接映射到 Java上的語(yǔ)言,那么編譯器很好寫:秘訣就是后序遍歷 AST。同理,零地址指令也與樹(shù)形結(jié)構(gòu)聯(lián)系了起來(lái):可以通過(guò)一個(gè)棧方便的把零地址指令序列再轉(zhuǎn)換回到樹(shù)的形式。這種描述看起來(lái)眼熟么 ?沒(méi)錯(cuò),后綴記法的求值中的核心數(shù)據(jù)結(jié)構(gòu)就是前文提到過(guò)的 求值棧 (或者叫操作數(shù)棧,現(xiàn)在應(yīng)該更好理解了 )。樹(shù)遍歷解釋器對(duì) AST 的求值
點(diǎn)擊復(fù)制文檔內(nèi)容
黨政相關(guān)相關(guān)推薦
文庫(kù)吧 www.dybbs8.com
備案圖鄂ICP備17016276號(hào)-1