專利名稱:用于在受控運行時環(huán)境中恢復同步到面向對象的軟件應用的裝置和方法
技術領域:
本公開總地涉及受控運行時環(huán)境,更具體地說,涉及用于在受控運行時環(huán)境中恢復同步到面向對象的軟件應用的裝置和方法。
背景技術:
對日益增加的軟件應用可移植性的需要(即,在具有不同的硬件、操作系統(tǒng)等的多種平臺上執(zhí)行給定的軟件應用的能力)以及減少獨立軟件開發(fā)商(ISV)搶占市場的時間的需要已經導致日益增多的受控運行時環(huán)境的開發(fā)和使用。
受控運行時環(huán)境一般使用動態(tài)編程語言,例如Java、C#等來實現(xiàn)。通常被稱為運行時環(huán)境的軟件引擎(例如Java虛擬機(JVM)、公共語言運行時(CLR)等)執(zhí)行動態(tài)程序語言指令。運行時環(huán)境插入在將被執(zhí)行的動態(tài)程序語言指令(例如,Java程序或源代碼)和目標執(zhí)行平臺(即,執(zhí)行動態(tài)程序的計算機的硬件和操作系統(tǒng))之間,或者說在兩者之間起到接口的作用,使得動態(tài)程序可以以與平臺無關的方式來執(zhí)行。
動態(tài)程序語言指令(例如Java指令)不是被靜態(tài)編譯并直接鏈接到本機碼或機器碼以供目標平臺(即,目標處理系統(tǒng)或平臺的操作系統(tǒng)和硬件)執(zhí)行的。相反,動態(tài)程序語言指令被靜態(tài)編譯為中間語言,而中間語言可以被即時(JIT)編譯器解釋或者接著編譯為可由目標處理系統(tǒng)或平臺執(zhí)行的本機碼或機器碼。一般地,JIT編譯器是由容留在目標處理平臺(例如計算機系統(tǒng))的操作系統(tǒng)中的運行時環(huán)境來提供的。因此,運行時環(huán)境,具體地說是JIT編譯器將與平臺無關的程序指令(例如,Java字節(jié)碼、C#字節(jié)碼等)翻譯成本機碼(即,可由底層的目標處理系統(tǒng)或平臺執(zhí)行的機器碼)。
為了提高整體產率,很多動態(tài)編程語言以及它們提供支持的受控運行時環(huán)境都提供使并發(fā)編程技術(例如,多線程技術)能夠被利用的基礎結構。具體地說,很多動態(tài)編程語言都提供同步特征或操作,以使得多個并發(fā)的執(zhí)行線程能夠共享或者訪問給定的對象及其變量,而不會引起沖突或爭用。例如,在全局可訪問對象(即,公共對象)的情形中,軟件設計者一般假定在運行時期間會發(fā)生沖突或爭用,并且在對象內包括適當?shù)耐讲僮?,以防止這樣的沖突或爭用。按照這種方式,軟件設計者可以保證全局可訪問對象是“線程安全的”(即,可以沒有沖突或爭用地被用于多線程運行時環(huán)境中)。
不幸的是,與對象同步相關聯(lián)的處理開銷導致執(zhí)行時間的大幅減少。例如,在一些公知的Java應用和基準程序(benchmark)的情形中,同步開銷可能會占用整個執(zhí)行時間的10%到20%。此外,不管在運行時期間是否真的需要這種同步,同步通常都被用作在運行時期間防止發(fā)生爭用(特別是在對象庫的情形中)的防護措施。
已知的逸出分析(escape analysis)技術可被用來提高包括不必要同步在內的代碼的整體執(zhí)行速度。總地來說,已知的逸出分析技術采用一種完整程序分析,以便能夠去除與在程序的運行時執(zhí)行期間將不會為之發(fā)生爭用的全局對象和非全局對象相關聯(lián)的同步操作。已知的逸出分析技術是基于靜態(tài)鏈接代碼模型的,該模型假定在運行時期間將不會加載任何新的對象類。然而,一些流行的編程語言,例如Java和CLI都提供了動態(tài)類加載特征,該特征允許將要在運行時上下文中被調用的函數(shù)或方法的動態(tài)鏈接。在一些情形中,將一個類動態(tài)地加載到正在執(zhí)行先前已優(yōu)化程序(例如,同步已被完全或部分去除的程序)的運行時環(huán)境中,這可能導致程序工作在非安全方式下(例如數(shù)據爭用)或者發(fā)生故障。雖然已知的基于靜態(tài)鏈接代碼模型的逸出分析技術可被用來從靜態(tài)鏈接代碼中去除同步,但是當先前失去同步的(即,經過優(yōu)化的)代碼隨后因被動態(tài)加載的類的影響又需要同步時,這些已知的技術不支持恢復同步到先前失去同步的代碼。此外,其他開放世界的特征,例如反射和本機法可以使逸出分析無效,從而導致不安全的執(zhí)行條件。
圖1是可被用來實現(xiàn)這里描述的同步恢復裝置和方法的示例性體系結構的框圖。
圖2圖示了與在逸出分析之后已為之去除同步的類相關聯(lián)的基于Java的代碼示例。
圖3圖示了用于另一類的基于Java的代碼示例,所述類如果被動態(tài)加載,則使對調用地點A的同步去除無效。
圖4是圖1中所示的即時編譯器可被配置來恢復同步到受動態(tài)加載的類影響的調用地點的示例性方式的流程圖。
圖5是圖1中所示的即時編譯器可被配置來恢復同步到受影響的調用地點的示例性方式的更詳細流程圖。
圖6是描繪一種圖1中所示的即時編譯器可被配置來為與受影響的調用地點相關聯(lián)的每個線程執(zhí)行鎖定/解鎖補償?shù)姆绞降氖纠詡未a。
圖7圖示了不管與調用地點A相關聯(lián)的類的動態(tài)加載,仍保持對其的同步去除有效的基于Java的代碼示例。
圖8和9圖解式描繪了一種示例性的方式,圖1中所示的即時編譯器可被配置來以此方式執(zhí)行解鎖補償操作。
圖10是描繪一種方式的示例性代碼,以此方式,cookie COMP_UNLOCK_TAG可被用來在堆棧展開上下文中恢復返回地址。
圖11是可被用來實現(xiàn)這里描述的裝置和方法的示例性處理器系統(tǒng)。
具體實施例方式
圖1是可被用來實現(xiàn)這里描述的同步恢復裝置和方法的示例性體系結構100的框圖。對于示例性的體系結構100,由一種或多種動態(tài)編程語言和/或指令組成的一個或多個軟件應用102被提供給語言編譯器104。應用102可以使用與平臺無關的語言來編寫,例如Java或C#。然而,也可以使用其他動態(tài)的或與平臺無關的計算機語言或指令。另外,應用102中的一些或全部可被存儲在將要執(zhí)行該應用的系統(tǒng)中。附加地或替換地,應用中的一些或全部可被存儲在與將要執(zhí)行應用102的系統(tǒng)相互獨立(并且可能位于遠端)的系統(tǒng)上。
語言編譯器104靜態(tài)編譯應用102中的一個或多個,以生成編譯后的代碼106。編譯后代碼106是以二進制格式存儲在存儲器(未示出)中的中間語言代碼或指令(例如,當編譯后(complied)的應用是用Java寫的時,是字節(jié)碼)。對于應用102,編譯后的代碼106可被本地存儲在將要在其上執(zhí)行編譯后代碼106的目標系統(tǒng)108上。目標系統(tǒng)108可以是下面參考圖11所詳細描述的計算機系統(tǒng)等。目標系統(tǒng)108可以與一個或多個終端用戶等相關聯(lián)。附加地或替換地,編譯后代碼106可以經由一條或多條通信鏈路被傳遞到目標系統(tǒng)108,所述通信鏈路例如是局域網、因特網、蜂窩系統(tǒng)或其他無線通信系統(tǒng)等。
編譯后代碼106的一個或多個部分(例如一個或多個軟件應用)可以由目標系統(tǒng)108來執(zhí)行。具體地說,操作系統(tǒng)110,例如Windows、Linux等容留可執(zhí)行編譯后代碼106的一個或多個部分的運行時環(huán)境112。例如,如果編譯后的代碼106包括Java字節(jié)碼,那么運行時環(huán)境112就是建立在執(zhí)行Java字節(jié)碼的Java虛擬機(JVM)等之上。運行時環(huán)境112將編譯后代碼106的一個或多個部分(即,中間語言指令或代碼)加載到運行時環(huán)境112可以訪問的存儲器(未示出)中。優(yōu)選地,運行時環(huán)境112將整個應用(或者有可能是多個應用)加載到存儲器中,并驗證編譯后的或中間語言代碼106的類型安全性。
在應用或者多個應用被運行時環(huán)境112加載到存儲器中之后,與正在執(zhí)行的應用所調用的、或者為執(zhí)行該應用所需的方法或對象相關聯(lián)的中間語言指令可以由即時(JIT)編譯器114來處理。JIT編譯器114編譯中間語言指令,以生成由計算機系統(tǒng)108內的一個或多個處理器(例如,圖11中所示的處理器1122)執(zhí)行的本機碼或機器碼。
JIT編譯器114可以將本機碼(即,與計算機系統(tǒng)108兼容的,或者可由計算機系統(tǒng)108執(zhí)行的機器碼)存儲在JIT內存緩存(JIT IMC)116中。按照這種方式,運行時環(huán)境112可以重復使用與先前編譯過的、被調用一次以上的方法相關聯(lián)的本機碼。換言之,被編譯為本機碼并被存儲在JIT IMC 116中的中間語言指令可以被運行時環(huán)境112重復使用并執(zhí)行多次。
雖然JIT IMC 116被描繪為實現(xiàn)在運行時環(huán)境112內,但是JIT IMC 116的其他配置也是可能的。例如,JIT IMC 116可以是操作系統(tǒng)110所容留的其他運行時模塊、會話或環(huán)境(未示出)內的另一個數(shù)據結構的一部分。在其他實施例中,特別是涉及虛擬調用的實施例中,可以實現(xiàn)JIT IMC 116,使得與將被調用的方法相關聯(lián)的本機碼被存儲在公知的數(shù)據結構中,例如虛擬分派(dispatch)表。
總的來說,動態(tài)編程語言例如Java提供兩種類型的使軟件設計者能夠生成線程安全碼或軟件對象(software object)的同步。同步后的軟件對象一次僅可以由一個執(zhí)行線程來訪問,從而防止與該對象所使用的參數(shù)或變量相關的沖突或爭用的發(fā)生。換言之,全局對象以及可由一個以上的執(zhí)行線程訪問的其他對象可以通過引入軟件鎖定和解鎖機制而成為線程安全的,上述機制防止一個以上的線程同時訪問對象。一種這樣類型的同步使得代碼塊(即,一條或多條語句)被同步。另一種這樣類型的同步使得方法(即,對代碼塊的調用)被同步。
動態(tài)編程語言為了同步代碼塊和方法,一般既提供高級或語言級同步語句,又提供低級或受控運行時級原語。例如,在Java的情況下,關鍵字“synchronized(已同步)”在語言級(即,高級)被用來宣告一個塊或方法將受到同步保護。另外,在Java的情況下,對應于語言級關鍵字“synchronized”的低級或受控運行時原語是“monitorenter”和“monitorexit”。然而,為了簡化以下的討論,低級同步原語將被稱為“l(fā)ock(鎖定)”和“unlock(解鎖)”,而高級或語言級同步語句將使用關鍵字“synchronized”來表示。
如上所述,已知的逸出分析技術一般采用完整程序分析,該分析基于的假設是一旦程序執(zhí)行已經啟動(即,在運行時期間),將不會加載附加的對象類。具體地說,用于執(zhí)行逸出分析的算法可以使用上下文敏感型方法,這些方法對編譯后的程序執(zhí)行過程間(inter-procedural)分析,以確定被傳遞給被調用者(例如,被調用的方法、對象等)的參數(shù)是否被指定為靜態(tài)變量。這樣的完整程序分析或過程間分析是基于以下假設在運行時期間將不加載新的對象類,并且這些分析通常被稱為封閉世界分析。這樣的封閉世界分析經??蓪е录みM的同步碼優(yōu)化。換言之,與在這樣的封閉世界分析時不發(fā)生爭用的全局對象和非全局對象相關聯(lián)的所有同步操作都可以被消除,從而大大加快JIT編譯器114可執(zhí)行代碼的速率。
這里描述的同步恢復裝置和方法使得受控運行時環(huán)境(例如JVM環(huán)境)能夠即時編譯以下代碼所述代碼基于新的類將不被動態(tài)加載(即,在運行時期間加載)的假設,已在一開始被優(yōu)化為激進地去除同步操作。因而,初始優(yōu)化(即,去同步)可以基于傳統(tǒng)的或已知的逸出分析,這種分析執(zhí)行封閉世界類型的分析,導致例如與不發(fā)生爭用的全局對象或非全局對象相關聯(lián)的同步操作的去除。然而,與已知的技術相反,這里描述的同步恢復裝置和方法可以用在動態(tài)類加載上下文中。具體地說,這里描述的重新同步裝置和方法使得JIT編譯器(例如,JIT編譯器114)能夠判定新加載的類是否以使在初始的封閉世界類逸出分析期間做出的優(yōu)化判決(例如,同步操作去除)無效的方式改變當前正被執(zhí)行的程序的行為。換言之,當JIT編譯器114在運行時或者它當前正在處理的程序或代碼的執(zhí)行期間遇到新加載的類時,對包括新加載的類在內的完整程序執(zhí)行逸出分析,并且同步操作被恢復到需要來防止在多個執(zhí)行線程之間的沖突或爭用的代碼或程序。下面將更詳細地描述,這里描述的同步恢復裝置和方法可以恢復同步到(修補同步回到)作為初始的封閉世界逸出分析的結果先前已被去同步的調用地點。另外,這里描述的同步恢復裝置和方法還分析運行時上下文,并生成補償代碼,例如鎖定和解鎖操作,以保持正確的同步語義。
動態(tài)加入的類(即,在程序的運行時執(zhí)行期間加入的)可以無效初始的封閉世界類逸出分析的結果,為了更好地理解這種示例性的狀況,在圖2和3中提供了示例性的基于Java的代碼。具體地說,圖2描繪了示例性的基于Java的代碼,在對圖2所示代碼的初始的封閉世界類逸出分析期間,為了所述代碼可以從調用地點A去除同步。更具體地說,因為至少在一開始的時候,“obj”沒有逸出方法“caller”,所以可以從調用地點A去除同步。換言之,對于在當前正在執(zhí)行方法“caller”的執(zhí)行線程之外的執(zhí)行線程而言,“obj”不是可訪問的或者說可用的。結果,在用“foo”的未同步版本完成初始的封閉世界類型的逸出分析之后,“foo”的同步版本可以被取代。
圖3描繪了包括從“Class1”導出的新類“Class2”在內的基于Java的代碼示例。如果在包含圖2所示代碼的程序正被執(zhí)行時,對象“Class2”被動態(tài)加載,那么在Class1中定義的公共靜態(tài)字段“global”也可以是Class2的一個實例。因此,因為在Class2內的虛擬方法“do_nothing”指定“obj”為“global”,所以“obj”對多個執(zhí)行線程變?yōu)榭捎?即,逸出所述線程)結果,在調用地點A處的同步去除不再有效,程序的繼續(xù)操作可能需要與調用地點A相關聯(lián)的代碼的重新同步。
圖4是圖1中所示的即時編譯器114可被配置來恢復同步到或者重新同步受動態(tài)加載的類(例如,結合圖2和3所描述的Class2)影響的調用地點的示例性方式的流程圖。一開始,運行時環(huán)境112判斷一些開放世界特征(例如,新的類被加載(框400))是否存在并將有可能破壞或無效先前做出的去同步決定。如果JIT編譯器114在框400處確定不存在新加載的類,那么JIT編譯器停留在框400處。相反,如果JIT編譯器114確定新的類已被加載(框400),則JIT編譯器114對當前正被執(zhí)行的整個程序,包括新加載的類在內執(zhí)行逸出分析(框402)??梢允褂萌魏涡枰募夹g來實現(xiàn)逸出分析,以識別逸出線程的對象(即,同時可由一個以上的執(zhí)行線程來訪問的對象)。
在逸出分析(框402)之后,JIT編譯器114確定在新的類加載(框400)之前,在初始的完整程序分析期間所做出的假設是否保持有效(框404)。換言之,JIT編譯器114判斷逸出分析(框402)是否已確定新加載的類改變了程序的行為,以致于多個執(zhí)行線程現(xiàn)在可以訪問原先是線程安全的(即,一次只由一個執(zhí)行線程訪問,因此沒有逸出它當前的執(zhí)行線程),但現(xiàn)在不是線程安全的對象。具體地說,新加載的類可以導致早先的逸出分析所做決定的失效以及用于去除與某一調用地點相關聯(lián)的非必要同步語句的優(yōu)化例程。在早先的逸出分析期間所執(zhí)行的去同步通常都是基于以下假設,即一個或多個對象將會保持線程安全。例如,一旦加載了在圖3中所示的代碼內定義的新類(即,Class2),在對圖2中所示的代碼執(zhí)行的初始逸出分析期間所做的假設將會失效。
無論如何,如果JIT編譯器114確定在先前的逸出分析期間所做的假設不再有效(例如,一個或多個對象不再是線程安全的,并且可能需要重新同步),那么JIT編譯器114識別因目前的錯誤假設受到影響或沖擊的調用地點(框406)。在已經識別出受影響的調用地點(框406)之后,JIT編譯器114恢復同步到這些地點中的每一個(框408),下面將結合圖5來更詳細地描述。
圖5是JIT編譯器114可被配置來恢復同步到受影響的調用地點(圖4的框408)的示例性方式的更詳細流程圖。首先,JIT編譯器114暫停所有當前活動的執(zhí)行線程(框500)。按此方式暫停執(zhí)行線程保證了如以下描述所完成的修補(patching)和鎖定/解鎖補償可以以安全的方式來實現(xiàn)(即,不損害當前正在執(zhí)行的進程)。此外,因為實際當中,新類的動態(tài)加載在運行時期間不是很頻繁的活動,所以與所有線程活動的完全暫停相關聯(lián)的開銷(即,時延)對整體產率的影響幾乎可以忽略不計。
在當前正在執(zhí)行的線程已經暫停(框500)之后,JIT編譯器114將受影響的調用地點修補回它們原始的同步版本(框502)。例如,如果目標代碼地址已被改變?yōu)橐靡粋€方法的去同步版本,則該目標代碼地址可以被改變回(即,修改為)原始的目標調用地址。
在修補(框502)之后,JIT編譯器114根據需要為每一個暫停的線程執(zhí)行鎖定/解鎖補償(框504)。如果在修補(框502)前完成的對非同步代碼的調用之后,并且在返回到正在調用的程序之前,一個或多個線程已經被暫停,那么就需要鎖定/解鎖補償。在這些情況下,在修補(框502)后立即取消線程活動暫停,這樣允許JIT編譯器114調用一個方法的同步版本,而同一方法已經啟動(即,在框500處暫停之前已啟動)的非同步版本將繼續(xù)執(zhí)行。結果,與該方法相關聯(lián)的對象可以同時被兩個執(zhí)行線程訪問,這可能導致對于一個或多個資源的不安全條件。
可以參考圖2和3中所示的示例性代碼來理解使用鎖定/解鎖補償?shù)姆绞健Ee例來說,如果JIT編譯器114確定在Class2已被加載后,在調用地點A處的同步去除不再有效(即,在圖4的框402處的逸出分析已識別出一個或多個逸出其執(zhí)行線程的對象),則JIT編譯器114完成調用地點A的重新同步(即,恢復同步到調用地點A)(圖4的框408)。如果在執(zhí)行鎖定/解鎖補償(圖5的框504)時,JIT編譯器114確定第一執(zhí)行線程當前正與對“foo”的非同步版本的活動調用相關聯(lián),則需要鎖定/解鎖補償。具體地說,如果第一線程在“global”變成Class2的一個實例的同時開始執(zhí)行“global.do_nothing(this)”,其利用“do_nothing”方法將“obj”指定為“global”,那么第二線程可以同時執(zhí)行“global.foo()”。結果,JIT編譯器114可以在相同的“obj”上執(zhí)行“foo”的同步和非同步兩個版本,從而違反了同步語義,并建立了不安全的共享資源條件。
圖6是描繪一種圖1中所示的JIT編譯器114可被配置來為與受影響的調用地點相關聯(lián)的每個線程執(zhí)行鎖定/解鎖補償(圖5的框504)的一種方式的示例性偽碼。具體地說,圖6中所描繪的示例性方法從棧頂?shù)綏5妆樵L所有的堆棧幀(即,與當前活動的線程相關聯(lián)的幀)。更具體地說,圖6中所描繪的示例性方法通過對z反復執(zhí)行鎖定操作,其中z是“<x,y>”的被調用者,并且它是堆棧上的最后一幀(即,在堆棧上是活動的),從而對于每個受影響的地點“<x,y>”(即,必須為其恢復同步的每個調用地點)保持正確的同步語義。在z是靜態(tài)方法的情況下,對類對象執(zhí)行鎖定操作。相反,如果z是一個實例方法(instance method)(即,涉及虛調用),則JIT編譯器114使用任何需要的技術來定位將對其執(zhí)行鎖定操作的對象。
函數(shù)“compensate_lock_unlock()”可被用來執(zhí)行鎖定操作,以保持正確的鎖定順序。另外,這個函數(shù)還保證正確的解鎖順序被執(zhí)行。例如,如果正由JIT編譯器114處理的代碼是基于Java的,那么鎖定和解鎖操作必須被正確地配對,以實現(xiàn)同步的方法。具體地說,有兩個地方必須執(zhí)行解鎖對象一旦退出同步方法之后,以及在例外處理中同步方法的破壞性展開期間。
圖6中所描繪的示例性方法使得JIT編譯器114能夠僅僅補償代碼中受新加入的類影響的那些部分,而將代碼中未受新加載的類影響的部分留著不動。換言之,簡單地修補一個方法的非同步版本的尾部代碼可能會超出必要地反優(yōu)化代碼,因為運行時環(huán)境對于未受新加載的類影響的其他調用地點可能需要(或者在不引入爭用的情況下能夠使用)所述方法的去同步版本。具體地說,由JIT編譯器114執(zhí)行的逸出分析可以單獨地識別受新加載的類影響的調用地點(即,可以安全去除同步的原始假設對其不再有效的調用地點)以及調用所述方法的去同步版本對其仍然安全的那些調用地點。
圖7圖示了不管Class2(圖2)的動態(tài)加載,同步去除對其仍保持有效的基于Java的代碼示例。具體地說,當Class2被新加載時,在調用地點B對非同步的“foo”的調用仍保持有效,這是因為逸出分析確定“obj”的類型不是Class2類型的。
圖8和9描繪了一種示例性的方式,在圖6的示例性偽碼中所示的compensate_lock_unlock方法可以以此方式完成??偟膩碚f,compensate_lock_unlock函數(shù)使得JIT編譯器114能夠將位于與當前正被執(zhí)行的非同步方法相關聯(lián)的堆棧幀的底部的返回地址重定向到或“劫持”到執(zhí)行適當?shù)慕怄i操作的樁代碼(stub code)。對于圖8中所示的例子,JIT編譯器114識別需要為其執(zhí)行解鎖操作的非同步方法“foo”的返回地址的位置。如圖9中所示,JIT編譯器114用樁代碼的地址替換非同步方法foo’的堆棧幀中的返回地址。因而,當非同步方法foo’的執(zhí)行結束時,控制權被轉移給適當?shù)臉洞a。接著,樁代碼執(zhí)行需要的解鎖操作,并使JIT編譯器114能夠跳回到原始的返回地址。樁代碼包括硬編碼的句柄地址,該地址代表了需要為其執(zhí)行解鎖操作的對象的實際地址。
圖10是描繪一種方式的示例性偽碼,以此方式,cookie COMP_UNLOCK_TAG可以與圖8和9中所描繪的示例性技術結合起來,用于在堆棧展開上下文中恢復返回地址。在堆棧展開上下文中,運行時環(huán)境(例如,虛擬機)一般依賴于返回地址找到堆棧內的下一幀。例如,公知的開放運行時平臺(ORP)將每個方法的起始和結束地址存儲在查找表中。因而,給定了一個代碼地址,虛擬機就可以經由查找表找到包含該代碼地址的方法。然而,如參考圖8和9所述地重定向或劫持返回地址將使得查找操作不能找到正確的下一幀。
圖10中所示的偽碼包括cookie COMP_UNLOCK_TAG,這意味著與這個標簽相鄰的代碼是補償解鎖樁代碼(stub code)。如圖9所示,實際的返回地址和COMP_UNLOCK_TAG在樁代碼之前被緊緊捆綁在一起。結果,如果JIT編譯器114沒有在查找表中找到關聯(lián)的方法,則JIT編譯器114檢查與之相鄰的字是不是cookie COMP_UNLOCK_TAG。如果找到了cookie,則JIT編譯器114返回實際的返回地址,該地址緊跟在cookie之前。cookieCOMP_UNLOCK_TAG被定義為一個非法代碼序列,使得JIT編譯器114不將cookie與編譯后代碼相互混淆。
在破壞性堆棧展開過程的情形中,JIT編譯器114通過經由上面參考圖10所描述的COMP_UNLOCK_TAG cookie來識別當前活動的堆棧幀,從包含在樁代碼中的句柄地址提取實際對象引用,并對對象執(zhí)行解鎖操作,從而補償缺失的解鎖操作。
雖然前面以示例的方式將鎖定/解鎖補償描述為結合方法或調用來使用,但是本領域的技術人員將很容易意識到,這里所描述的技術和裝置可以被容易地調整為與代碼塊一起使用,以取得類似的或相同的結果。
圖11是可被用來實現(xiàn)這里描述的裝置和方法的示例性處理器系統(tǒng)1120的框圖。例如,這里所描述的方法可以被實現(xiàn)為存儲在存儲器上,并由耦合到存儲器的處理器來執(zhí)行的指令。如圖11所示,處理器系統(tǒng)1120包括耦合到互連總線或網絡1124的處理器1122。處理器1122可以是任何適合的處理器、處理單元或微處理器,例如Intel Itanium系列、IntelX-Scale系列、Intel Pentium系列等當中的處理器。雖然未在圖11中示出,但是系統(tǒng)1120可以是多處理器系統(tǒng),因而可以包括與處理器1122相同或類似的一個或多個附加的處理器,它們被耦合到互連總線或網絡1124。
圖11的處理器1122被耦合到芯片組1128,該芯片組1128包括存儲器控制器1130和輸入/輸出(I/O)控制器1132。眾所公知,芯片組一般提供I/O和存儲器管理功能以及多個通用和/或專用寄存器、計時器等,它們可以由耦合到該芯片組的一個或多個處理器來訪問或使用。存儲器控制器1130完成以下功能使處理器1122(如果有多個處理器的話,就是多個處理器)能夠訪問系統(tǒng)存儲器1134,該存儲器可以包括任何需要類型的易失性存儲器,例如靜態(tài)隨機訪問存儲器(SRAM)、動態(tài)隨機訪問存儲器(DRAM)等。I/O控制器1132完成以下功能使處理器1122能夠經由I/O總線1140與外圍輸入/輸出(I/O)設備1136和1138通信。I/O設備1136和1138可以是任何需要類型的I/O設備,例如鍵盤、視頻顯示器或監(jiān)視器、鼠標等。雖然存儲器控制器1130和I/O控制器1132在圖11中被圖示為芯片組1128內的獨立功能模塊,但是這些模塊完成的功能可以被集成在單個半導體電路內,或者可以使用兩個或更多單獨的集成電路來實現(xiàn)。
雖然這里已描述了某些方法、裝置和制品,但是本專利的覆蓋范圍不限于此。相反,本專利覆蓋正好落入所附權利要求書在字面上或者在等同原則下的范圍內的所有方法、裝置和制品。
權利要求
1.一種恢復同步到程序代碼的方法,包括確定類對象是否已被動態(tài)加載;對所述程序代碼執(zhí)行逸出分析;確定在初始逸出分析期間做出的假設是否有效;以及如果在初始逸出分析期間所做的假設不再有效,那么恢復同步到因所述類對象的加載而受到影響的所述程序代碼中的至少一部分。
2.如權利要求1所述的方法,其中在初始逸出分析期間做出的假設與在某一具體時間上只對一個執(zhí)行線程可訪問的至少一個對象相關聯(lián)。
3.如權利要求1所述的方法,其中所述程序代碼是建立在動態(tài)編程語言之上。
4.如權利要求3所述的方法,其中所述動態(tài)編程語言是Java。
5.如權利要求1所述的方法,其中所述程序代碼的所述至少一部分是調用地點。
6.如權利要求1所述的方法,其中恢復同步到所述程序代碼的至少一部分的步驟包括對與所述程序代碼的所述至少一部分相關聯(lián)的執(zhí)行線程進行鎖定/解鎖補償。
7.如權利要求6所述的方法,還包括在對所述執(zhí)行線程進行鎖定/解鎖補償之前,暫停所述執(zhí)行線程。
8.如權利要求6所述的方法,還包括在對所述執(zhí)行線程進行鎖定/解鎖補償之前,修補與所述執(zhí)行線程相關聯(lián)的調用地點。
9.如權利要求6所述的方法,其中對所述執(zhí)行線程進行鎖定/解鎖補償?shù)牟襟E包括使用標簽和cookie之一將與所述程序代碼相關聯(lián)的地址改變?yōu)闃洞a地址。
10.如權利要求9所述的方法,還包括執(zhí)行與所述樁代碼地址相關聯(lián)的樁代碼,以解鎖所述程序代碼。
11.一種用于恢復同步到程序代碼的系統(tǒng),包括存儲器;以及耦合到所述存儲器的處理器,該處理器能夠確定類對象是否已被動態(tài)加載;對所述程序代碼執(zhí)行逸出分析;確定在初始逸出分析期間做出的假設是否有效;以及如果在初始逸出分析期間所做的假設不再有效,那么恢復同步到因所述類對象的加載而受到影響的所述程序代碼中的至少一部分。
12.如權利要求11所述的系統(tǒng),其中在初始逸出分析期間做出的假設與在某一具體時間上只對一個執(zhí)行線程可訪問的至少一個對象相關聯(lián)。
13.如權利要求11所述的系統(tǒng),其中所述程序代碼是建立在動態(tài)編程語言之上。
14.如權利要求13所述的系統(tǒng),其中所述動態(tài)編程語言是Java。
15.如權利要求11所述的系統(tǒng),其中所述程序代碼的所述至少一部分是調用地點。
16.如權利要求11所述的系統(tǒng),其中所述處理器能夠通過對與所述程序代碼的所述至少一部分相關聯(lián)的執(zhí)行線程進行鎖定/解鎖補償,從而恢復同步到所述程序代碼的所述至少一部分。
17.如權利要求16所述的系統(tǒng),其中所述處理器能夠在對所述執(zhí)行線程進行鎖定/解鎖補償之前,暫停所述執(zhí)行線程。
18.如權利要求16所述的系統(tǒng),其中所述處理器能夠在對所述執(zhí)行線程進行鎖定/解鎖補償之前,修補與所述執(zhí)行線程相關聯(lián)的調用地點。
19.如權利要求16所述的系統(tǒng),其中所述處理器能夠通過使用標簽和cookie之一將與所述程序代碼相關聯(lián)的地址改變?yōu)闃洞a地址,從而對所述執(zhí)行線程進行鎖定/解鎖補償。
20.如權利要求19所述的系統(tǒng),其中所述處理器能夠執(zhí)行與所述樁代碼地址相關聯(lián)的樁代碼,以解鎖所述程序代碼。
21.一種其上存儲有指令的機器可訪問介質,所述指令在被執(zhí)行時導致機器確定類對象是否已被動態(tài)加載;對所述程序代碼執(zhí)行逸出分析;確定在初始逸出分析期間做出的假設是否有效;以及如果在初始逸出分析期間所做的假設不再有效,那么恢復同步到因所述類對象的加載而受到影響的所述程序代碼中的至少一部分。
22.如權利要求21所述的機器可訪問介質,其中在初始逸出分析期間做出的假設與在某一具體時間上只對一個執(zhí)行線程可訪問的至少一個對象相關聯(lián)。
23.如權利要求21所述的機器可訪問介質,其中所述程序代碼是建立在動態(tài)編程語言之上。
24.如權利要求23所述的機器可訪問介質,其中所述動態(tài)編程語言是Java。
25.如權利要求21所述的機器可訪問介質,其中所述程序代碼的所述至少一部分是調用地點。
26.如權利要求21所述的其上存儲有指令的機器可訪問介質,所述指令在被執(zhí)行時導致所述機器通過對與所述程序代碼的所述至少一部分相關聯(lián)的執(zhí)行線程進行鎖定/解鎖補償,從而恢復同步到所述程序代碼的所述至少一部分。
27.如權利要求26所述的其上存儲有指令的機器可訪問介質,所述指令在被執(zhí)行時導致所述機器在對所述執(zhí)行線程進行鎖定/解鎖補償之前,暫停所述執(zhí)行線程。
28.如權利要求26所述的其上存儲有指令的機器可訪問介質,所述指令在被執(zhí)行時導致所述機器在對所述執(zhí)行線程進行鎖定/解鎖補償之前,修補與所述執(zhí)行線程相關聯(lián)的調用地點。
29.如權利要求26所述的其上存儲有指令的機器可訪問介質,所述指令在被執(zhí)行時導致所述機器使用標簽和cookie之一將與所述程序代碼相關聯(lián)的地址改變?yōu)闃洞a地址,從而對所述執(zhí)行線程進行鎖定/解鎖補償。
30.如權利要求29所述的其上存儲有指令的機器可訪問介質,所述指令在被執(zhí)行時導致所述機器執(zhí)行與所述樁代碼地址相關聯(lián)的樁代碼,以解鎖所述程序代碼。
31.一種恢復同步到程序代碼的方法,包括對所述程序代碼反復執(zhí)行逸出分析;識別所述程序代碼中將為其恢復同步的至少一個部分;暫停與所述程序代碼相關聯(lián)的至少一個執(zhí)行線程;將所述程序代碼修補為原始的同步版本;以及對與所述至少一個執(zhí)行線程相關聯(lián)的代碼進行鎖定/解鎖補償。
32.如權利要求31所述的方法,其中將所述程序代碼修補為原始的同步版本的步驟包括修補與所述程序代碼的所述至少一個部分相關聯(lián)的調用地點。
33.如權利要求31所述的方法,其中對與所述至少一個執(zhí)行線程相關聯(lián)的代碼進行鎖定/解鎖補償?shù)牟襟E包括將堆棧幀中的一個地址改變?yōu)橹赶驑洞a。
34.如權利要求31所述的方法,其中反復執(zhí)行逸出分析的步驟包括每次加載一個新的類用于執(zhí)行,就執(zhí)行所述逸出分析。
35.一種具有與之相關聯(lián)的操作系統(tǒng)的計算機系統(tǒng),所述計算機系統(tǒng)包括可操作地耦合到所述操作系統(tǒng)的運行時環(huán)境;可操作地耦合到所述運行時環(huán)境的即時編譯器,其中所述即時編譯器被配置為響應于所述運行時環(huán)境接收到新的類,執(zhí)行程序代碼的逸出分析;識別與將為之恢復同步的程序代碼相關聯(lián)的至少一個調用地點;以及恢復同步到所述至少一個調用地點。
36.如權利要求35所述的計算機系統(tǒng),其中所述運行時環(huán)境是建立在虛擬機上。
37.如權利要求35所述的計算機系統(tǒng),其中所述即時編譯器被配置為通過暫停至少一個執(zhí)行線程,將所述至少一個調用地點修補為原始的同步版本,并且對所述至少一個執(zhí)行線程進行鎖定/解鎖補償,從而恢復同步到所述至少一個調用地點。
全文摘要
公開了用于在受控運行時環(huán)境中恢復同步到面向對象的軟件應用的裝置和方法。所公開的裝置和方法確定一個類對象是否已被動態(tài)加載,對程序代碼執(zhí)行逸出分析,并且確定在初始的逸出分析期間做出的假設是否還有效。另外,如果在初始逸出分析期間所做的假設不再有效,那么所公開的系統(tǒng)和方法恢復同步到因所述類對象的加載而受到影響的至少一部分程序代碼。
文檔編號G06F9/46GK1791860SQ200480013989
公開日2006年6月21日 申請日期2004年3月19日 優(yōu)先權日2003年5月20日
發(fā)明者吳甘沙, 路奎元, 石小華 申請人:英特爾公司