動態(tài)語言的優(yōu)化執(zhí)行的制作方法【專利摘要】通過包括執(zhí)行上下文和執(zhí)行代碼庫的動態(tài)執(zhí)行模塊來執(zhí)行動態(tài)語言的程序代碼。程序代碼的指令被轉換為存儲在執(zhí)行代碼庫中的機器代碼,執(zhí)行上下文通過執(zhí)行以及跨越執(zhí)行跟蹤程序的運行時狀態(tài)和持久狀態(tài)。使用執(zhí)行代碼庫和執(zhí)行上下文,動態(tài)執(zhí)行模塊使重復的機器代碼生成最小化,同時保留了程序的動態(tài)方面?!緦@f明】動態(tài)語言的優(yōu)化執(zhí)行【
技術領域:
】[0001]本公開一般地涉及動態(tài)計算機程序語言和即時(just-in-time)代碼生成領域。具體地,本公開描述了一種通過上下文跟蹤和即時代碼生成來優(yōu)化執(zhí)行動態(tài)計算機程序語言的系統(tǒng)、方法和過程?!?br>背景技術:
】[0002]針對web開發(fā)和應用開發(fā)已大量采用了諸如PHP:超文本預處理器(PHP)、Python、Ruby和Perl的動態(tài)語言,因為它們使得開發(fā)者產(chǎn)率高。這些語言有許多特征有助于它們的多產(chǎn)特性,但是最重要的兩個特征是運行時鍵入和將新數(shù)據(jù)動態(tài)地評價為代碼的能力。這些特性允許開發(fā)者編寫能夠比以諸如C、Java或C++的語言編寫的靜態(tài)代碼更靈活地使用的代碼。例如,動態(tài)語言通過在運行時允許開發(fā)者有條件地從現(xiàn)有代碼生成新的可執(zhí)行代碼以處理新數(shù)據(jù),來使得能夠進行更靈活的開發(fā)實踐。[0003]動態(tài)語言的缺點在于它們的執(zhí)行通常顯著慢于靜態(tài)語言(其可能強制編譯時靜態(tài)鍵入并且可能不允許動態(tài)代碼執(zhí)行)。由于在編譯時函數(shù)和變量的類型是已知的,并且由于可執(zhí)行代碼的全范圍是編譯器已知的,所以可在程序的執(zhí)行之前有效地將靜態(tài)語言轉換成機器代碼。在動態(tài)語言的情況下,在代碼被執(zhí)行的時刻之前,可執(zhí)行代碼的全范圍未知,并且許多函數(shù)和變量的類型可能未知。由于這些原因,動態(tài)語言無法在執(zhí)行之前被完全地轉換為機器代碼。另外,即使向機器代碼的運行時轉換常常也是不可行的,因為即時編譯過程本身可能需要大量執(zhí)行資源,導致執(zhí)行期間的性能下降?!?br/>發(fā)明內(nèi)容】[0004]所公開的配置包括一種通過動態(tài)執(zhí)行模塊來執(zhí)行計算機程序的系統(tǒng)、方法和計算機可讀介質(zhì)。所公開的配置包括一種計算機實現(xiàn)的方法,其中,接收執(zhí)行程序代碼的第一請求。這里,所述程序代碼包括初始代碼和運行時條件代碼。響應于第一請求,從初始代碼生成執(zhí)行資源,其中所述執(zhí)行資源包括執(zhí)行代碼庫(executioncodebase)和執(zhí)行上下文(executioncontext)。所述執(zhí)行代碼庫包括從初始代碼生成的機器代碼,并且所述執(zhí)行上下文包括存儲的對針對初始代碼中的函數(shù)、變量和用戶定義類型生成的元素的引用。執(zhí)行代碼庫中的機器代碼被執(zhí)行,并且使用運行時條件代碼來更新執(zhí)行代碼庫和執(zhí)行上下文。然后接收執(zhí)行程序代碼的第二請求,并且使用更新的執(zhí)行上下文來執(zhí)行更新的執(zhí)行代碼庫中的機器代碼?!緦@綀D】【附圖說明】[0005]圖1是示出執(zhí)行環(huán)境中的動態(tài)執(zhí)行模塊的示例實施例的高級框圖。[0006]圖2是示出示例計算機的高級框圖。[0007]圖3是示出根據(jù)一個實施例的動態(tài)執(zhí)行模塊內(nèi)的組件的詳細視圖的框圖。[0008]圖4是示出使用動態(tài)執(zhí)行模塊的一個實施例來執(zhí)行程序代碼的過程的流程圖。【具體實施方式】[0009]附圖和以下描述僅以例示方式描述特定實施例。本領域技術人員將容易從以下描述認識到在不脫離本文所述的原理的情況下可采用本文所示的結構和方法的替選實施例。現(xiàn)在將詳細參照若干實施例,其示例示出于附圖中。需要注意的是,只要可行,相似或相同的參考數(shù)字可用在圖中并且可指示相似或相同的功能。[0010]圖1示出在執(zhí)行環(huán)境120中的程序代碼100和動態(tài)執(zhí)行模塊101。執(zhí)行環(huán)境120包括可托管并執(zhí)行計算機程序指令的一個或多個計算機系統(tǒng)。在一個實施例中,執(zhí)行環(huán)境120是單個計算機系統(tǒng),例如web服務器。在另一實施例中,執(zhí)行環(huán)境包括通過網(wǎng)絡連接的若干算機系統(tǒng),例如數(shù)據(jù)中心中的服務器計算機。[0011]例如,程序代碼100包括以諸如?5^11〇11、?61'1、1^^、?即等的計算機語言的計算機源代碼。程序代碼100可包括初始代碼106和運行時條件代碼107。初始代碼106包括在發(fā)起程序代碼100的執(zhí)行時被加載的計算機指令。例如,初始代碼106可包括具有程序的"主函數(shù)"或"主循環(huán)"的文件。初始代碼106在被執(zhí)行時可加載調(diào)用運行時條件代碼107的附加計算機程序指令。運行時條件代碼107可基于在已發(fā)起執(zhí)行之后確定的情況來有條件地加載。例如,運行時條件代碼107可包括在運行時基于程序代碼100的當前執(zhí)行從數(shù)據(jù)庫加載的計算機指令。[0012]動態(tài)執(zhí)行模塊101是執(zhí)行環(huán)境120的組件,其使得程序代碼100能夠更有效地執(zhí)行。動態(tài)執(zhí)行模塊101取代了用于諸如PHP、Perl、Python或Ruby的編程語言的標準虛擬機或解析器。動態(tài)執(zhí)行模塊101可以是在還執(zhí)行執(zhí)行環(huán)境120的其它進程的硬件上執(zhí)行的軟件模塊,或者其可以在它自己的專用硬件資源上執(zhí)行。當程序代碼100在執(zhí)行環(huán)境120中執(zhí)行時,動態(tài)執(zhí)行模塊101管理并監(jiān)視該執(zhí)行以確保執(zhí)行既快速還有效。動態(tài)執(zhí)行模塊101可通過使用即時機器代碼生成、代碼片段跟蹤、機器代碼重用、上下文跟蹤以及其它技術來改善程序代碼100的執(zhí)行。本文中更詳細地描述了這些技術中的一些。[0013]動態(tài)執(zhí)行模塊101包括執(zhí)行資源102和執(zhí)行支持模塊105。執(zhí)行資源102是為特定程序代碼100生成的資源,其中一些資源可跨越相同代碼的若干調(diào)用一直存在。執(zhí)行資源102包括執(zhí)行上下文103和執(zhí)行代碼庫104。執(zhí)行上下文103存儲特定程序在執(zhí)行時的動態(tài)運行時狀態(tài)以及可跨越不同執(zhí)行一直存在的程序代碼100的結構和狀態(tài)。執(zhí)行上下文103包括結構,該結構存儲對針對程序代碼100中的函數(shù)、變量和用戶定義類型(例如類、結構等)生成的元素的引用。執(zhí)行上下文103可在程序代碼100的調(diào)用之間被重置,以防止來自一個調(diào)用的動態(tài)值污染代碼的下一調(diào)用。然而,執(zhí)行上下文重置可被執(zhí)行為使得保持非易失性數(shù)據(jù)(其可在調(diào)用之間迀移)。執(zhí)行代碼庫104存儲在程序的該執(zhí)行以及先前執(zhí)行期間從程序代碼100生成的機器代碼。執(zhí)行代碼庫104用作從程序代碼100生成的機器代碼的緩存,使得在程序的調(diào)用之間不需要重復代碼生成。執(zhí)行上下文103用于跟蹤執(zhí)行代碼庫104中與程序的當前調(diào)用相關的機器代碼部分(例如,用于當前調(diào)用的函數(shù)定義的機器代碼等)。執(zhí)行支持模塊105為動態(tài)執(zhí)行模塊101提供運行時支持,例如即時機器代碼生成、執(zhí)行管理等。[0014]圖1所示的實體利用一個或多個計算機或者這樣的計算機內(nèi)的模塊來實現(xiàn)。圖2是示出示例計算機200的高級框圖。計算機200包括耦合到芯片集204的至少一個處理器202。芯片集204包括存儲器控制器中心(hub)220和輸入/輸出(I/O)控制器中心222。存儲器(memory)206和圖形適配器212耦合到存儲器控制器中心220,顯示器218耦合到圖形適配器212。存儲裝置208、鍵盤210、指示裝置214和網(wǎng)絡適配器216耦合到I/O控制器中心222。計算機200的其它實施例具有不同的架構。[0015]存儲裝置208是諸如硬盤驅(qū)動器、壓縮盤只讀存儲器(⑶-ROM)、DVD或固態(tài)存儲裝置的非瞬時性計算機可讀存儲介質(zhì)。存儲器206保存處理器202所使用的指令和數(shù)據(jù)。指示裝置214是鼠標、跟蹤球或其它類型的指示裝置,并且與鍵盤210組合使用以向計算機200輸入數(shù)據(jù)。圖形適配器212在顯示器218上顯示圖像和其它信息。網(wǎng)絡適配器216將計算機200親合到一個或多個計算機網(wǎng)絡。[0016]計算機200適于執(zhí)行計算機程序模塊以提供本文所述的功能。如本文所用,術語"模塊"是指用于提供指定功能的計算機程序邏輯。因此,模塊可實現(xiàn)于硬件、固件和/或軟件中。在一個實施例中,程序模塊被存儲在存儲裝置208上,被加載到存儲器206中,并由處理器202執(zhí)行。[0017]圖1的實體所使用的計算機200的類型可根據(jù)實施例以及實體所需的處理能力而變化。例如,執(zhí)行環(huán)境120可以包括一起工作以提供本文所述的功能的多個刀片服務器。計算機200可缺少上述組件中的一些,例如鍵盤210、圖形適配器212和顯示器218。[0018]圖3是示出根據(jù)一個實施例的動態(tài)執(zhí)行模塊101內(nèi)的組件的詳細視圖的高級框圖。如前所述,動態(tài)執(zhí)行模塊101包括執(zhí)行資源102和執(zhí)行支持模塊105。執(zhí)行資源102進一步包括執(zhí)行上下文103和執(zhí)行代碼庫104。[0019]如前所述,執(zhí)行上下文103存儲捕獲程序執(zhí)行的當前運行時狀態(tài)的數(shù)據(jù)以及可跨越程序調(diào)用一直存在以加速同一程序代碼的未來執(zhí)行的信息。執(zhí)行上下文103包括函數(shù)表301、變量表302、分配表304、源表示庫309和包含表(includetable)310。執(zhí)行上下文103還可包括用于各種用戶定義類型的表,例如類表303。用戶定義類型所需的表將取決于動態(tài)執(zhí)行模塊101所執(zhí)行的特定動態(tài)語言。在PHP的情況下,可使用類表303,但是在沒有類的非面向?qū)ο蟮恼Z言的情況下,類表303可沒有必要,而可利用相似的表來跟蹤其它用戶定義類型。[0020]分配表304是數(shù)據(jù)結構,其包含初始代碼106中定義的非易失性數(shù)據(jù)以及在運行時在程序的調(diào)用期間動態(tài)分配的元素。例如,分配表304存儲程序代碼100中聲明的變量、結構和用戶定義類型(例如類)。動態(tài)執(zhí)行模塊101可通過基于程序代碼100的先前調(diào)用所使用的存儲器在分配表304中預先分配空間并且通過在執(zhí)行上下文103的重置之間保持分配表304中的非易失性數(shù)據(jù),來減少程序代碼100所進行的運行時存儲器分配的量。跨越程序代碼100的單獨的執(zhí)行一直存在的數(shù)據(jù)的示例包括全局常量、全局變量、全局類等。存儲在分配表304中的元素可被變量表302和類表303中的條目引用。[0021]函數(shù)表301是按照名稱和代碼上下文將函數(shù)映射至執(zhí)行代碼庫104中的編譯的機器代碼的數(shù)據(jù)結構。代碼上下文是利用其調(diào)用函數(shù)的上下文,例如參數(shù)、包含、命名空間等。在動態(tài)語言中,函數(shù)調(diào)用的代碼上下文可改變函數(shù)調(diào)用所執(zhí)行的代碼。例如,改變綁定至函數(shù)名稱的代碼的函數(shù)調(diào)用之前的條件包含語句可導致該函數(shù)調(diào)用與它在先前執(zhí)行中所調(diào)用的不同的代碼片段,即使函數(shù)名稱和參數(shù)相同。[0022]當程序代碼100被執(zhí)行并且遇到對先前在相同代碼上下文中(在程序代碼100的先前執(zhí)行中或者在早前時間的相同執(zhí)行期間)定義的函數(shù)的調(diào)用時,該函數(shù)的機器代碼生成將沒有必要,因為可通過函數(shù)表301中的映射來訪問相同代碼上下文中針對相同函數(shù)先前生成的機器代碼。另一方面,如果遇到新函數(shù),或者如果在新的代碼上下文中遇到已知函數(shù),則可針對該函數(shù)生成新機器代碼,并且可將對該機器代碼的引用插入函數(shù)表301中的適當條目中。這樣,過去已產(chǎn)生的機器代碼可被重用,而不會犧牲基于上下文調(diào)用不同代碼的動態(tài)生成的函數(shù)的靈活性。[0023]變量表302將變量名稱映射至分配表304中存儲的變量。類似地,用戶定義類型可具有將那些類型的命名實例映射至分配表304中的分配的表。例如,類表303將類名稱映射至分配表304中存儲的類。可在運行時基于變量或用戶定義類型的改變代碼上下文來修改該映射。這使得動態(tài)執(zhí)行模塊101能夠支持運行時對變量和用戶定義類型的動態(tài)改變,同時在變量和用戶定義類型是非易失性的情況下仍能夠優(yōu)化和重用。[0024]函數(shù)表301、變量表302以及用于用戶定義類型的表(例如類表303)可使得沒有被動態(tài)修改的無條件內(nèi)置數(shù)據(jù)能夠跨越程序代碼100的獨立執(zhí)行而一直存在。無條件內(nèi)置數(shù)據(jù)的該持續(xù)性可通過使內(nèi)置非易失性數(shù)據(jù)所需的初始化最小化來加速程序代碼100的新調(diào)用所需的初始設置。[0025]源表示庫309包括程序代碼100中已由動態(tài)執(zhí)行模塊101處理的指令的表示。源表示庫309可按照能夠更快訪問指令結構以便于動態(tài)執(zhí)行模塊101處理的方式來存儲程序代碼100的指令。例如,在一個實施例中,來自程序代碼100的指令按照控制流圖(CFG)的形式存儲在源表示庫309中。在另一實施例中,程序代碼100的指令按照抽象語法樹(AST)的形式存儲。這樣的結構實施例可加速代碼生成和代碼索引。[0026]例如,假設程序代碼100包括如下PHP指令:[0027]【權利要求】1.一種用于通過動態(tài)執(zhí)行模塊執(zhí)行計算機程序的計算機實現(xiàn)的方法,所述方法包括:接收執(zhí)行程序代碼的第一請求,所述程序代碼包括初始代碼和運行時條件代碼;響應于所述第一請求,從所述初始代碼生成執(zhí)行資源,所述執(zhí)行資源包括執(zhí)行代碼庫和執(zhí)行上下文,所述執(zhí)行代碼庫包括從所述初始代碼生成的機器代碼,W及所述執(zhí)行上下文包括存儲的對針對所述初始代碼中的函數(shù)、變量和用戶定義類型生成的元素的引用;使用所述執(zhí)行上下文來執(zhí)行所述執(zhí)行代碼庫中的機器代碼;響應于執(zhí)行所述執(zhí)行代碼庫中的機器代碼,使用所述運行時條件代碼來更新所述執(zhí)行代碼庫和所述執(zhí)行上下文;接收執(zhí)行所述程序代碼的第二請求;W及使用更新的執(zhí)行上下文來執(zhí)行更新的執(zhí)行代碼庫中的機器代碼。2.根據(jù)權利要求1所述的計算機實現(xiàn)的方法,其中,使用所述執(zhí)行上下文來執(zhí)行所述執(zhí)行代碼庫中的機器代碼還包括使用存儲的引用來訪問針對函數(shù)、變量和用戶定義類型生成的元素。3.根據(jù)權利要求1所述的計算機實現(xiàn)的方法,其中,更新所述執(zhí)行代碼庫還包括將從所述運行時條件代碼生成的機器代碼存儲在所述執(zhí)行代碼庫中。4.根據(jù)權利要求1所述的計算機實現(xiàn)的方法,其中,所述執(zhí)行上下文還包括包含存儲的對元素的引用的函數(shù)表、變量表和類表。5.根據(jù)權利要求4所述的計算機實現(xiàn)的方法,其中,更新所述執(zhí)行上下文還包括在所述函數(shù)表、變量表和類表中存儲對針對所述運行時條件代碼中的函數(shù)、變量和類生成的元素的引用。6.根據(jù)權利要求5所述的計算機實現(xiàn)的方法,其中,所述執(zhí)行上下文還包括源表示庫,W及更新所述執(zhí)行上下文還包括將所述運行時條件代碼的一部分的表示存儲在所述源表不庫中。7.根據(jù)權利要求6所述的計算機實現(xiàn)的方法,其中,所述執(zhí)行上下文還包括包含表,W及更新所述執(zhí)行上下文還包括在所述包含表中生成條目,所述條目包括到所述源表示庫中的引用和到所述執(zhí)行代碼庫中的引用。8.根據(jù)權利要求1所述的計算機實現(xiàn)的方法,其中,所述執(zhí)行上下文還包括分配表,所述分配表包括針對所述程序代碼中的所述變量和用戶定義類型分配的元素。9.根據(jù)權利要求1所述的計算機實現(xiàn)的方法,其中,所述程序代碼、所述初始代碼和所述運行時條件代碼包括PHP計算機指令。10.-種用于通過動態(tài)執(zhí)行模塊執(zhí)行計算機程序的計算機,所述計算機包括:非瞬時性計算機可讀存儲介質(zhì),所述非瞬時性計算機可讀存儲介質(zhì)存儲用于通過動態(tài)執(zhí)行模塊來執(zhí)行計算機程序的可執(zhí)行計算機程序指令,所述指令能夠被執(zhí)行W執(zhí)行下述步驟:接收執(zhí)行程序代碼的第一請求,所述程序代碼包括初始代碼和運行時條件代碼;響應于所述第一請求,從所述初始代碼生成執(zhí)行資源,所述執(zhí)行資源包括執(zhí)行代碼庫和執(zhí)行上下文,所述執(zhí)行代碼庫包括從所述初始代碼生成的機器代碼,W及所述執(zhí)行上下文包括存儲的對針對所述初始代碼中的函數(shù)、變量和用戶定義類型生成的元素的引用;使用所述執(zhí)行上下文來執(zhí)行所述執(zhí)行代碼庫中的機器代碼;響應于執(zhí)行所述執(zhí)行代碼庫中的機器代碼,使用所述運行時條件代碼來更新所述執(zhí)行代碼庫和所述執(zhí)行上下文;接收執(zhí)行所述程序代碼的第二請求;W及使用更新的執(zhí)行上下文來執(zhí)行更新的執(zhí)行代碼庫中的機器代碼;W及處理器,所述處理器用于執(zhí)行所述計算機程序指令。11.根據(jù)權利要求10所述的計算機,其中,使用所述執(zhí)行上下文來執(zhí)行所述執(zhí)行代碼庫中的機器代碼還包括使用存儲的引用來訪問針對函數(shù)、變量和用戶定義類型生成的元素。12.根據(jù)權利要求10所述的計算機,其中,更新所述執(zhí)行代碼庫還包括將從所述運行時條件代碼生成的機器代碼存儲在所述執(zhí)行代碼庫中。13.根據(jù)權利要求10所述的計算機,其中,所述執(zhí)行上下文還包括包含存儲的對元素的引用的函數(shù)表、變量表和類表。14.根據(jù)權利要求13所述的計算機,其中,更新所述執(zhí)行上下文還包括在所述函數(shù)表、變量表和類表中存儲對針對所述運行時條件代碼中的函數(shù)、變量和類生成的元素的引用。15.根據(jù)權利要求14所述的計算機,其中,所述執(zhí)行上下文還包括源表示庫,W及更新所述執(zhí)行上下文還包括將所述運行時條件代碼的一部分的表示存儲在所述源表示庫中。16.根據(jù)權利要求15所述的計算機,其中,所述執(zhí)行上下文還包括包含表,W及更新所述執(zhí)行上下文還包括在所述包含表中生成條目,所述條目包括到所述源表示庫中的引用和到所述執(zhí)行代碼庫中的引用。17.根據(jù)權利要求10所述的計算機,其中,所述執(zhí)行上下文還包括分配表,所述分配表包括針對所述程序代碼中的所述變量和用戶定義類型分配的元素。18.根據(jù)權利要求10所述的計算機,其中,所述程序代碼、所述初始代碼和所述運行時條件代碼包括PHP計算機指令。19.一種存儲用于通過動態(tài)執(zhí)行模塊執(zhí)行計算機程序的可執(zhí)行計算機程序指令的非瞬時性計算機可讀存儲介質(zhì),所述指令能夠被執(zhí)行W執(zhí)行下述步驟:接收執(zhí)行程序代碼的第一請求,所述程序代碼包括初始代碼和運行時條件代碼;響應于所述第一請求,從所述初始代碼生成執(zhí)行資源,所述執(zhí)行資源包括執(zhí)行代碼庫和執(zhí)行上下文,所述執(zhí)行代碼庫包括從所述初始代碼生成的機器代碼,W及所述執(zhí)行上下文包括存儲的對針對所述初始代碼中的函數(shù)、變量和用戶定義類型生成的元素的引用;使用所述執(zhí)行上下文來執(zhí)行所述執(zhí)行代碼庫中的機器代碼;響應于執(zhí)行所述執(zhí)行代碼庫中的機器代碼,使用所述運行時條件代碼來更新所述執(zhí)行代碼庫和所述執(zhí)行上下文;接收執(zhí)行所述程序代碼的第二請求;W及利用更新的執(zhí)行上下文來執(zhí)行更新的執(zhí)行代碼庫中的機器代碼。20.根據(jù)權利要求19所述的計算機可讀介質(zhì),其中,所述程序代碼、所述初始代碼和所述運行時條件代碼包括PHP計算機指令。【文檔編號】G06F15/16GK104471557SQ201380038085【公開日】2015年3月25日申請日期:2013年6月17日優(yōu)先權日:2012年6月18日【發(fā)明者】所羅門·布洛斯,杰里米·休格曼申請人:谷歌公司