国产精品1024永久观看,大尺度欧美暖暖视频在线观看,亚洲宅男精品一区在线观看,欧美日韩一区二区三区视频,2021中文字幕在线观看

  • <option id="fbvk0"></option>
    1. <rt id="fbvk0"><tr id="fbvk0"></tr></rt>
      <center id="fbvk0"><optgroup id="fbvk0"></optgroup></center>
      <center id="fbvk0"></center>

      <li id="fbvk0"><abbr id="fbvk0"><dl id="fbvk0"></dl></abbr></li>

      將程序執(zhí)行從編譯代碼變換到解釋代碼的制作方法

      文檔序號:6533008閱讀:240來源:國知局
      將程序執(zhí)行從編譯代碼變換到解釋代碼的制作方法
      【專利摘要】可以從源自以動態(tài)語言(例如JavaScript)編寫的程序的字節(jié)代碼來生成經(jīng)優(yōu)化的編譯的代碼。優(yōu)化可以基于一種或多種假設(shè)。在經(jīng)優(yōu)化的編譯的代碼的執(zhí)行期間,所述優(yōu)化所基于的所述一種或多種假設(shè)可以被檢查有效性。響應(yīng)于確定所述優(yōu)化是基于無效的一種或多種假設(shè),經(jīng)優(yōu)化的代碼的執(zhí)行可以停止,解釋器所使用的變量的狀態(tài)可以被還原并且程序的執(zhí)行可以在解釋器中使用源自程序的未經(jīng)優(yōu)化的字節(jié)代碼來恢復(fù)。程序的繼續(xù)可以在字節(jié)代碼中的一個點處恢復(fù),所述點類似于在經(jīng)優(yōu)化的編譯的代碼中的所述一種或多種假設(shè)被確定為假的那點。
      【專利說明】將程序執(zhí)行從編譯代碼變換到解釋代碼
      [0001] 背景
      [0002] 動態(tài)編程語言是一種在運行時執(zhí)行靜態(tài)語言通常在編譯期間執(zhí)行或根本不執(zhí)行 的行為的語言。在運行時由動態(tài)語言執(zhí)行的行為可以包括通過添加新代碼、通過擴展對象 和定義或通過修改類型系統(tǒng)對程序的擴展。在動態(tài)編程語言中,在編譯時不可用的信息可 以顯著地改變程序如何執(zhí)行。例如,在靜態(tài)程序中,當(dāng)在源代碼中聲明變量時,該聲明指定 了所述變量的類型。變量X是整數(shù)或變量X是字符串等。如果變量X是整數(shù),則將X加到 整數(shù)常量將執(zhí)行算術(shù)加法。如果變量X是字符串,則將X加到是字符串的常量將執(zhí)行常量 和X的串聯(lián)。在動態(tài)編程語言中,變量的類型直到該程序執(zhí)行時才知道,因此,需要額外的 代碼路徑來處理不同類型的操作,這會出現(xiàn)為程序執(zhí)行增加開銷。
      [0003] 通常被認(rèn)為是動態(tài)語言的語言示例包括但不局限于:ActionScript、BASIC、 BeanShell、ColdFusion、Common Lisp 和一些其它 Lisp 語言、Groovy、E 編程語言; JavaScript、VBScript、MATLAB、Lua、Objective-C、Perl、PHP、Powershell、Python、Ruby、 Smalltalk、Tel 以及 Dolphin Smalltalk。
      [0004] 概述
      [0005] 通過動態(tài)語言,可以做出關(guān)于不太可能靜態(tài)確定的類型信息的假設(shè)。隨后可以使 用這種不精確的信息來應(yīng)用優(yōu)化??梢蕴峁┩ㄟ^優(yōu)化假設(shè)的無效所觸發(fā)的后退或跳出機 制。可以從源自以動態(tài)語言(例如但不局限于JavaScript)編寫的程序的字節(jié)代碼來生成 經(jīng)優(yōu)化的編譯代碼。優(yōu)化可以基于關(guān)于數(shù)據(jù)的特性的一種或多種假設(shè)。在經(jīng)優(yōu)化的編譯的 代碼的執(zhí)行期間,所述優(yōu)化所基于的所述一種或多種假設(shè)可以被檢查有效性。響應(yīng)于確定 所述優(yōu)化是基于無效的一種或多種假設(shè),經(jīng)優(yōu)化的代碼的執(zhí)行可以停止,解釋器所使用的 對應(yīng)的變量的狀態(tài)可以被還原并且程序的執(zhí)行可以在解釋器中使用源自程序的未經(jīng)優(yōu)化 的字節(jié)代碼來恢復(fù)。程序的繼續(xù)可以在字節(jié)代碼中的一個點處恢復(fù),所述點類似于在經(jīng)優(yōu) 化的編譯的代碼中的所述一種或多種假設(shè)被確定為假的那點。
      [0006] 在經(jīng)優(yōu)化的編譯的代碼中的優(yōu)化可以包括對變量類型操作的優(yōu)化??梢詫鬟f給 解釋器的跳出信息量最小化。非活動的編譯的代碼不需要被復(fù)活用于解釋器。
      [0007] 可以在經(jīng)優(yōu)化的編譯的代碼中預(yù)先確定的點處設(shè)定一個或多個跳出點。在每個跳 出點處,可以捕捉未經(jīng)優(yōu)化的字節(jié)代碼中的變量位置和對應(yīng)的位置。當(dāng)在執(zhí)行期間到達(dá)跳 出點時,可以檢查與該跳出點相關(guān)聯(lián)的一種或多種假設(shè)的有效性,并且變量狀態(tài)可以被還 原用于對應(yīng)的解釋器的變量。可以將變量的狀態(tài)和在未經(jīng)優(yōu)化的字節(jié)代碼中的對應(yīng)位置發(fā) 送給解釋器。解釋器可以在未經(jīng)優(yōu)化的字節(jié)代碼中的所接收的對應(yīng)位置處恢復(fù)未經(jīng)優(yōu)化的 字節(jié)代碼的執(zhí)行。
      [0008] 提供本概述是為了以簡化的形式介紹將在以下【具體實施方式】中進(jìn)一步描述的概 念選擇。本概述并不旨在標(biāo)識所要求保護(hù)主題的關(guān)鍵特征或必要特征,也不旨在用于限制 所要求保護(hù)主題的范圍。

      【專利附圖】

      【附圖說明】
      [0009] 在附圖中:
      [0010] 圖la示出根據(jù)在此所述的主題的各方面的包括被配置為呈現(xiàn)來自所接收的文檔 中的頁的瀏覽器應(yīng)用的系統(tǒng)100的示例;
      [0011] 圖lb示出根據(jù)在此所述的主題的各方面的包括被配置為從編譯的代碼變換到字 節(jié)代碼的執(zhí)行的運行時引擎的系統(tǒng)200的示例;
      [0012] 圖lc示出根據(jù)在此所述的主題的各方面的包括被配置為從編譯的代碼變換到字 節(jié)代碼的執(zhí)行的運行時引擎的系統(tǒng)300的示例;
      [0013] 圖Id示出根據(jù)在此所述的主題的各方面的程序源代碼、對應(yīng)的字節(jié)代碼、編譯的 代碼和跳出表格的示例150 ;
      [0014] 圖le示出根據(jù)在此所述的主題的各方面的具有跳出信息的編譯的代碼的示例 170 ;
      [0015] 圖If示出根據(jù)在此所述的主題的各方面的程序源代碼、以及具有跳出信息的編 譯的代碼的示例171 ;
      [0016] 圖lg示出根據(jù)在此所述的主題的各方面的程序源代碼、對應(yīng)的字節(jié)代碼、以及具 有跳出信息的編譯的代碼的示例180 ;
      [0017] 圖2示出根據(jù)在此所述的主題的各方面的將程序執(zhí)行從經(jīng)優(yōu)化的編譯的代碼變 換到解釋的代碼的方法250的示例;
      [0018] 圖3是根據(jù)本文公開的主題的各方面的計算環(huán)境的示例的框圖。
      [0019] 詳細(xì)描述
      [0020] 概覽
      [0021] 一些基于靜態(tài)分析的傳統(tǒng)的編譯器優(yōu)化對于動態(tài)語言是不可用的,因為進(jìn)行優(yōu)化 所需的信息在編譯時不可用。然而,通過使用試探法或通過收集簡檔數(shù)據(jù)和/或使用所收 集的簡檔數(shù)據(jù)或通過以其他方式做出一種或多種假設(shè)來推導(dǎo)丟失的信息就可以執(zhí)行某種 程度的優(yōu)化。例如,假設(shè)腳本可由運行時引擎接收以作為網(wǎng)頁或其它文檔的一部分來執(zhí)行。 運行時引擎可使用解釋器來執(zhí)行腳本。在一次或多次腳本的執(zhí)行期間可由解釋器來收集關(guān) 于該腳本的簡檔信息。簡檔信息可被用于確定腳本的哪些部分可通過使用編譯器編譯這些 部分并執(zhí)行得到的機器代碼,而非解釋腳本的這些部分,來被更高效地執(zhí)行。這樣,使用解 釋器可以執(zhí)行腳本的一些部分,而使用編譯器可以編譯該腳本的其它部分,并且可以執(zhí)行 所生成的編譯的代碼。腳本的經(jīng)編譯的部分(例如本機機器代碼)可以被存儲以供以后在 再次執(zhí)行腳本的這些部分時使用。
      [0022] 類似地,可以確定腳本的啟動部分。可以對腳本的啟動部分加標(biāo)志,這樣,在隨后 的腳本運行中,在處理非啟動部分之前可以由運行時引擎處理該啟動部分。
      [0023] 根據(jù)在此所述的主題的各方面,可以執(zhí)行包括諸如方法或函數(shù)或者方法或函數(shù)的 任意部分之類的任意代碼塊的經(jīng)編譯的字節(jié)代碼??梢曰陉P(guān)于在運行時對程序可用的信 息的特性的一種或多種假設(shè)來優(yōu)化編譯的字節(jié)代碼。所述假設(shè)可以基于簡檔信息、試探法 或任意其它適合的信息。經(jīng)優(yōu)化的編譯的字節(jié)代碼可以包括基于在所述經(jīng)編譯的字節(jié)代碼 中所做的特定優(yōu)化來預(yù)先確定的一個或多個跳出點。對于每個跳出點,可以捕捉一組變量, 該組變量保持有解釋器在跳出點處恢復(fù)執(zhí)行所需的值。在寄存器分配之后可以創(chuàng)建每個跳 出點的跳出表格。每個跳出點的跳出表格可以包括跳出點的每個變量的位置(例如堆棧位 置、寄存器等)。跳出表格還可以包括每個變量的狀態(tài)(例如在所述變量已經(jīng)通過類型專用 化或其它優(yōu)化被優(yōu)化為int32、雙精度等的情況)。
      [0024] 在后續(xù)經(jīng)優(yōu)化的編譯的字節(jié)代碼的執(zhí)行期間,可以對關(guān)于在其上生成所述字節(jié)代 碼的程序?qū)⒁僮鞯臄?shù)據(jù)的假設(shè)進(jìn)行測試。響應(yīng)于確定在其中做出所述優(yōu)化的一種或多 種假設(shè)是不正確的,執(zhí)行可以"跳出"到解釋器。就是說,可以停止經(jīng)編譯的代碼的執(zhí)行,并 且解釋器可以執(zhí)行與在跳出點處開始的經(jīng)優(yōu)化的編譯的字節(jié)代碼所對應(yīng)的未經(jīng)優(yōu)化的字 節(jié)代碼,所述跳出點對應(yīng)于在經(jīng)優(yōu)化的編譯的代碼中的在其處確定所述一種或多種假設(shè)為 假的點。當(dāng)跳出發(fā)生時,解釋器所需的變量的狀態(tài)可以通過檢查跳出點的跳出表格來被重 新物化(rematerialized)。跳出點的跳出表格可以為變量提供一個值(對于常量)或位 置。跳出表格可以提供解釋器在該跳出點恢復(fù)執(zhí)行所需的每個變量的狀態(tài)(對于類型專用 化)。在重新物化了解釋器繼續(xù)執(zhí)行所需的變量的狀態(tài)之后,解釋器可以在跳出位置處恢復(fù) 控制以承載當(dāng)前正在執(zhí)行的函數(shù)的執(zhí)行。
      [0025] 根據(jù)在此所述的主題的一些方面,可以接收以動態(tài)語言編碼的源代碼以供執(zhí)行。 源代碼可以是任意代碼塊,例如方法或函數(shù)或者方法或函數(shù)的任意部分。源代碼可被解析 以生成經(jīng)解析的源代碼。經(jīng)解析的源代碼被轉(zhuǎn)換成字節(jié)代碼??梢允褂媒忉屍鱽硪淮位蚨?次解釋所述字節(jié)代碼??梢陨申P(guān)于字節(jié)代碼的使用模式的簡檔信息。可以存儲所述簡檔 信息。簡檔信息可被分析以確定與字節(jié)代碼接收到的部分相關(guān)聯(lián)的情況。該字節(jié)代碼部分 可被即時(JIT)編譯成經(jīng)編譯的字節(jié)代碼部分,作為所確定的情況的結(jié)果??纱鎯?jīng)編譯 的字節(jié)代碼部分。字節(jié)代碼部分可稍后在解釋器處所接收的字節(jié)代碼中再次被接收。與所 接收到的字節(jié)代碼部分相對應(yīng)的經(jīng)編譯的字節(jié)代碼部分可被定位在存儲中。可對位于存儲 中的經(jīng)編譯的字節(jié)代碼部分執(zhí)行至少一個情況檢查。如果所述至少一個情況檢查通過,則 執(zhí)行經(jīng)編譯的字節(jié)代碼部分而非解釋所接收到的字節(jié)代碼部分。經(jīng)編譯的字節(jié)代碼部分可 以包括基于假設(shè)的優(yōu)化。所述假設(shè)可以基于簡檔數(shù)據(jù)、試探法或所提供的其它信息。當(dāng)執(zhí) 行經(jīng)優(yōu)化的代碼時,可以執(zhí)行情況檢查。響應(yīng)于確定所述優(yōu)化所基于的假設(shè)是不正確的,經(jīng) 編譯的代碼的執(zhí)行可以結(jié)束。代碼的執(zhí)行可以在字節(jié)代碼中的一個位置處恢復(fù),所述位置 類似于在所述假設(shè)被確定為假的那點。
      [0026] 在系統(tǒng)實現(xiàn)的一個示例中,可以提供運行時引擎。運行時引擎可以包括下述項的 全部或一些:解析器、字節(jié)代碼生成器、執(zhí)行控制器、解釋器、JIT編譯器、簡檔生成器以及 跳出引擎。解析器可以接收用動態(tài)語言編碼的源代碼并可以解析該源代碼來生成經(jīng)解析的 源代碼。字節(jié)碼生成器可以將經(jīng)解析的源代碼轉(zhuǎn)換成字節(jié)代碼。解釋器可以被配置為當(dāng)由 執(zhí)行控制器啟用時解釋所述字節(jié)代碼一次或多次。JIT編譯器可被配置成當(dāng)由執(zhí)行控制器 啟用時,編譯字節(jié)代碼。簡檔生成器可以從字節(jié)代碼或從源代碼中生成簡檔信息并可以存 儲所述簡檔信息。執(zhí)行控制器可以啟用解釋器或JIT編譯器來基于簡檔信息執(zhí)行它們各自 的功能。
      [0027] 隨后可以在經(jīng)編譯的代碼中做出優(yōu)化??梢詫⑻鳇c插入在經(jīng)編譯的代碼中預(yù)先 確定的點處。可以基于特定優(yōu)化的特性來預(yù)先確定跳出點。對于每個跳出點,可以捕捉一 組變量,該組變量保持有使得解釋器在程序中的該點處恢復(fù)執(zhí)行的值??梢源鎯?yīng)于預(yù) 先確定的跳出點的變量的位置。在后續(xù)程序執(zhí)行中,如果優(yōu)化所基于的推斷證明是不正確 的,可以提供后退或跳出機制。可以通過檢查與假設(shè)相關(guān)聯(lián)的情況來確定推斷是不正確的。 根據(jù)在此所述的主題的各方面,機器代碼執(zhí)行器可以檢查相關(guān)聯(lián)的情況。響應(yīng)于確定所述 推斷是不正確的(例如通過機器代碼執(zhí)行器檢查情況),根據(jù)在此所述的主題的各方面,經(jīng) 編譯的代碼的執(zhí)行可以停止,解釋器所需的變量可以被重置為在預(yù)先確定的跳出點處所保 存的值并且可以在解釋器處恢復(fù)執(zhí)行。解釋器可以在與不正確的假設(shè)相關(guān)聯(lián)的跳出點處恢 復(fù)執(zhí)行。
      [0028] 根據(jù)在此所述的主題的各方面,跳出引擎可以通過將與機器代碼相關(guān)聯(lián)的變量的 狀態(tài)轉(zhuǎn)換成解釋器所需的狀態(tài)來還原相關(guān)聯(lián)的活動的變量的狀態(tài)??梢栽诰幾g時間(例如 由JIT編譯器)來確定跳出點。在存在依賴于做出的假設(shè)的路徑的任何地方出現(xiàn)跳出點。 每個跳出點可以具有與其相關(guān)聯(lián)的表格,該表格包括關(guān)于為了解釋器正確執(zhí)行必須被復(fù)活 的該組解釋器變量的信息,如何執(zhí)行轉(zhuǎn)換以將變量值從與機器代碼相關(guān)聯(lián)的值轉(zhuǎn)換成與解 釋器相關(guān)聯(lián)的值的描述以及在字節(jié)代碼中在其處恢復(fù)解釋的位置。
      [0029] 經(jīng)編譯的代碼執(zhí)行中的不再被需要因而非活動的變量可能需要為了解釋器而被 復(fù)活。就是說,一個或多個變量的活躍度可能需要被延長至跳出點以使得該變量所持有的 信息對于解釋器可用??梢詧?zhí)行優(yōu)化以最小化對所需的寄存器的數(shù)目的影響。例如,如果 已知變量值在特定跳出點處為常量值,該常量可以被重新排序以便所述變量在該跳出點處 不再需要是可用的。類似地,如果已知變量在特定跳出點處具有與另一變量相同的值,則僅 使得一個包含該值的變量在該跳出點處對于解釋器可用。
      [0030] 將程序執(zhí)行從經(jīng)編譯的代碼變換為經(jīng)解釋的代碼
      [0031] 圖1示出根據(jù)在此所述的主題的一些方面的web瀏覽器環(huán)境100。如在圖la中所 示,環(huán)境100可以包括下述一個或多個:計算設(shè)備102、服務(wù)器104、網(wǎng)絡(luò)106以及瀏覽器應(yīng) 用108。Web瀏覽環(huán)境100可以包括本領(lǐng)域中已知的其它組件。
      [0032] 計算設(shè)備102可以是任何類型的固定或移動計算設(shè)備,包括桌面計算機(例如,個 人計算機等)、移動計算機或計算設(shè)備(例如,Palm?設(shè)備、RM Blackberry?設(shè)備、個人 數(shù)字助理(PDA)、膝上型計算機、筆記本計算機、平板計算機(例如,Apple iPad?)、上網(wǎng)本 等等)、移動電話(例如,蜂窩電話、智能電話,諸如Apple iPhone、G〇〇gle Android?手機、 Microsoft Windows?手機等)或其它類型的移動設(shè)備。服務(wù)器104可在包括一個或多個 服務(wù)器的一個或多個計算機系統(tǒng)中實現(xiàn),其可以是在此描述的任何類型的計算設(shè)備或能夠 實現(xiàn)在此描述的相應(yīng)功能的以其它方式知曉的計算設(shè)備。
      [0033] 計算設(shè)備102和服務(wù)器104可通過網(wǎng)絡(luò)106來通信地耦合。網(wǎng)絡(luò)106可包括一 個或多個通信鏈路和/或通信網(wǎng)絡(luò),諸如PAN(個域網(wǎng))、LAN(局域網(wǎng))、WAN(廣域網(wǎng))、或 網(wǎng)絡(luò)的組合,諸如因特網(wǎng)??墒褂酶鞣N鏈路來將計算設(shè)備102和服務(wù)器通信地耦合到網(wǎng)絡(luò) 106,該各種鏈路包括有線和/或無線鏈路,如IEEE 802. 11無線局域網(wǎng)(WLAN)無線鏈路、 全球微波互聯(lián)接入(Wi-MAX)鏈路、蜂窩網(wǎng)絡(luò)鏈路、無線個人區(qū)域網(wǎng)絡(luò)(PAN)鏈路(例如, Bluetooth?鏈路)、以太網(wǎng)鏈路、USB鏈路等等。
      [0034] 瀏覽器應(yīng)用108可以是可在計算設(shè)備102上執(zhí)行的程序。瀏覽器應(yīng)用108可 使得網(wǎng)絡(luò)信息資源能被檢索、呈現(xiàn)和遍歷??墒褂镁W(wǎng)絡(luò)地址(諸如統(tǒng)一資源標(biāo)識符 (URI))來通過瀏覽器應(yīng)用108檢索信息資源或?qū)ο?。信息資源的示例包括網(wǎng)頁、圖像、 視頻,以及其它形式的內(nèi)容。出現(xiàn)在信息資源中的超鏈接使得用戶能夠容易地將他們 的瀏覽器導(dǎo)航到相關(guān)的資源。瀏覽器應(yīng)用108的示例包括由華盛頓州雷蒙德市的微軟 公司開發(fā)的Internet Explorer?、由加利福尼亞州芒廷維市的Mozilia公司開發(fā)的 MozillaFirefox?、由加利福尼亞州庫珀蒂諾市的Apple公司開發(fā)的Safari?,以及由加利 福尼亞州芒廷維尤市的Chrome公司開發(fā)的Google?。
      [0035] 瀏覽器應(yīng)用108可以通過網(wǎng)絡(luò)106從服務(wù)器104檢索文檔112。文檔112可以是包 括標(biāo)記語言的代碼的web文檔,標(biāo)記語言諸如超文本標(biāo)記語言(HTML)、動態(tài)HTML (DHTML)、 可擴展HTML (XHTML)、可擴展標(biāo)記語言(XML)等。文檔112可以包括D0M (文檔對象模型) 對象114和一個或多個腳本116。D0M對象114可以包括根據(jù)D0M規(guī)范在文檔112中所表 示的一個或多個對象,該D0M規(guī)范是用于表示對象并與對象進(jìn)行交互的跨平臺且獨立于語 言的規(guī)范。D0M對象114可包括被直接包括在文檔112中的對象、和/或由文檔112引用 的并分開地從服務(wù)器104或其它服務(wù)器檢索的對象。腳本116包括根據(jù)動態(tài)語言(例如, JavaScript、VBScript、AJAX、Python、Perl等)來格式化的代碼,該格式化的代碼使得能夠 對D0M對象114做出改變,包括基于諸如用戶輸入、環(huán)境情況(例如,一天中的時間或其它 變量)等因素的改變。腳本116的代碼可在進(jìn)行中訪問和修改D0M對象114的對象,而無 需返回到服務(wù)器104。
      [0036] 瀏覽器應(yīng)用108可以接收(例如加載)文檔112。瀏覽器應(yīng)用108可包括瀏覽器 引擎(例如,布局引擎或呈現(xiàn)引擎),該瀏覽器引擎格式化文檔112的信息并顯示經(jīng)格式化 的信息。例如,如圖la顯示的,瀏覽器應(yīng)用108可基于由計算設(shè)備102的顯示器110顯示 的文檔112來生成頁面118。瀏覽器應(yīng)用108可被配置成執(zhí)行一個或多個腳本116,該一個 或多個腳本116被嵌入在文檔112中或與文檔112分開但與文檔112相關(guān)聯(lián)。
      [0037] 圖lb示出根據(jù)在此所述的主題的一些方面的系統(tǒng)200的框圖。系統(tǒng)200可包括 一個或多個計算機或計算設(shè)備,例如包括諸如處理器143等之類的一個或多個處理器、存 儲器145、執(zhí)行控制器309、解釋器311、諸如JIT(即時)編譯器313、存儲315、機器代碼執(zhí) 行器317和跳出引擎337之類的編譯器的計算設(shè)備102。執(zhí)行控制器309、解釋器311、諸如 JIT(即時)編譯器313的編譯器、存儲315、機器代碼執(zhí)行器317和跳出引擎337可被實現(xiàn) 為一個或多個程序模塊,當(dāng)所述程序模塊被加載到存儲器145中時使得所述一個或多個處 理器143等分別執(zhí)行歸因于執(zhí)行控制器309、解釋器311、諸如JIT (即時)編譯器313、存儲 315、機器代碼執(zhí)行器317和跳出引擎337的動作。
      [0038] 執(zhí)行控制器309、解釋器311和/或JIT編譯器313可以接收從源代碼生成的字 節(jié)代碼。源代碼可以是任意以動態(tài)語言編寫的源代碼,例如但不局限于動態(tài)腳本語言(諸 如但不限于JavaScript、VBScript、Python等等??梢越馕鲈创a并從經(jīng)解析的源代碼中 生成字節(jié)代碼?;谧止?jié)碼325和簡檔、試探法或其它信息,執(zhí)行控制器309可啟用解釋器 311和JIT編譯器313之一來對字節(jié)代碼325進(jìn)行操作。解釋器311可被配置成,當(dāng)由從執(zhí) 行控制器309接收到的解釋器控制信號啟用時解釋字節(jié)代碼325。JIT編譯器313可被配 置成,當(dāng)由從執(zhí)行控制器309接收到的編譯器控制信號啟用時編譯字節(jié)代碼325。
      [0039] 當(dāng)由解釋器控制信號啟用解釋器311時,解釋器311可以解釋并執(zhí)行未經(jīng)優(yōu)化的 字節(jié)代碼325。解釋器311可以被實現(xiàn)為JavaScript解釋器、VBScript解釋器、Python解 釋器或用于在此其它地方提到的或以其它方式所知的另一動態(tài)語言或動態(tài)腳本語言的解 釋器。通過該方式,源代碼可至少部分地由解釋器311的操作來執(zhí)行。類似地,響應(yīng)于接收 到啟用編譯器控制信號,JIT編譯器313可以編譯字節(jié)代碼325。JIT編譯器313可被實現(xiàn) 為JavaScript編譯器、VBScript編譯器、Python編譯器或用于在此其它地方提到的或以其 它方式所知的另一動態(tài)語言或動態(tài)腳本語言的編譯器。JIT編譯器313被稱為"即時"編譯 器,這是因為由于需要經(jīng)編譯的字節(jié)代碼(即,要被緊急執(zhí)行的),特定的字節(jié)代碼部分可 由JIT編譯器313編譯,而非在執(zhí)行之前預(yù)先編譯完整的字節(jié)代碼325。JIT編譯器313可 以生成具有機器可執(zhí)行代碼或指令形式的經(jīng)編譯的字節(jié)代碼333。
      [0040] JIT編譯器313可以基于如上所述的假設(shè)執(zhí)行代碼優(yōu)化。JIT編譯器313可以在它 生成的經(jīng)編譯的字節(jié)代碼中插入一個或多個預(yù)先確定的跳出點。對于每個跳出點,諸如跳 出表格303等之類的跳出表格可以被創(chuàng)建,在其中,可以記錄變量的位置、在字節(jié)代碼325 中與跳出點的位置相對應(yīng)的位置以及其它信息。跳出表格303等可以描述在堆棧上或寄存 器中哪里可以找到變量。JIT編譯器313可以生成一個或多個跳出表格并可以將它們與經(jīng) 優(yōu)化的編譯的字節(jié)代碼(例如作為機器代碼)一起保存??梢酝ㄟ^編碼跳出表格中的信息 來避免對變量的生存期的非必要的延長來優(yōu)化跳出表格。例如,如果已知變量X的值在跳 出時間是常量10, X = 10可以被編碼在跳出表格中,這樣,值10就不需要在存儲器或寄存 器中被復(fù)活。類似地,當(dāng)超過一個變量在跳出點處具有相同的值(例如X = y),如果該信息 被編碼在跳出表格中(例如跳出表格中的相同位置可以被用于X和y),則對于具有相同值 的所有變量來說,該相同的位置可被用在跳出表格中。
      [0041] 這些技術(shù)可以使得寄存器分配更加有效。經(jīng)優(yōu)化的編譯的字節(jié)代碼可以被作為用 于在由系統(tǒng)200后續(xù)執(zhí)行程序期間訪問的經(jīng)編譯的字節(jié)代碼333來存儲在存儲315中。
      [0042] 當(dāng)執(zhí)行經(jīng)優(yōu)化的編譯的字節(jié)代碼時,可由機器代碼執(zhí)行器317(它可以是諸如處 理器143等的一個或多個處理器)接收經(jīng)優(yōu)化的編譯的字節(jié)代碼333。執(zhí)行經(jīng)編譯的字節(jié) 代碼可以與堆棧335上的編譯器框架341相關(guān)聯(lián)。在每個跳出點處可以確定所述優(yōu)化所基 于的底層的一種或多種假設(shè)是有效還是無效的。響應(yīng)于確定所述假設(shè)是有效的,經(jīng)優(yōu)化的 編譯的代碼可以繼續(xù)執(zhí)行。響應(yīng)于確定所述假設(shè)是無效的,經(jīng)優(yōu)化的編譯的代碼的執(zhí)行可 以被停止??梢詫⒃撎鳇c的跳出表格傳遞給跳出引擎337。跳出引擎337可以還原解釋 器所需的變量的狀態(tài)(例如值)。跳出引擎可以為堆棧335創(chuàng)建新的框架(例如解釋器框 架339)。如果解釋器所需的變量已變成非活動的,則跳出引擎337可以通過將變量的狀態(tài) 從非活動改變到活動來復(fù)活該變量。跳出引擎337可以實例化解釋器311的一個實例,向 解釋器傳遞在未經(jīng)優(yōu)化的字節(jié)代碼中與在經(jīng)優(yōu)化的編譯的代碼中的跳出點相對應(yīng)的位置 以及包括所有被還原的活動變量的值的新創(chuàng)建的解釋器框架。因此這樣,從其生成字節(jié)代 碼325的源代碼可以由JIT編譯器313和機器代碼執(zhí)行器317的操作來部分執(zhí)行并由解釋 器311來部分執(zhí)行。
      [0043] 圖lc示出根據(jù)在此所述的主題的各方面的系統(tǒng)300的另一示例。系統(tǒng)300可以 包括諸如處理器142等的一個或多個處理器、存儲器144以及包括下述一個或多個項的運 行時引擎:引擎接口 302、解析器304、字節(jié)代碼生成器306、執(zhí)行控制器308、解釋器310、諸 如但不限于JIT(即時)編譯器312之類的編譯器、存儲314、機器代碼執(zhí)行器316、跳出引 擎336以及腳本庫318。
      [0044] 如在圖lc中所示的,引擎接口 302可接收腳本源代碼208。引擎接口 302可以是 在場的或不在場的。解析器304可以被配置作為到運行時引擎的接口,而不是使得引擎接 口 302在場。當(dāng)在場時,引擎接口 302是提供用于將主機與圖lc的運行時引擎對接的一個 或多個方法的通信接口。根據(jù)在此所述的主題的一些方面,可以根據(jù)由華盛頓州雷蒙德市 的微軟公司所開發(fā)的IActiveScript來實現(xiàn)引擎接口 302。引擎接口 302可以為解析器304 提供源代碼208。
      [0045] 解析器304可以接收并解析源代碼208。解析器304可對源代碼208執(zhí)行令牌生 成或詞法分析,使得源代碼208被格式化成符號或令牌。解析器304可對令牌執(zhí)行差錯校 驗以確定是否形成可允許的表達(dá)式、句法差錯不存在等。解析器304可以將經(jīng)解析的源代 碼作為經(jīng)解析的源代碼(未示出)輸出。經(jīng)解析的源代碼可具有任何合適的形式,包括由 解析器304生成為AST (抽象句法樹)代碼,如本領(lǐng)域的技術(shù)人員知曉的,該AST代碼包括 源代碼208的抽象句法結(jié)構(gòu)的樹表示。
      [0046] 字節(jié)代碼生成器306可以接收經(jīng)解析的源代碼。字節(jié)代碼生成器306可被配置成 將經(jīng)解析的源代碼轉(zhuǎn)換成字節(jié)代碼,其包括被配置成用于解釋器的高效執(zhí)行以及用于進(jìn)一 步編譯成機器代碼的指令集。所生成的字節(jié)代碼可以將經(jīng)解析的源代碼表示為數(shù)字代碼 和相應(yīng)的可選參數(shù)。字節(jié)代碼生成器306可以輸出經(jīng)生成的字節(jié)代碼(未示出)。字節(jié)代 碼可具有任何合適的形式,包括由字節(jié)代碼生成器306生成的如本領(lǐng)域的技術(shù)人員知曉的 P-代碼(便攜式代碼)形式。
      [0047] 執(zhí)行控制器308、解釋器310和JIT編譯器312每個都可以接收所生成的字節(jié)代 碼。解釋器310可以包括簡檔生成器204。簡檔生成器204可被配置成分析所生成的字節(jié) 代碼來收集有關(guān)源代碼208的統(tǒng)計數(shù)據(jù)以及進(jìn)一步的信息。簡檔生成器204可生成簡檔信 息320,其可包括所收集的信息并可被存儲在存儲314中。
      [0048] 執(zhí)行控制器308可以訪問簡檔信息320,并且可以被通信地耦合到解釋器310和 JIT編譯器312?;谒傻淖止?jié)代碼和簡檔信息320,執(zhí)行控制器308可啟用解釋器310 和JIT編譯器312之一來對所生成的字節(jié)代碼進(jìn)行操作。解釋器310可被配置成,當(dāng)由從 執(zhí)行控制器308接收到的解釋器控制信號啟用時解釋所生成的字節(jié)代碼。JIT編譯器312 可被配置成,當(dāng)由從執(zhí)行控制器308接收到的編譯器控制信號啟用時編譯所生成的字節(jié)代 碼。例如,在源代碼208的第一次執(zhí)行期間,簡檔信息320可能還不存在。在這種情況下, 執(zhí)行控制器308可啟用解釋器310來解釋所生成的字節(jié)代碼并生成簡檔信息320。在源代 碼208隨后的執(zhí)行期間(例如,在源代碼208的相同的第一次執(zhí)行期間的稍后,和/或在源 代碼208的接下來的執(zhí)行期間),根據(jù)簡檔信息320,執(zhí)行控制器308可啟用解釋器310來 解釋源代碼208的各部分,并可啟用JIT編譯器312來編譯源代碼208的其它各部分。
      [0049] 當(dāng)由解釋器控制信號啟用解釋器310時,解釋器310可以解釋并執(zhí)行所生成的字 節(jié)代碼。解釋器310可被實現(xiàn)為JavaScript解釋器、VBScript解釋器、Python解釋器或用 于在此其它地方提到的或以其它方式所知的另一動態(tài)語言的解釋器。通過該方式,源代碼 208可至少部分地由解釋器310的操作來執(zhí)行。
      [0050] 當(dāng)JIT編譯器312由編譯器控制信號啟用時,JIT編譯器312可編譯所生成的字 節(jié)代碼。JIT編譯器312可被實現(xiàn)為JavaScript編譯器、VBScript編譯器、Python編譯器 或用于在此其它地方提到的或以其它方式所知的另一動態(tài)語言的編譯器。JIT編譯器312 被稱為"即時"編譯器,這是因為由于需要經(jīng)編譯的字節(jié)代碼(即,要被緊急執(zhí)行的),特定 的字節(jié)代碼部分可由JIT編譯器312編譯,而非在執(zhí)行之前預(yù)先編譯完整的字節(jié)代碼。JIT 編譯器312可以生成具有機器可執(zhí)行代碼或指令形式的經(jīng)編譯的字節(jié)代碼332。
      [0051] JIT編譯器312可以基于如上所述的假設(shè)執(zhí)行代碼優(yōu)化。JIT編譯器312可以在 它生成的經(jīng)編譯的字節(jié)代碼中插入一個或多個預(yù)先確定的跳出點。對于每個跳出點,諸如 跳出表格303等之類的跳出表格可以被創(chuàng)建,在其中,可以記錄變量的狀態(tài)、在所生成的字 節(jié)代碼中與跳出點的位置相對應(yīng)的位置。跳出表格可以描述在堆棧上或機器代碼的寄存器 中哪里可以找到變量。JIT編譯器312可以生成表格并將它們與經(jīng)優(yōu)化的編譯的字節(jié)代碼 332(例如機器代碼)一起保存。經(jīng)優(yōu)化的編譯的字節(jié)代碼332可以被作為用于在由系統(tǒng) 300后續(xù)執(zhí)行程序期間訪問的經(jīng)編譯的字節(jié)代碼332來存儲在存儲314中。
      [0052] 當(dāng)執(zhí)行經(jīng)優(yōu)化的編譯的字節(jié)代碼時,可由機器代碼執(zhí)行器316(它可以是諸如處 理器142等的一個或多個處理器)接收經(jīng)優(yōu)化的編譯的字節(jié)代碼332。在每個跳出點處可 以檢查所述優(yōu)化所基于的底層的一種或多種假設(shè)是有效還是無效的。響應(yīng)于確定所述假設(shè) 是有效的,經(jīng)優(yōu)化的編譯的字節(jié)代碼332可以繼續(xù)執(zhí)行。響應(yīng)于確定所述假設(shè)是無效的,經(jīng) 優(yōu)化的編譯的代碼的執(zhí)行可以被停止。可以將該跳出點的跳出表格傳遞給跳出引擎336。 跳出引擎336可以還原解釋器所需的變量的狀態(tài)(例如值)。如果解釋器所需的變量已變 成非活動的,跳出引擎336可以通過將變量的狀態(tài)從非活動改變到活動來復(fù)活該變量。跳 出引擎336可以實例化解釋器310的實例,向解釋器傳遞在未經(jīng)優(yōu)化的字節(jié)代碼中與在經(jīng) 優(yōu)化的編譯的代碼中的跳出點相對應(yīng)的位置、變量和它們的位置。因此這樣,從其生成字節(jié) 代碼的源代碼可以由JIT編譯器312和機器代碼執(zhí)行器316的操作來部分執(zhí)行并由解釋器 310來部分執(zhí)行。
      [0053] 跳出的使用可以允許多次優(yōu)化。在許多動態(tài)編程語言中的變量可以是日期、字符 串、數(shù)組、整數(shù)等等。在一些動態(tài)語言中,為變量創(chuàng)建對象,并且存儲在寄存器中并隨后存 儲在表格中的位置包括指向該對象的指針。對象自身可以存儲對象的描述和對象的數(shù)據(jù)。 這樣,如果變量a是字符串,可以為該字符串創(chuàng)建對象,指向該對象的指針可以被存儲,且 對象自身可以標(biāo)識變量a為字符串并可以指定該字符串自身(例如"你好世界"("Hello World"))。一種用于在當(dāng)基于簡檔數(shù)據(jù)假設(shè)變量為整數(shù)的情況下的方案的優(yōu)化是將整數(shù)自 身存儲在變量中以取代指向為該整數(shù)創(chuàng)建的對象的指針或表示并描述該整數(shù)對象的經(jīng)編 碼的值。一種直接對整數(shù)對象進(jìn)行編碼的方案是使用單詞的位之一來存儲標(biāo)記該值為整數(shù) 的指示符。這樣,在32位處理器的情況下,32位的一個位可以指示其它31位的內(nèi)容表示整 數(shù)值或可指示其它31位的內(nèi)容不表示整數(shù)值。
      [0054] 圖Id示出以JavaScript編寫的源代碼152的示例150,在其中,函數(shù)foo執(zhí)行兩 個變量a和b的加法并返回加法操作的結(jié)果。在示例150中顯示的字節(jié)代碼154是從該示 例的源代碼152中生成的字節(jié)代碼。在行#1,將第一自變量(a)加載到解釋器臨時變量tl。 在行#2,將第二自變量(b)加載到解釋器臨時變量t2。在行#3,臨時變量tl的內(nèi)容和臨時 變量t2的內(nèi)容被相加并放置到解釋器臨時變量t0中。在行#4,返回臨時變量t0的內(nèi)容。 臨時變量tl、臨時變量t2和臨時變量t0的內(nèi)容在JavaScript中可以無論怎樣都是合法 的,包括浮點數(shù)、整數(shù)、字符串等等。
      [0055] 在圖Id中,所生成的代碼156示出表示編譯字節(jié)代碼154并基于簡檔數(shù)據(jù)對其進(jìn) 行整數(shù)加法優(yōu)化的結(jié)果的偽代碼。當(dāng)字節(jié)代碼154被編譯時,并不知道變量a和b的類型 是什么。變量a和/或變量b可以是字符串、日期、整數(shù)等等。如果變量a和b是日期,將 執(zhí)行一種加法操作,如果變量a和變量b是字符串,串聯(lián)操作將準(zhǔn)備就緒,并且如果變量a 和變量b是浮點數(shù),則將調(diào)用浮點加法操作。如果期望變量a和變量b很可能是整數(shù)(例 如通過運行解釋器多次并發(fā)現(xiàn)變量a和變量b總是整數(shù))是合理的,那么編譯的代碼的樂 觀優(yōu)化可以執(zhí)行整數(shù)加法,如由所生成的代碼156所示,該樂觀優(yōu)化針對整數(shù)加法進(jìn)行了 優(yōu)化。由于在當(dāng)變量a和變量b是日期、字符串或非整數(shù)數(shù)字的情況下通過不提供代碼路 徑減少了執(zhí)行的代碼量,所述代碼被優(yōu)化了。
      [0056] 在所生成的代碼156的行#1,將第一自變量(a)加載到寄存器regl。在這點(跳 出點#1)處,檢查regl的內(nèi)容以查看regl的內(nèi)容是否真的是整數(shù)。響應(yīng)于regl的內(nèi)容不 是整數(shù),(行#2),所生成的代碼的執(zhí)行被停止,并且調(diào)用跳出引擎(在所生成的代碼156的 行#3處執(zhí)行跳出指令)。在解釋器中在字節(jié)代碼154的行#2處繼續(xù)程序執(zhí)行,因為字節(jié)代 碼154的行#1已經(jīng)被執(zhí)行。tl的內(nèi)容已經(jīng)被放置在regl中。t2和t0還不是活動的,并 且不必被復(fù)活。發(fā)送給跳出引擎的表格的內(nèi)容被示出在圖Id的表格1的內(nèi)容158中。表 格1的內(nèi)容158描述了跳出點1的執(zhí)行在字節(jié)代碼154的行#2處恢復(fù),變量tl的值被存 儲在:regl中,而變量t2和t0當(dāng)前并不是活的。這意味著變量t2和t0是不活動的且不需 要被復(fù)活。
      [0057] 如果相反,regl的內(nèi)容是整數(shù),則所生成的代碼156在所生成的代碼156的行#4 處繼續(xù)執(zhí)行。在行#4處,自變量b被加載到寄存器reg2中。在所生成的代碼156的行#5 處,檢查reg2的內(nèi)容以確定它是整數(shù)還是非整數(shù)。如果reg2的內(nèi)容是非整數(shù),在行#6執(zhí) 行跳出指令。所生成的代碼156的執(zhí)行停止,且在解釋器中在字節(jié)代碼154的行#3處執(zhí)行 恢復(fù)。變量a和b是活動的。存儲在tl中的變量a的值駐留在regl,而存儲在t2中的變 量b的值駐留在reg2。t0不是活的。該信息被放置在表格2(表格2160的內(nèi)容)中。
      [0058] 如果相反,reg2的內(nèi)容是整數(shù),則所生成的代碼156在所生成的代碼156的行#7 處繼續(xù)執(zhí)行。將1^81和^82的內(nèi)容相加并放置在寄存器^83中。在行#7,^81和^82 相加的結(jié)果被放置在寄存器reg3中。在行#8,如果reg3溢出,則到達(dá)第三跳出點。在第 三跳出點,在行#9,跳出被定向到字節(jié)代碼154的行#3以通過不丟失信息的方式來重做操 作。相關(guān)聯(lián)的表格Table3162的內(nèi)容與表格2是相同的。為了避免丟失信息,整數(shù)值可以 被轉(zhuǎn)換成浮點數(shù),并且在解釋器中可以執(zhí)行浮點加法。如果相反,reg3不溢出,所生成的代 碼156在所生成的代碼156的行#10處繼續(xù)執(zhí)行并返回reg3中的值。
      [0059] 在上述示例中,JavaScript指針的一個位可以被設(shè)定為指示符值,該指示符值指 示了剩余的31位表示整數(shù)值。為了在整數(shù)上執(zhí)行數(shù)學(xué)運算,可以從存儲了指針的32位寄存 器中提取表示整數(shù)的31位并可以執(zhí)行所述運算。隨后可以在經(jīng)解碼的整數(shù)值上執(zhí)行進(jìn)一 步的數(shù)學(xué)運算。一旦數(shù)學(xué)運算的值或結(jié)果需要被存儲或傳遞到當(dāng)前編譯范圍之外的進(jìn)程, 可以將其重新編碼成JavaScript對象指針,將所述指示符位設(shè)定回指示符值。例如,根據(jù) 在此所述的主題的一些實施例,在所生成的代碼156的行#10處返回reg3之前,可以撤消 整數(shù)類型的專用化并重新編碼該值。(為了清楚起見,編碼/解碼步驟并沒有包括在偽代碼 示例中。)表格還可以捕捉tl是在regl中的信息。因為該信息是被解碼的,它可以被重新 編碼成JavaScript值,將指示符位重置為指示其它31位不是整數(shù)值。類似地,64位浮點值 可以被表示為對象,這樣,對于在regl中的浮點數(shù)來說,可以做出regl的內(nèi)容是浮點數(shù)的 檢查。如果是,來自JavaScript數(shù)字的浮點數(shù)據(jù)被加載到浮點寄存器中并且最后可以創(chuàng)建 新的JavaScript數(shù)字,在該新的JavaScript數(shù)字中,在要返回給調(diào)用者的寄存器中放置結(jié) 果數(shù)字、放置指向JavaScript數(shù)字的指針。
      [0060] 圖le示出為圖Id的相同的JavaScript源代碼(源代碼152)的浮點數(shù)的加法優(yōu) 化的經(jīng)編譯的代碼的示例170。源代碼和字節(jié)代碼154兩者是相同的,例如170與例如150 相同,然而,僅僅為了示例170,假設(shè)期望變量是浮點數(shù)而不是整數(shù)是合理的。將理解的是, 第一跳出點和第一跳出點的對應(yīng)的表格信息與針對整數(shù)加法優(yōu)化的所生成代碼156相同。
      [0061] 在示例170的行#1處,變量可以被加載到寄存器regl中。在行#2處檢查regl 的內(nèi)容以確定regl的內(nèi)容是否指向JavaScript數(shù)字。響應(yīng)于確定regl的內(nèi)容不是指向 JavaScript數(shù)字,可在行#3調(diào)用跳出引擎。存儲在該跳出點(跳出點#1)的表格中的跳出 信息與先前示例150中的相同。如果regl的內(nèi)容指向JavaScript數(shù)字,在行#4處,可以通 過使用regl訪問來自JavaScript數(shù)字的浮點數(shù)據(jù)來從JavaScript數(shù)字中查明浮點值,并 將浮點數(shù)據(jù)加載到浮點寄存器floatRegl中。因為不再需要regl,編譯器可以在行#5處重 用regl來加載變量b。在行#6處,可以檢查regl以確定其內(nèi)容是否指向JavaScript數(shù)字。 如果它沒有,在行#7處可以調(diào)用跳出引擎。在跳出點#2,為了復(fù)活tl,可以從floatRegl 中查明變量a的值。
      [0062] 跳出引擎可以確定變量a是浮點數(shù)字,并可創(chuàng)建JavaScript數(shù)字對象,并可放置 tl中的JavaScript數(shù)字的位置以允許解釋器開始從字節(jié)代碼154的行#3處執(zhí)行,因為解 釋器處理不是浮點值的JavaScript對象。在該點處,t2駐留在regl中,而t0不是活的。 如果相反,在行#6處,regl的內(nèi)容確實指向JavaScript數(shù)字,可以通過使用regl訪問來自 JavaScript數(shù)字的浮點數(shù)據(jù)來從JavaScript數(shù)字中查明浮點值,并在行#8將浮點數(shù)據(jù)加 載到浮點寄存器floatReg2中。在行#9,可以執(zhí)行兩個浮點數(shù)字的加法并可將結(jié)果存儲在 fl〇atReg3中。在此不需要跳出,因為JavaScript將數(shù)字運算定義為正被雙精度浮點運算 執(zhí)行,因此,任何浮點溢出都將表現(xiàn)出按每JavaScript慣例的行為。因為不再需要regl,在 行#10處編譯器可以重用regl以保持指向所構(gòu)造的JavaScript數(shù)字對象的位置的指針, 所述JavaScript數(shù)字對象持有將兩個浮點值相加的結(jié)果。在行#11,可將regl返回給調(diào)用 者。
      [0063] 當(dāng)?shù)谝缓瘮?shù)(例如函數(shù)foo)調(diào)用第二函數(shù)(例如函數(shù)bar)時,可以應(yīng)用另一種 被稱為內(nèi)聯(lián)(in-lining)的優(yōu)化。在這種情況下,函數(shù)bar的代碼可以以順序次序在函數(shù) foo的代碼內(nèi)部被寫出。如果在內(nèi)聯(lián)的函數(shù)內(nèi)部出現(xiàn)跳出,則調(diào)用函數(shù)和被調(diào)用函數(shù)兩者的 狀態(tài)可都被還原,并且這兩個函數(shù)可以運行??梢詣?chuàng)建被調(diào)用函數(shù)的表格以及調(diào)用函數(shù)的 表格。
      [0064] 當(dāng)以諸如JavaScript之類的動態(tài)語言做出函數(shù)調(diào)用時,編譯器不能確定在編譯 時哪個函數(shù)正被調(diào)用。雖然腳本可以指示函數(shù)foo正被調(diào)用,在運行時,被稱為foo的函數(shù) 可以改變。這樣,就不能做出關(guān)于在編譯時哪個函數(shù)正被調(diào)用的假設(shè)。內(nèi)聯(lián)在調(diào)用函數(shù)的 內(nèi)部直接生成被調(diào)用函數(shù)的代碼。當(dāng)該代碼被執(zhí)行時,可以動態(tài)地做出經(jīng)內(nèi)聯(lián)的函數(shù)是應(yīng) 該實際被調(diào)用的函數(shù)的檢查。根據(jù)在此所述的主題的各方面,如果正被調(diào)用的函數(shù)不是經(jīng) 內(nèi)聯(lián)的函數(shù),則可做出對跳出引擎的調(diào)用。在圖If中,示例m,JavaScript函數(shù)barl72 以及JavaScript函數(shù)fool73被定義。經(jīng)編譯的代碼在經(jīng)編譯的代碼174中示出。
      [0065] 編譯器可以做出下述優(yōu)化。如果bar被調(diào)用,貝U聲明var c = a+b ;在函數(shù)fool73 中是非必要的,因為bar總是返回10。函數(shù)foo返回0,因為bar返回值10。但由于bar 可以改變,可做出一個檢查來查看bar是否已經(jīng)改變。如果bar已經(jīng)改變,可以做出對跳出 引擎的調(diào)用。如果做出對跳出引擎的調(diào)用,解釋器將需要變量c。為了使得c可用,將需要 a+b。a+b被存儲在reg3中,因此,不能釋放reg3以供重用直到跳出發(fā)生之后。這樣,以其 它方式將變得非活動的變量可以被維持在活動狀態(tài)。
      [0066] 在圖 lg 中的不例 180 中,JavaScript 函數(shù) barl82 以及 JavaScript 函數(shù) fool83 被定義。函數(shù)barl82具有兩個自變量:變量a和函數(shù)func。腳本184調(diào)用具有a = 2和 func = foo的函數(shù)barl82。從腳本184生成的字節(jié)代碼在字節(jié)代碼185中被示出。
      [0067] 在行#1處,函數(shù)barl85的字節(jié)代碼將變量a的值(2)放置在tl中。在行#2處, 常量100被放置在t2中,在行#3處,函數(shù)foo被放置在t3中,而在行#4處,用自變量2 和100來調(diào)用函數(shù)foo。在行#5處,將用自變量2和100調(diào)用foo的結(jié)果與2相加并將結(jié) 果放置在被返回的t0中。函數(shù)foo的經(jīng)編譯的字節(jié)代碼在圖Id中被示為所生成的代碼 156。將函數(shù)fool83內(nèi)聯(lián)到函數(shù)barl82的經(jīng)編譯的代碼在圖lg中被示為所生成的代碼 186。在第一跳出點前,BarNativeCode(Bar本機代碼)是堆棧的頂層框架。當(dāng)在第一跳 出點處調(diào)用跳出引擎時,調(diào)用跳出引擎的新框架將被放置在堆棧的頂部。當(dāng)跳出引擎創(chuàng)建 foo的存儲的經(jīng)解釋的框架并開始在解釋器上運行它時,頂部的4個框架將是foo經(jīng)還原的 被解釋的框架,下一個將是跳出引擎的框架,下一個是具有內(nèi)聯(lián)的foo和調(diào)用者框架的Bar NativeCode(本機代碼)的框架。在經(jīng)還原的foo完成正被解釋之后,跳出引擎可以創(chuàng)建 bar的經(jīng)還原的被解釋的框架并可以開始在解釋器上運行它。從上至下堆棧將出現(xiàn):Bar經(jīng) 還原的被解釋的框架、跳出引擎的框架、具有內(nèi)聯(lián)的f〇〇和調(diào)用者框架的Bar NativeCode 的框架。最后,在經(jīng)還原的bar完成解釋之后,跳出引擎可以返回到bar本機代碼,并且bar 本機代碼可以返回到調(diào)用者。在這個點,堆棧的頂層框架將是調(diào)用者框架。
      [0068] 內(nèi)聯(lián)代碼188和經(jīng)內(nèi)聯(lián)的代碼189表示在所生成的代碼186中來自已經(jīng)被內(nèi)聯(lián)到 函數(shù)bar中的函數(shù)foo的代碼。在函數(shù)foo已經(jīng)被內(nèi)聯(lián)到函數(shù)bar中之后,函數(shù)foo可以 改變。到bar函數(shù)字節(jié)代碼185的第一跳出檢查foo是正確的函數(shù)。該函數(shù)被加載到reg3 中并檢查reg3以查看函數(shù)是否是foo。如果是,經(jīng)編譯的代碼的執(zhí)行繼續(xù)。如果不是,執(zhí) 行在解釋器中恢復(fù)。在第一跳出點處調(diào)用跳出引擎,并且執(zhí)行在函數(shù)barl85的行#4處恢 復(fù)。這是一個簡單的跳出,因為執(zhí)行是在內(nèi)聯(lián)外部發(fā)生的,這樣在還原tl、t2和t3之后,執(zhí) 行可以在解釋器中繼續(xù)。如果該函數(shù)是f 〇〇,執(zhí)行繼續(xù)并且執(zhí)行經(jīng)內(nèi)聯(lián)的代碼188。在經(jīng)內(nèi) 聯(lián)的代碼188中,如果regl的內(nèi)容不是整數(shù),則在第二跳出點處調(diào)用跳出引擎,并且執(zhí)行在 foo (字節(jié)代碼154)中的行#2處恢復(fù)。由于bar實際上正在被執(zhí)行,到函數(shù)bar的行#5的 跳出可以被很好完成。在foo完成執(zhí)行之后,foo的結(jié)果可以被放置在t4中??梢宰龀龅?bar的行#5的跳出,tl在regl中,并且t4將包含從跳出到foo的解釋器返回值。該信息 可以被編碼到2個鏈接在一起的表格中,以便這兩個跳出將一個接一個發(fā)生。在加法溢出 時,可以在內(nèi)聯(lián)代碼189中執(zhí)行類似的處理。將可以理解,如上所述,跳出在一行中出現(xiàn)一 次,而框架被每次復(fù)活一個框架。當(dāng)返回給調(diào)用者時,調(diào)用者的框架被復(fù)活。
      [0069] 在第一跳出點前,BarNativeCode是堆棧的頂層框架。當(dāng)在第一跳出點處調(diào)用跳 出引擎時,調(diào)用跳出引擎的新框架將被放置在堆棧的頂部。當(dāng)跳出引擎創(chuàng)建foo的存儲的 經(jīng)解釋的框架并開始在解釋器上運行它時,頂部的4個框架將是foo經(jīng)還原的被解釋的框 架,下一個將是跳出引擎的框架,下一個是具有內(nèi)聯(lián)的foo的Bar NativeCode的框架。在 經(jīng)還原的f〇〇完成正被解釋之后,跳出引擎可以創(chuàng)建bar的經(jīng)還原的被解釋的框架并可以 開始在解釋器上運行它。從上至下堆棧將出現(xiàn):Bar經(jīng)還原的被解釋的框架、跳出引擎的框 架、具有內(nèi)聯(lián)的foo和調(diào)用者框架的Bar NativeCode的框架。最后,在經(jīng)還原bar完成解 釋之后,跳出引擎可以返回到bar本機代碼,并且bar本機代碼可以返回到調(diào)用者。在這個 點,堆棧的頂層框架將是調(diào)用者框架。
      [0070] 圖2示出了可以將以動態(tài)語言編寫的程序的執(zhí)行從經(jīng)編譯的代碼變換成經(jīng)解釋 的代碼的方法250。方法250可以由諸如如上所述的系統(tǒng)100、系統(tǒng)200和/或系統(tǒng)300之 類的系統(tǒng)來實現(xiàn)。所描述的順序是可選的。并不是所有的動作都要被采用。在252,可以由 計算設(shè)備的處理器接收字節(jié)代碼。在254,可以做出關(guān)于程序可以在其上操作的數(shù)據(jù)的一種 或多種假設(shè)。在256,基于所述假設(shè),可以基于所述一種或多種假設(shè)為所接收的字節(jié)代碼的 一部分生成經(jīng)優(yōu)化的編譯的代碼。在預(yù)置的跳出點處可以捕捉變量值位置。還可以捕捉在 字節(jié)代碼中的對應(yīng)位置。在260,可以執(zhí)行經(jīng)優(yōu)化的編譯的代碼。變量值可以被保存在變量 值位置中。在262,可以檢查經(jīng)編譯的代碼中的優(yōu)化所基于的假設(shè)的有效性。在264,響應(yīng) 于確定所述假設(shè)還是有效的,經(jīng)編譯的代碼的執(zhí)行可以繼續(xù)。在266,響應(yīng)于確定所述假設(shè) 是無效的,經(jīng)編譯的代碼的執(zhí)行可以在跳出點處停止。在268,來自所捕捉位置的變量值可 以被用于還原解釋器變量值。在270,對在字節(jié)代碼中的所指示的模擬位置處的字節(jié)代碼的 解釋可以開始。
      [0071] 合適的計算環(huán)境的示例
      [0072] 為了提供有關(guān)本文所公開主題的各方面的上下文,圖3以及以下討論旨在提供其 中可以實現(xiàn)本文所公開主題的各實施例的合適計算環(huán)境510的簡要概括描述。盡管本文所 公開的主題是在諸如程序模塊等由一個或多個計算機或其他計算設(shè)備執(zhí)行的計算機可執(zhí) 行指令的通用上下文中描述的,但本領(lǐng)域技術(shù)人員將認(rèn)識到,本文所公開的主題的各部分 還能夠結(jié)合其他程序模塊和/或硬件和軟件的組合來實現(xiàn)。通常,程序模塊包括執(zhí)行特定 任務(wù)或?qū)崿F(xiàn)特定數(shù)據(jù)類型的例程、程序、對象、物理人為產(chǎn)物、數(shù)據(jù)結(jié)構(gòu)等。通常,程序模塊 的功能可在各個實施例中按需進(jìn)行組合或分布。計算環(huán)境510只是合適的操作環(huán)境的一個 示例,并且不旨在對此處所公開的主題的使用范圍或功能提出任何限制。
      [0073] 參考圖3,描述了計算機512形式的計算設(shè)備。計算機512可包括至少一個處理單 元514、系統(tǒng)存儲器516和系統(tǒng)總線518。至少一個處理單元514可執(zhí)行被存儲在諸如但不 限于系統(tǒng)存儲器516之類的存儲器中的指令。處理單元514可以是各種可用處理器中的任 何一種。例如,處理單元514可以是GPU。這些指令可以是用于實現(xiàn)被描述為由上述一個 或多個組件或模塊所執(zhí)行的功能的指令或用于實現(xiàn)上述方法中的一個或多個的指令。也可 以使用雙微處理器及其他多處理器體系結(jié)構(gòu)作為處理單元514。計算機512可被用于支持 在顯示屏上呈現(xiàn)圖形的系統(tǒng)中。在另一示例中,計算設(shè)備的至少一部分可以用在包括圖形 處理單元的系統(tǒng)中。系統(tǒng)存儲器516可包括易失性存儲器520和非易失性存儲器522。非 易失性存儲器522可包括只讀存儲器(ROM)、可編程ROM (PR0M)、電可編程ROM (EPR0M)或閃 存。易失性存儲器520可包括可充當(dāng)外高速緩沖存儲器的隨機存取存儲器(RAM)。系統(tǒng)總 線518將包括系統(tǒng)存儲器516的系統(tǒng)物理人為產(chǎn)物耦合到處理單元514。系統(tǒng)總線518可 以是幾種類型的總線結(jié)構(gòu)中的任何一種,包括存儲器總線、存儲控制器、外圍總線、外總線 或局部總線,并且可以使用各種可用總線體系結(jié)構(gòu)中的任一種。計算機512可包括處理單 元514可通過系統(tǒng)總線518訪問的數(shù)據(jù)存儲。數(shù)據(jù)存儲可包括用于圖形呈現(xiàn)的可執(zhí)行指令、 3D模型、素材、材質(zhì)等。
      [0074] 計算機512通常包括各種計算機可讀介質(zhì),諸如易失性和非易失性介質(zhì)、可移動 和不可移動介質(zhì)。計算機存儲介質(zhì)可以通過用于存儲諸如計算機可讀指令、數(shù)據(jù)結(jié)構(gòu)、程 序模塊或其它數(shù)據(jù)等信息的任何方法或技術(shù)來實現(xiàn)。計算機存儲介質(zhì)包括但不限于,RAM、 ROM、EEPR0M、閃存或其它存儲器技術(shù)、CDR0M、數(shù)字多功能盤(DVD)或其它光盤存儲、磁盒、 磁帶、磁盤存儲或其它磁存儲設(shè)備、或可以用來儲存所期望的信息并可由計算機512訪問 的任何其他瞬態(tài)或非瞬態(tài)介質(zhì)。
      [0075] 將理解,圖3描述了可充當(dāng)用戶與計算機資源之間的媒介的軟件。該軟件可以包 括可存儲在盤存儲524上的操作系統(tǒng)528,該操作系統(tǒng)可分配計算機512的資源。盤存儲 524可以是通過諸如接口 526等不可移動存儲器接口連接到系統(tǒng)總線518的硬盤驅(qū)動器。 系統(tǒng)應(yīng)用程序530利用由操作系統(tǒng)528通過存儲在系統(tǒng)存儲器516或者存儲在盤存儲524 上的程序模塊532和程序數(shù)據(jù)534對資源的管理??梢岳斫?,計算機可用各種操作系統(tǒng)或 操作系統(tǒng)的組合來實現(xiàn)。
      [0076] 用戶可通過輸入設(shè)備536向計算機512輸入命令或信息。輸入設(shè)備536包括但不 限于定點設(shè)備,諸如鼠標(biāo)、跟蹤球、指示筆、觸摸墊、鍵盤、話筒等。這些及其他輸入設(shè)備通過 系統(tǒng)總線518經(jīng)由接口端口 538連接到處理單元514。接口端口 538可表示串行端口、并行 端口、通用串行總線(USB)等。輸出設(shè)備540可與輸入設(shè)備使用相同類型的端口。提供輸 出適配器542以舉例說明存在像監(jiān)視器、揚聲器、以及打印機的需要特定適配器的一些輸 出設(shè)備540。輸出適配器542包括但不限于,在輸出設(shè)備540和系統(tǒng)總線518之間提供連接 的視頻卡和聲卡。其他設(shè)備和/或系統(tǒng)和/或設(shè)備,諸如遠(yuǎn)程計算機544,可提供輸入和輸 出兩種能力。
      [0077] 計算機512可以使用到諸如遠(yuǎn)程計算機544之類的一個或多個遠(yuǎn)程計算機的邏輯 連接來在聯(lián)網(wǎng)環(huán)境中操作。遠(yuǎn)程計算機544可以是個人計算機、服務(wù)器、路由器、網(wǎng)絡(luò)PC、對 等設(shè)備或其他常見的網(wǎng)絡(luò)節(jié)點,并且通常包括許多或所有以上相對于計算機512所描述的 元件,但在圖3中僅示出了存儲器存儲設(shè)備546。遠(yuǎn)程計算機544可經(jīng)由通信連接550邏輯 地連接。網(wǎng)絡(luò)接口 548涵蓋諸如局域網(wǎng)(LAN)和廣域網(wǎng)(WAN)這樣的通信網(wǎng)絡(luò),但也可包 括其他網(wǎng)絡(luò)。通信連接550是指用來將網(wǎng)絡(luò)接口 548連接到總線518的硬件/軟件。通信 連接550可以在計算機512內(nèi)或外并且包括諸如調(diào)制解調(diào)器(電話、電纜、DSL和無線)和 ISDN適配器、以太網(wǎng)卡等內(nèi)和外技術(shù)。
      [0078] 可以理解,所示網(wǎng)絡(luò)連接僅是示例,并且可以使用在計算機之間建立通信鏈路的 其他手段。本領(lǐng)域的普通技術(shù)人員可以理解,計算機512或其他客戶機設(shè)備可作為計算機 網(wǎng)絡(luò)的一部分來部署。在這一點上,本文所公開的主題涉及具有任意數(shù)量的存儲器或存儲 單元以及在任意數(shù)量的存儲單元或卷上發(fā)生的任意數(shù)量的應(yīng)用和進(jìn)程的任何計算機系統(tǒng)。 本文所公開的主題的各方面可應(yīng)用于具有部署在網(wǎng)絡(luò)環(huán)境中的具有遠(yuǎn)程或本地存儲的服 務(wù)器計算機和客戶計算機的環(huán)境。本文所公開的主題的各方面也可應(yīng)用于具有編程語言功 能、解釋和執(zhí)行能力的獨立計算設(shè)備。
      [0079] 本文所述的各種技術(shù)可結(jié)合硬件或軟件,或在適當(dāng)時以其組合來實現(xiàn)。由此,本文 所公開的方法和裝置或其特定方面或部分可采取包含在諸如軟盤、CD-ROM、硬盤驅(qū)動器或 任何其他機器可讀存儲介質(zhì)等有形介質(zhì)中的程序代碼(即,指令)的形式,其中當(dāng)程序代碼 被加載到諸如計算機等機器內(nèi)并由其執(zhí)行時,該機器成為用于實現(xiàn)本文所公開的主題的各 方面的裝置。如此出所用的,術(shù)語"機器可讀介質(zhì)"應(yīng)被用來排除提供(即存儲和/或傳輸) 任何形式的傳播信號的任何機制。在程序代碼在可編程計算機上執(zhí)行的情況下,計算設(shè)備 通常將包括處理器、該處理器可讀的存儲介質(zhì)(包括易失性和非易失性的存儲器和/或存 儲元件)、至少一個輸入設(shè)備、以及至少一個輸出設(shè)備??衫缤ㄟ^使用數(shù)據(jù)處理API等來 利用域?qū)S镁幊棠P透鞣矫娴膭?chuàng)建和/或?qū)崿F(xiàn)的一個或多個程序可用高級過程語言或面 向?qū)ο蟮木幊陶Z言來實現(xiàn)以與計算機系統(tǒng)通信。然而,如果需要,該程序可以用匯編語言或 機器語言來實現(xiàn)。在任何情形中,語言可以是編譯語言或解釋語言,且與硬件實現(xiàn)相結(jié)合。
      [0080] 盡管用結(jié)構(gòu)特征和/或方法動作專用的語言描述了本主題,但可以理解,所附權(quán) 利要求書中定義的主題不必限于上述具體特征或動作。更確切而言,上述具體特征和動作 是作為實現(xiàn)權(quán)利要求的示例形式公開的。
      【權(quán)利要求】
      1. 一種系統(tǒng),包括: 計算設(shè)備的至少一個處理器; 所述計算設(shè)備的存儲器;以及 包括加載到所述存儲器中的至少一個模塊的跳出引擎,所述至少一個模塊使所述至少 一個處理器: 響應(yīng)于檢測到關(guān)于程序在其上操作的數(shù)據(jù)的特性的至少一種假設(shè)的無效性,將以動態(tài) 語言編寫的程序的執(zhí)行從機器代碼執(zhí)行器執(zhí)行的經(jīng)編譯的代碼變換到由解釋器解釋的經(jīng) 解釋的字節(jié)代碼,所述經(jīng)編譯的代碼基于所述至少一種假設(shè)被優(yōu)化,所述經(jīng)解釋的字節(jié)代 碼沒有基于所述至少一種假設(shè)被優(yōu)化; 在所述經(jīng)解釋的字節(jié)代碼中的一個點處恢復(fù)在解釋器中的所述程序的執(zhí)行,所述點對 應(yīng)于在經(jīng)優(yōu)化的編譯的代碼中檢測到無效性處的點。
      2. 如權(quán)利要求1所述的系統(tǒng),其特征在于,還包括: 加載到所述存儲器中的至少一個模塊,所述至少一個模塊使所述至少一個處理器: 從由所述機器代碼執(zhí)行器所使用的對應(yīng)變量中重新物化由所述解釋器所使用的變量。
      3. 如權(quán)利要求1所述的系統(tǒng),其特征在于,還包括: 加載到所述存儲器中的至少一個模塊,所述至少一個模塊使所述至少一個處理器: 在所述經(jīng)優(yōu)化的編譯的字節(jié)代碼中插入至少一個跳出點,所述至少一個跳出點與持有 所述解釋器恢復(fù)所述程序的執(zhí)行所需要的值的一組變量相關(guān)聯(lián)。
      4. 如權(quán)利要求1所述的系統(tǒng),其特征在于,其中執(zhí)行是在經(jīng)優(yōu)化的編譯的代碼中預(yù)先 確定的跳出點處被從經(jīng)優(yōu)化的編譯的代碼變換到未經(jīng)優(yōu)化的字節(jié)代碼。
      5. -種方法,包括: 在計算設(shè)備的處理器處接收字節(jié)代碼,所接收的字節(jié)代碼包括源自以動態(tài)語言編寫的 程序的未經(jīng)優(yōu)化的字節(jié)代碼; 接收關(guān)于由所述程序操作的數(shù)據(jù)的至少一種假設(shè); 基于所述至少一種假設(shè)生成經(jīng)優(yōu)化的編譯的代碼; 執(zhí)行所述經(jīng)優(yōu)化的編譯的代碼; 響應(yīng)于確定所述至少一種假設(shè)的無效性,停止所述經(jīng)優(yōu)化的編譯的代碼的執(zhí)行; 還原與所述經(jīng)優(yōu)化的編譯的代碼相關(guān)聯(lián)的變量相對應(yīng)的解釋器變量; 在所述未經(jīng)優(yōu)化的字節(jié)代碼中的一個點處恢復(fù)在解釋器中的所述程序的執(zhí)行,所述點 對應(yīng)于在經(jīng)優(yōu)化的編譯的代碼中確定所述無效性處的點。
      6. 如權(quán)利要求5所述的方法,其特征在于,還包括: 捕捉在所述未經(jīng)優(yōu)化的字節(jié)代碼中與在所述經(jīng)優(yōu)化的編譯的代碼中的至少一個預(yù)先 確定的跳出點相對應(yīng)的位置。
      7. 如權(quán)利要求6所述的方法,其特征在于,還包括: 捕捉與在所述經(jīng)優(yōu)化的編譯的代碼中的至少一個預(yù)先確定的跳出點相關(guān)聯(lián)的變量的 位置。
      8. 如權(quán)利要求7所述的方法,其特征在于,還包括: 執(zhí)行所述經(jīng)優(yōu)化的編譯的代碼;以及 在所述至少一個預(yù)先確定的跳出點處重新物化與所述經(jīng)優(yōu)化的編譯的代碼變量相關(guān) 聯(lián)的對應(yīng)的解釋器變量。
      9. 如權(quán)利要求5所述的方法,其特征在于,還包括: 復(fù)活由所述解釋器所使用的變量。
      10. -種包括當(dāng)執(zhí)行時使計算設(shè)備的至少一個處理器執(zhí)行下列操作的計算機可執(zhí)行指 令的計算機可讀存儲介質(zhì): 響應(yīng)于在跳出點處檢測到至少一個無效情況,從執(zhí)行源自以動態(tài)語言編寫的程序的經(jīng) 優(yōu)化的編譯的代碼中跳出,所述經(jīng)優(yōu)化的編譯的代碼基于至少一種無效假設(shè)被優(yōu)化; 基于所述經(jīng)優(yōu)化的編譯的代碼變量的狀態(tài)來還原解釋器變量的狀態(tài); 在未經(jīng)優(yōu)化的字節(jié)代碼中與在所述經(jīng)優(yōu)化的編譯的代碼中的所述跳出點相對應(yīng)的點 處,在所述解釋器中恢復(fù)所述程序的執(zhí)行; 執(zhí)行源自所述程序的經(jīng)優(yōu)化的編譯的代碼,所述程序以JavaScript編寫;以及 保存包括在所述經(jīng)優(yōu)化的編譯的程序執(zhí)行期間在其處存儲了變量的位置的跳出信息。
      【文檔編號】G06F9/30GK104115120SQ201380008460
      【公開日】2014年10月22日 申請日期:2013年1月31日 優(yōu)先權(quán)日:2012年2月7日
      【發(fā)明者】L·拉弗里尼爾, C·曼 申請人:微軟公司
      網(wǎng)友詢問留言 已有0條留言
      • 還沒有人留言評論。精彩留言會獲得點贊!
      1