專利名稱:動態(tài)優(yōu)化字節(jié)編碼程序的方法和裝置的制作方法
技術(shù)領(lǐng)域:
本發(fā)明一般涉及優(yōu)化軟件應(yīng)用程序執(zhí)行的方法和裝置。更具體來說,本發(fā)明涉及在運行期間為了優(yōu)化軟件應(yīng)用程序而動態(tài)地決定部分代碼應(yīng)當(dāng)被解釋還是被編譯的方法和裝置。
用計算機系統(tǒng)共享計算機系統(tǒng)網(wǎng)絡(luò)(例如局域網(wǎng)、內(nèi)連網(wǎng)和因特網(wǎng))資源的情況正在增加。相應(yīng)地,軟件應(yīng)用程序或計算機程序可能要以不同的格式傳遞給不同的計算機系統(tǒng),這是因為,有的計算機系統(tǒng)通常要求軟件應(yīng)用程序要采用專門適合該特定計算機系統(tǒng)的格式。另外,也可以將計算機程序以與機器無關(guān)的格式(即按字節(jié)代碼)傳遞給計算機系統(tǒng),以便使一種格式的計算機程序能被許多不同的計算機系統(tǒng)使用。
如果計算機程序是以與機器無關(guān)的格式傳遞的,則可以直接解釋程序,或者,也可以將程序翻譯成與機器有關(guān)的代碼,即“機器代碼”。直接解釋的程序比翻譯成機器代碼的程序占用較少的計算機系統(tǒng)空間。然而在多數(shù)情況下,直接解釋的程序比翻譯成機器代碼的程序的執(zhí)行速度慢。因此,決定直接解釋計算機程序還是將計算機程序翻譯成機器代碼,經(jīng)常是根據(jù)空間與執(zhí)行速度之間的相對重要性。
如上所述,可以按字節(jié)代碼將計算機程序傳遞給計算機系統(tǒng)。接收字節(jié)代碼的計算機系統(tǒng)一般含有用于在運行時編譯字節(jié)代碼的編譯程序。在運行時編譯字節(jié)代碼的結(jié)果是將字節(jié)代碼翻譯成機器代碼。
圖1A表示一個具有字節(jié)代碼編譯程序的計算機系統(tǒng)的框圖。字節(jié)代碼104可以以計算機程序的形式被傳遞或用其它方式提供給計算機系統(tǒng)105。字節(jié)代碼104一般可以由各種不同的源提供。當(dāng)字節(jié)代碼104被執(zhí)行時,字節(jié)代碼104要在運行時用編譯程序106編譯。編譯程序106生成的編譯代碼108一般是系統(tǒng)105專用的、并能在該系統(tǒng)105中執(zhí)行的與機器有關(guān)的代碼。就是說,編譯程序106在運行時將字節(jié)代碼106翻譯成編譯代碼108。
有些計算機系統(tǒng)能在發(fā)現(xiàn)部分以前編譯的代碼要被反復(fù)執(zhí)行時,使這部分以前編譯的代碼被“重新編譯”成以更高效率執(zhí)行的格式。換言之,可以用成本更高的第二個編譯過程來編譯被反復(fù)調(diào)用的以前編譯的代碼以便能更高效率地執(zhí)行該反復(fù)調(diào)用的代碼。圖1b是表示使用兩個編譯過程的計算機系統(tǒng)的框圖。計算機系統(tǒng)115包括第一個編譯程序116和第二個編譯程序122。字節(jié)代碼114被提供給計算機系統(tǒng)115執(zhí)行。運行時,第一個編譯程序116將字節(jié)代碼114翻譯成與機器有關(guān)的編譯代碼118或日機器代碼。
執(zhí)行與機器有關(guān)的編譯代碼118,追蹤與機器有關(guān)的編譯代碼118所含的不同子程序(method),以確定何時用第二個編譯程序編譯最經(jīng)常被調(diào)用的子程序。當(dāng)確認了高度執(zhí)行的(或者說反復(fù)執(zhí)行的)編譯代碼120時,就重新編譯該高度執(zhí)行的編譯代碼120,以提高計算機程序的總體執(zhí)行速度。因此,第二個編譯程序122要將高度執(zhí)行的編譯代碼120翻譯成重新編譯的高度執(zhí)行代碼124。
第二個編譯程序122經(jīng)常是比第一個編譯程序116慢的編譯程序,盡管用第二個編譯程序122編譯的代碼一般比第一個編譯程序116編譯的代碼執(zhí)行的效率更高。因此,確定何時重新編譯高度執(zhí)行的編譯代碼120涉及在總體運行時間中額外的編譯開銷與重新編譯的高度執(zhí)行代碼124帶來的效率提高之間作出權(quán)衡。
為提高效率而允許將預(yù)先編譯的代碼重新編譯的一個系統(tǒng),要根據(jù)特定部分的編譯代碼(例如子程序)被調(diào)用的次數(shù)來確定是否重新編譯預(yù)先編譯的代碼。如果該子程序被調(diào)用的次數(shù)超過一個固定的界限值,該子程序就被重新編譯。這個固定的界限值本質(zhì)上是一個固定閾值,它反映該子程序被重新編譯以提高執(zhí)行效率之前,該子程序被調(diào)用的次數(shù)。
在運行時如果用編譯程序?qū)⒆止?jié)代碼翻譯成與機器有關(guān)的代碼,總體程序執(zhí)行中經(jīng)常加入了很大的編譯開銷。因此,盡管機器代碼可能比解釋代碼執(zhí)行的速度快,要是總是將程序的所有部分都編譯成機器代碼后再執(zhí)行機器代碼,如果增加的執(zhí)行速度不能彌補與編譯該程序關(guān)聯(lián)的開銷,則這種做法并不可取。換言之,如果花費在編譯該程序上的時間不能在程序的執(zhí)行期間得到彌補,則程序以解釋代碼執(zhí)行起來會更快。
在一個如上所述的現(xiàn)有系統(tǒng)中,盡管重新編譯被編譯過的程序中的例程可能具有使程序執(zhí)行效率更高的作用,用固定界限值來確定例程何時應(yīng)當(dāng)被重新編譯反而會導(dǎo)致低效率的(即非優(yōu)化的)執(zhí)行。例如,如果這樣設(shè)定固定界限值,使程序中的每一個例程實際上都要被重新編譯,則由重新編譯獲得的提高的執(zhí)行速度可能不會彌補與重新編譯關(guān)聯(lián)的編譯開銷。
因此,需要一種能高效地執(zhí)行字節(jié)代碼格式的程序的方法。更具體來說,需要一種能動態(tài)地確定何時應(yīng)解釋部分計算機程序、何時應(yīng)將部分計算機程序翻譯成機器代碼,由此保證高效地執(zhí)行計算機程序的方法。
本文介紹用于在運行期間動態(tài)地確定應(yīng)解釋還是編譯部分字節(jié)代碼,以優(yōu)化軟件應(yīng)用程序的方法和裝置。根據(jù)本發(fā)明的一個方面,當(dāng)一個選定的子程序(method)被調(diào)用時,它起初是被解釋的。一個調(diào)用跟蹤器(invokation tracker)跟蹤該選定子程序的調(diào)用次數(shù)。當(dāng)該選定子程序的調(diào)用次數(shù)超過一個閾值時,該子程序被編譯。通過獨立地跟蹤各種子程序或其它代碼段的使用情況,就能更加智能地決定哪些子程序應(yīng)當(dāng)被編譯,哪些子程序應(yīng)當(dāng)依然被解釋。在有些實施例中,可以對所有子程序采用一個閾值;在其它實施例中,可以采用多個閾值,每個閾值與一個或多個子程序關(guān)聯(lián)。在后一種安排中,不同子程序關(guān)聯(lián)的閾值可以不同。
根據(jù)本發(fā)明的另一個方面,測量編譯某個別子程序相關(guān)的開銷。這個開銷然后要與一個可接受開銷參數(shù)進行比較,如果該開銷不在可接受的范圍內(nèi),就對啟動編譯該特定子程序的閾值進行調(diào)整。本發(fā)明這方面的內(nèi)容可以應(yīng)用于該子程序的初始編譯和/或該子程序的重新編譯。
根據(jù)本發(fā)明的再一個方面,用于執(zhí)行組織成多個子程序的字節(jié)代碼的一個計算機系統(tǒng)中,包括一個適于解釋各種子程序的解釋程序,以及一個對某選定子程序的解釋進行計數(shù)的跟蹤機制。該跟蹤機制用于確定該選定子程序何時適于編譯。計算機系統(tǒng)進一步包括一個適于編譯各種子程序的編譯程序。在一個實施例中,計算機系統(tǒng)包括一個閾值調(diào)整機制,它與跟蹤機制合作,以確定該選定子程序何時適于編譯。在另一個實施例中,計算機系統(tǒng)進一步包括另一個計算該選定子程序被編譯后的調(diào)用次數(shù)的跟蹤機制,用于確定該選定子程序何時適于重新編譯。
本發(fā)明的這些優(yōu)點和其它優(yōu)點,表現(xiàn)在以下的詳細說明和各附圖中。
以下說明結(jié)合附圖來闡述本發(fā)明。附圖簡述圖1a是表示一個具有字節(jié)代碼編譯程序的計算機系統(tǒng)的框圖。
圖1b是表示使用兩個編譯過程的計算機系統(tǒng)的框圖。
圖2a是表示按照本發(fā)明的一個實施例的一個動態(tài)地編譯代碼的計算機系統(tǒng)的框圖。
圖2b是表示按照本發(fā)明的一個實施例,處理字節(jié)代碼的相關(guān)步驟的過程流圖。
圖3是表示按照本發(fā)明的一個實施例,執(zhí)行一個程序相關(guān)的步驟(即圖2b的步驟206)的過程流圖。
圖4是表示按照本發(fā)明的一個實施例,執(zhí)行一個程序的相關(guān)步驟(即圖3的步驟320)的過程流圖。
圖5是表示按照本發(fā)明的一個實施例,執(zhí)行一個重新編譯程序的相關(guān)步驟(即圖4的步驟420)的過程流圖。
圖6是表示按照本發(fā)明的一個實施例,增大一個閾值的相關(guān)步驟(即圖5的步驟516)的過程流圖。
圖7是表示按照本發(fā)明的一個實施例,執(zhí)行一個閾值監(jiān)測程序的相關(guān)步驟(即圖2b的步驟204)的過程流圖。
圖8是表示按照本發(fā)明的一個實施例,減小一個閾值的相關(guān)步驟(即圖7的步驟712)的過程流圖。
圖9是表示按照本發(fā)明的一個實施例,計算一個解釋開銷的相關(guān)步驟的過程流圖。
圖10是表示一個適于實現(xiàn)本發(fā)明的通用計算機系統(tǒng)的示意圖。
圖11是表示一個由圖10的通用計算機系統(tǒng)支持、適于實現(xiàn)本發(fā)明的虛擬機的示意圖。
字節(jié)編碼的計算機程序被提供給計算機系統(tǒng)時,程序可以被直接解釋,或者,程序可以在運行時被翻譯成機器代碼執(zhí)行。被直接解釋的程序占用的計算機內(nèi)存一般比被翻譯成機器代碼的程序少。另一方面,被翻譯成機器代碼的程序執(zhí)行的速度一般比被直接解釋的程序快。然而在有些情況下,如果用編譯程序生成機器代碼,增加到程序總體運行時間的編譯開銷并不總是能在程序執(zhí)行期間得到補償。在這些情況下,直接解釋該程序可能速度更快,效率更高。總之,要確定程序被直接解釋時執(zhí)行的效率更高還是被翻譯成機器代碼時執(zhí)行的效率更高是困難的。因此,程序往往不能以最快的速度或者最可能高效率地執(zhí)行。
允許字節(jié)編碼的計算機程序既能被直接解釋,又能被翻譯成機器代碼,能使計算機程序的執(zhí)行速度比純粹解釋的程序所能達到的執(zhí)行速度有所提高。解釋的代碼與機器代碼(即編譯的代碼)的混合使用,對內(nèi)存的需求比單純執(zhí)行機器代碼時低。因此,解釋的代碼與編譯的代碼的混合使用,提高了程序執(zhí)行的效率。
字節(jié)編碼的程序中每個子程序都可以被監(jiān)測,以確定編譯該子程序是否有益于程序的總體執(zhí)行。在一個實施例中,監(jiān)測子程序時要記錄該子程序作為解釋的子程序被調(diào)用的次數(shù)。當(dāng)對該解釋的子程序的調(diào)用達到某個水平或閾值,表明如果該子程序被編譯,它有可能彌補編譯的代價時,該子程序就被動態(tài)地編譯。為了實質(zhì)上保證將與對程序中子程序編譯關(guān)聯(lián)的編譯開銷維持在一個可以接受的水平,程序的編譯開銷和解釋開銷二者都要監(jiān)測。如果認為編譯開銷太高,那么就可以進行調(diào)整,減少被編譯的子程序的數(shù)量,以降低編譯開銷。所作的調(diào)整包括提高用于確定何時對一個解釋的子程序進行編譯的閾值。通過允許修改自適應(yīng)的閾值,字節(jié)編碼的程序的執(zhí)行就會得到顯著的優(yōu)化。換言之,可以調(diào)整解釋的代碼與動態(tài)編譯的代碼的混合比例,使執(zhí)行時間更短,并在程序占用的內(nèi)存空間與程序的執(zhí)行速度之間取得更好的平衡。
下面結(jié)合圖2a,描述按照本發(fā)明的一個實施例的一個計算機系統(tǒng),該計算機系統(tǒng)用自適應(yīng)閾值來確定字節(jié)代碼應(yīng)當(dāng)在何時被動態(tài)編譯。字節(jié)代碼144在運行時被作為輸入提供給計算機系統(tǒng)146。字節(jié)代碼144可以被組織成與機器無關(guān)的計算機程序,一般被組織成子程序或例程。在一個實施例中,字節(jié)代碼144可以被一個虛擬機內(nèi)的編譯時環(huán)境提供給同一虛擬機內(nèi)的一個運行時環(huán)境-例如計算機系統(tǒng)146。實現(xiàn)本發(fā)明所在的一種適合的虛擬機,本文將在以后結(jié)合圖11加以詳述。
字節(jié)代碼144被提供給計算機系統(tǒng)146時,字節(jié)代碼144可以被解釋程序148處理。另外,字節(jié)代碼144也可以被編譯程序150編譯,生成編譯的代碼。一般來說,字節(jié)代碼144實際上可以直接地既輸入到解釋程序148,又輸入到編譯程序150,但是在所述實施例中,字節(jié)代碼144只被提供給解釋程序148處理。下文將針對圖2b討論與處理字節(jié)代碼關(guān)聯(lián)的步驟。
一個子程序每次被調(diào)用時,與該子程序關(guān)聯(lián)的字節(jié)代碼144就被用解釋程序148解釋。在所述實施例中,保持著對子程序被解釋的次數(shù)的記錄。任何適當(dāng)?shù)拇胧┒伎梢杂脕砀欁映绦虮唤忉尩拇螖?shù)。適當(dāng)?shù)拇胧┲邪?,用一個計數(shù)器來記錄子程序被解釋的次數(shù),但不限于采用計數(shù)器。這種計數(shù)器在某個子程序內(nèi)是這樣實現(xiàn)的該子程序每當(dāng)被解釋一次,計數(shù)器的值遞增1。
當(dāng)子程序被解釋的次數(shù)超過一個閾值(即界限值)時,就可以用編譯程序150編譯該子程序。反復(fù)解釋一個包含在頻繁執(zhí)行的代碼158中的子程序,效率可能很低,這是因為解釋的字節(jié)代碼154一般比編譯代碼執(zhí)行得慢,或者說效率更低。編譯頻繁執(zhí)行的代碼158一般能使頻繁執(zhí)行的代碼158中包含的子程序的執(zhí)行效率更高,因為通過編譯該子程序所節(jié)省的時間可能會彌補與編譯過程關(guān)聯(lián)的編譯開銷。
一般來說,在多數(shù)計算機程序的執(zhí)行過程中,有些子程序反復(fù)執(zhí)行,其它的則不常執(zhí)行。頻繁執(zhí)行的代碼158一般被視為含有構(gòu)成程序執(zhí)行的重要部分的子程序的代碼段。頻繁執(zhí)行的代碼158被編譯程序150編譯時,生成頻繁執(zhí)行的代碼的編譯版本162。因此,當(dāng)頻繁執(zhí)行的編譯代碼162中的子程序被調(diào)用時,編譯子程序(compiledmethods)就被調(diào)用。在一個實施例中,頻繁執(zhí)行的代碼158包含一組子程序,它們實際占50%以上的總體執(zhí)行時間,例如大約90%的總體執(zhí)行時間。
有些計算機系統(tǒng)中包括單級編譯,另一些計算機系統(tǒng)中包括多級編譯。包括有多級編譯的計算機系統(tǒng)可以被安排在確定重新編譯子程序會提高這些子程序相關(guān)的執(zhí)行效率的時候去重新編譯編譯子程序。例如,將可以用編譯程序150完成的一個第一級編譯,與某個“中間”級編譯關(guān)聯(lián)。中間級編譯可以被安排去將字節(jié)代碼編譯成某種編譯形式,這種編譯形式盡管比解釋字節(jié)代碼的效率高,卻可能沒有“最終”級編譯的效率高。中間級編譯本質(zhì)上會犧牲執(zhí)行中間級編譯子程序的某些執(zhí)行效率去換取編譯速度,而最終級編譯的編譯時間雖然更長,執(zhí)行效率卻更高。
在一個實施例中,可以用跟蹤機構(gòu)來識別包含在頻繁執(zhí)行的編譯代碼162中的最經(jīng)常執(zhí)行的子程序。換言之,在頻繁執(zhí)行的編譯代碼162內(nèi),可以識別出高度執(zhí)行的編譯代碼166。當(dāng)高度執(zhí)行的編譯代碼166內(nèi)的子程序執(zhí)行的次數(shù)超過閾值時,就用另一個編譯程序170重新編譯高度執(zhí)行的編譯代碼166,生成高度執(zhí)行的代碼的重新編譯版本174。應(yīng)當(dāng)明白,另一個編譯程序170可能是與編譯程序150不同的編譯程序。另外,編譯程序170與編譯程序150也可能實際上是相同的編譯程序,但用不同的編譯程序參數(shù)執(zhí)行。應(yīng)當(dāng)明白,盡管以上只描述了兩級編譯,但系統(tǒng)146一般可以包含任意級數(shù)編譯。
圖2b是表示根據(jù)本發(fā)明的一個實施例處理字節(jié)代碼-即與機器無關(guān)的計算機程序-的相關(guān)步驟的過程流圖。過程202從啟動閾值監(jiān)測程序(threshhold monitor)的步驟204開始。閾值監(jiān)測程序與計算機程序并發(fā)執(zhí)行,下文將會說明,它記錄一個閾值,該閾值表示某特定子程序在被考慮進行編譯之前要執(zhí)行的次數(shù)。閾值監(jiān)測程序的一個實施例將在下文中結(jié)合圖7說明。
在步驟206,執(zhí)行一個由字節(jié)代碼組成的計算機程序。該步驟將在以后說明圖3時討論。計算機程序執(zhí)行后,處理字節(jié)代碼的子程序就結(jié)束。應(yīng)當(dāng)明白,在所述實施例中,閾值監(jiān)測程序與該程序?qū)嶋H上是基本上同時(即作為并行過程)執(zhí)行的。換言之,步驟204和206實際上是并行執(zhí)行的。
下面參見圖3,說明按照本發(fā)明的一個實施例執(zhí)行一個程序的相關(guān)步驟,即圖2b的步驟206的相關(guān)步驟。在步驟308,對閾值初始化。在一個實施例中,閾值是個上限值,表示在考慮對子程序進行編譯之前該特定子程序要執(zhí)行的次數(shù)。閾值的大小一般變化很大,要取決于特定系統(tǒng)的要求,例如內(nèi)存要求和效能要求。例如可以將閾值初始化在1,000~10,000范圍內(nèi)。
在一個實施例中,一個程序執(zhí)行所關(guān)聯(lián)的所有子程序只用一個閾值,即閾值可是個全局常量或全局變量。不過應(yīng)當(dāng)明白,其它實施例中可以有多個閾值,例如,閾值可以是子程序?qū)S玫某A炕蜃映绦驅(qū)S玫淖兞俊?br>
閾值在步驟308被初始化后,在步驟312,含有無執(zhí)行計數(shù)器的子程序解釋代碼被加載,并將執(zhí)行計數(shù)器加到這些子程序。換言之,子程序被分配,計數(shù)器被加到這些新分配的子程序。一旦加入計數(shù)器后,在步驟316,新分配的子程序中的計數(shù)器被初始化,例如設(shè)置為0。
過程從步驟316繼續(xù)到步驟320,執(zhí)行加載代碼中的子程序,直到代碼執(zhí)行完成或者加載代碼中所有適當(dāng)?shù)淖映绦蚧旧隙家呀?jīng)執(zhí)行。在代碼執(zhí)行期間,控制流可能到達以前未曾加載的子程序,在這種情況下,代碼可以被動態(tài)加載,本領(lǐng)域的熟練人員明白這一點。下文將針對圖4更詳細地說明執(zhí)行子程序M的相關(guān)步驟。在代碼執(zhí)行的過程中,步驟324判斷,是否還有解釋代碼要加載。如果判斷還有解釋代碼要加載,則過程返回到步驟312去加載其它代碼,反之,如果判斷沒有其它解釋代碼要加載,則繼續(xù)步驟320的代碼執(zhí)行。
圖4是表示按照本發(fā)明的一個實施例,執(zhí)行一個程序的相關(guān)步驟(即圖3的步驟320)的過程流圖。子程序M的執(zhí)行從步驟404開始,此時子程序M的計數(shù)器即執(zhí)行計數(shù)器遞增。計數(shù)器遞增后,在步驟408將該子程序M計數(shù)器與閾值比較。如上所述,閾值指示的是在考慮編譯子程序M之前子程序M要執(zhí)行的次數(shù)。
在步驟412,判斷子程序M計數(shù)器是否超過閾值。如果子程序M計數(shù)器不超過閾值,表示沒有必要編譯子程序M。相應(yīng)地,過程流從步驟412轉(zhuǎn)移到步驟416,用解釋程序執(zhí)行子程序M。反之,如果步驟412判斷結(jié)果是子程序M計數(shù)器超過閾值,則表示編譯而不是解釋子程序M會提高執(zhí)行總體程序的效率。于是,如果判定子程序M計數(shù)器超過閾值,則在步驟420執(zhí)行一個重新編譯程序(recompiler)。下文將結(jié)合圖5更詳細地說明執(zhí)行重新編譯程序的相關(guān)步驟。
步驟420執(zhí)行重新編譯程序后,過程流繼續(xù)到步驟424,判斷子程序M是否被編譯。就是說,判斷子程序M是否因為在步驟420執(zhí)行重新編譯程序而被編譯。如果判斷子程序M不被編譯,過程流繼續(xù)到步驟416,用解釋程序執(zhí)行子程序M。如果步驟424判斷子程序M已經(jīng)編譯,則在步驟428執(zhí)行子程序M的編譯代碼。
如上所述,在一個實施例中,用一個重新編譯程序來確定編譯程序?qū)⑷绾翁幚硪粋€給定的子程序,例如子程序M。如果判斷編譯對執(zhí)行總體程序有益,則安排這種重新編譯程序去實際調(diào)用一個編譯程序來編譯子程序M。圖5是表示按照本發(fā)明的一個實施例,執(zhí)行一個重新編譯程序(即圖4的步驟420)的相關(guān)步驟的過程流圖。重新編譯程序的執(zhí)行開始于步驟504,該步驟搜尋子程序M的直接調(diào)用程序(direct caller)。一般來說,搜尋該調(diào)用程序,即調(diào)用子程序M的子程序,必然要檢查調(diào)用堆棧(call stack),本領(lǐng)域的熟練人員都知道這一點。
搜尋子程序M的調(diào)用程序后,在步驟506,判斷子程序M的調(diào)用程序是否存在。如果判斷子程序M的調(diào)用程序存在,過程繼續(xù)到步驟508,該步驟判斷總體程序關(guān)聯(lián)的編譯程序是否要將子程序M直接插入(inline)調(diào)用程序。將子程序M直接插入調(diào)用程序,一般要復(fù)制一份子程序M的解釋代碼,并將復(fù)制的代碼合并到調(diào)用程序中,合并之前要剔除不必要的部分代碼,例如涉及調(diào)用程序向子程序M傳遞的參數(shù)或變量說明的代碼。如果調(diào)用程序反復(fù)執(zhí)行,由此使得子程序M要反復(fù)執(zhí)行,或者如果調(diào)用程序反復(fù)調(diào)用子程序M,則將子程序M直接插入調(diào)用程序并編譯該調(diào)用程序就可能會提高總體程序執(zhí)行的效率。不過,將子程序M直接插入調(diào)用程序并不刪除子程序M的未直接插入版本,這是因為其它子程序也可能會調(diào)用子程序M,所以子程序M必須保持對其它子程序開放。因此,將子程序M直接插入調(diào)用程序并不必然提高總體程序執(zhí)行的效率。這是因為直接插入子程序M,增加了該程序相關(guān)的代碼的物理量。
如果在步驟508確定編譯程序要將子程序M直接插入調(diào)用程序,則在所述實施例中,暗示總體程序執(zhí)行效率提高的好處實際上大于增加額外程序代碼的壞處。結(jié)果,過程流從步驟508轉(zhuǎn)移到步驟510,調(diào)用編譯程序來直接插入子程序M,并編譯已插入子程序M的子程序M的調(diào)用程序。
將子程序M直接插入子程序M的調(diào)用程序的決定涉及各種不同的因素。這些因素例如包括子程序M的大小、調(diào)用程序的大小、與子程序M和調(diào)用程序相關(guān)的參數(shù)的值;以及調(diào)用子程序M的次數(shù),但不局限于這些因素??傊畱?yīng)當(dāng)明白,直接插入子程序M不僅會將子程序M直接插入子程序M的調(diào)用程序,也會將子程序M的調(diào)用程序直接插入調(diào)用程序的調(diào)用程序。換言之,可以在堆棧中搜尋任意多級的調(diào)用程序。
直接插入子程序M并編譯調(diào)用程序后,在步驟512檢查編譯開銷。一般來說,檢查編譯開銷總要監(jiān)測與運行期間編譯子程序相關(guān)的開銷。該編譯開銷然后與最大期望編譯開銷比較。在一個實施例中,最大期望編譯開銷,是運行期間編譯子程序或以其它方式將子程序翻譯成機器代碼的花費占整個系統(tǒng)開銷(例如中央處理單元或花費的時間)的某個最大百分比。因此檢查編譯開銷必然要確定實際用于在運行時編譯子程序的系統(tǒng)開銷量。
在步驟514判斷編譯開銷是否超過最大期望編譯開銷。如果判定編譯開銷超過最大期望編譯開銷,則表示被編譯的子程序數(shù)量太多,于是過程流轉(zhuǎn)移到步驟516,增大閾值。增大閾值一般能有效地降低編譯開銷,這是因為增大閾值增加了在考慮編譯子程序之前子程序要被調(diào)用的次數(shù)。例如,如果閾值的設(shè)定值為1000,在程序執(zhí)行期間幾乎所有子程序都至少被調(diào)用1000次,然后將閾值提高到10,000,結(jié)果會降低編譯開銷,因為被編譯的子程序少了。下文將結(jié)合圖6更詳細地說明增大閾值的相關(guān)步驟。在步驟516增大閾值后,執(zhí)行重新編譯程序的過程結(jié)束。
如果在步驟514判定編譯開銷小于最大期望編譯開銷,則認為該閾值是可以接受的。就是說,編譯子程序和執(zhí)行編譯的子程序相關(guān)的開銷被認為處于一個可以接受的水平。這樣,重新編譯程序的執(zhí)行結(jié)束。
返回步驟508,如果判定與總體程序的執(zhí)行關(guān)聯(lián)的編譯程序不會將子程序M直接插入調(diào)用程序,則在步驟518,調(diào)用編譯程序來編譯子程序M。單獨編譯子程序M而不將子程序M插入調(diào)用程序,一般會減少整個程序相關(guān)的代碼量。如上所述,插入子程序M實際上導(dǎo)致復(fù)制一份子程序M。以后,如果子程序M被不同的子程序調(diào)用,子程序M最終可能會被插入各個不同的子程序中。這樣,子程序M相關(guān)的代碼的復(fù)制品會在整個程序中迅速增加,編譯插入代碼相關(guān)的編譯工作量會非常大。因此,在一個實施例中,為了節(jié)省存儲空間,減少編譯工作量,如果子程序M可能被多個子程序調(diào)用的話,就單獨編譯子程序M,而不是將子程序M直接插入其調(diào)用程序。子程序M在步驟518被編譯后,過程流轉(zhuǎn)移到步驟512,檢查編譯開銷。要確定子程序M是否可能被多個子程序調(diào)用,就要研究調(diào)用鏈(call chains),本領(lǐng)域的熟練人員知道這一點。
回過來看步驟506,該步驟判斷是否存在子程序M的調(diào)用程序,如果不存在子程序M的調(diào)用程序,或者由于其它原因在搜尋調(diào)用程序時沒有發(fā)現(xiàn),則過程流繼續(xù)到步驟518,編譯子程序M。如果沒有發(fā)現(xiàn)調(diào)用程序,則表示子程序M是被運行時系統(tǒng)調(diào)用的,而不是被其它子程序調(diào)用的。
如上所述,如果總體程序執(zhí)行相關(guān)的編譯開銷大于所希望的最大開銷,就要增大閾值。使用這種自適應(yīng)閾值一般允許按特定應(yīng)用程序的需要而修改閾值。對于有許多子程序或函數(shù)都超過一定調(diào)用次數(shù)的應(yīng)用程序來說,如果對應(yīng)的閾值太低,則會導(dǎo)致人們所不希望的、效率(即時間和存儲空間)上的高編譯開銷。于是,設(shè)置較高的閾值,就能使編譯開銷符合要求,即降低編譯開銷。
在程序執(zhí)行期間增大閾值,也能防止以緊密的間隔編譯子程序。例如,如果幾乎同時超過特定閾值的不同子程序的數(shù)量相對較多,則在總體程序的執(zhí)行的期間可能會發(fā)生暫停。由于程序執(zhí)行期間的暫停是不利的,所以在編譯前幾個子程序后增大閾值能防止一系列編譯的間隔太密,籍此基本消除編譯產(chǎn)生的停頓。
下面結(jié)合圖6,描述按照本發(fā)明的一個實施例,增大一個閾值的相關(guān)步驟(即圖5的步驟516)。換言之,現(xiàn)在說明圖5的步驟516。應(yīng)當(dāng)明白,對于閾值是個全局值的實施例來說,增大閾值將增大該全局值。反之,如果閾值是子程序?qū)S玫闹担瑒t增大閾值將只是增大特定子程序或子程序組的閾值。
增大閾值的過程開始于步驟602,該步驟判斷閾值是否處于閾值極限,即上限閾值。閾值極限與正在執(zhí)行的總體程序的要求有關(guān),一般是認為可以接受的閾值的最大值。
如果在步驟602判定閾值處于閾值極限,那么,在所述的實施例中,就不得增大閾值。這樣,增大閾值的過程視為完成。例如,閾值極限大約在1000~5000個數(shù)量級上的調(diào)用,對于現(xiàn)存系統(tǒng)是合適的。反之,如果在步驟602判定閾值不處于閾值極限,那么在步驟604,判斷閾值極限在當(dāng)前時段內(nèi)是否曾經(jīng)向上調(diào)整過。在一個實施例中,判斷閾值極限在當(dāng)前時段內(nèi)是否向上調(diào)整過,涉及判斷相關(guān)的間隔變化標志(interval change flag)是否指示最近已經(jīng)作過調(diào)整。下文將描述用于設(shè)置和清除間隔變化標志的表示機制。
如果在步驟604判定閾值極限在當(dāng)前時段內(nèi)(例如最近的過去)向上調(diào)整過,則不再增大閾值。不再增大最近已經(jīng)調(diào)整過的閾值,是為了防止閾值被過分調(diào)整。如果在步驟604判定不再增大閾值,則增大閾值的過程視為完成。
如果在步驟604判定閾值極限在當(dāng)前時段內(nèi)未曾向上調(diào)整過,則過程流轉(zhuǎn)移到步驟606,閾值被乘以一個閾值系數(shù)。各閾值系數(shù)一般都依賴總體計算機程序的要求而大不相同。例如,大約1.2~2量級的閾值系數(shù)就比較適合當(dāng)前系統(tǒng)。在閾值被乘以一個閾值系數(shù),閾值增大之后,在步驟608設(shè)置間隔變化標志。間隔變化標志用于指示,閾值在當(dāng)前時段內(nèi)已經(jīng)作過調(diào)整。增大閾值的過程在設(shè)置間隔變化標志后完成。
在所述實施例中,正如說明圖2b時所述,程序執(zhí)行的開始與閾值監(jiān)測程序的開始并行發(fā)生。就是說,在程序執(zhí)行期間,監(jiān)測程序也在執(zhí)行。圖7是表示按照本發(fā)明的一個實施例,開始執(zhí)行一個閾值監(jiān)測程序的相關(guān)步驟(即圖2b的步驟204)的過程流圖。閾值監(jiān)測程序的執(zhí)行開始于步驟702,此時閾值監(jiān)測程序接到操作系統(tǒng)的一個定時器信號。定時器信號實際上是一種周期性地中斷程序執(zhí)行的時鐘“滴答”。本領(lǐng)域熟練人員知道,可以將閾值監(jiān)測程序的執(zhí)行掛起,即讓閾值監(jiān)測程序“睡著”,一直到收到定時器信號。
一旦收到定時器信號,就在步驟704更新編譯開銷和解釋開銷的滑動平均數(shù)(sliding averages)。換言之,在一定時段內(nèi)(例如最近的過去)花在編譯上的時間量和花在編譯上的時間量,用該時段的時間間隔個數(shù)平均后,都可以表達為該時段的百分數(shù)。
滑動平均數(shù)被更新后,間隔變化標志在步驟706被復(fù)位。復(fù)位間隔變化標志一般是將間隔變化標志設(shè)置成表示閾值在給定的時段內(nèi)未被調(diào)整過。間隔變化標志被復(fù)位后,在標志708,判斷編譯開銷是否超過最大期望編譯開銷。最好將編譯開銷保持在最小期望編譯開銷至最大期望編譯開銷的范圍內(nèi)。最小期望編譯開銷和最大期望編譯開銷的值的變動范圍很大,但人們發(fā)現(xiàn)在有些系統(tǒng)中它們的合適值是最小期望編譯開銷大約在5%~25%,最大期望編譯開銷大約在20%~65%。在一個特定實施例中,最小期望編譯開銷是給定時段的大約10%,最大期望編譯開銷是給定時段的大約50%。
如果在步驟708判定編譯開銷大于最大期望編譯開銷,則過程流轉(zhuǎn)移到步驟716,增大閾值(例如全局閾值)。前文說明圖6時描述過一種增大閾值的適當(dāng)方法。一旦增大閾值后,過程流轉(zhuǎn)移到步驟702,過程在此等待從操作系統(tǒng)接收新的定時器信號。
如果在步驟708判定編譯開銷小于最大期望編譯開銷,則在步驟710判斷編譯開銷是否小于最小期望編譯開銷。如果編譯開銷小于最小期望編譯開銷,則說明閾值可能定的太高,因此,為了使編譯開銷保持在最小期望編譯開銷至最大期望編譯開銷的范圍內(nèi),要在步驟712減小閾值。減小閾值使閾值更容易達到,結(jié)果增加了對子程序的編譯(關(guān)于減小閾值下文在討論圖8時將有詳細說明)。這樣就能將編譯開銷提高到最小期望編譯開銷以上。減小閾值后,過程流返回到步驟702,在該步驟中,執(zhí)行閾值監(jiān)測程序的過程在接收到定時器信號之前實際上一直被掛起。
如果判定編譯開銷在最小期望編譯開銷至最大期望編譯開銷的范圍內(nèi),則在步驟714判斷解釋開銷是否大于最大期望解釋開銷。關(guān)于計算解釋開銷的一個適當(dāng)方法,下文在討論圖9時將有詳細說明與最大期望編譯開銷的情況一樣,最大期望解釋開銷的值的范圍變動也很大。另外,最小期望解釋開銷的值的范圍變動也可以變動很大。例如,最大期望解釋開銷可以是給定時段的約20%,最小期望解釋開銷可以是給定時段的約5%。在一個實施例中,最大、最小期望解釋開銷可以基本上與最大、最小期望編譯開銷相同。
如果解釋開銷大于最大期望解釋開銷,則在步驟712減小閾值。減小閾值的過程中的一個典型過程在下文討論圖8時敘述。減小閾值一般使更多的子程序被編譯,從而減少了被解釋的子程序的數(shù)目。另一方面,如果判定解釋開銷小于最大期望解釋開銷,則在步驟718判斷解釋開銷是否小于最小期望解釋開銷。如果解釋開銷小于最小期望解釋開銷,則在步驟716增大閾值。如果解釋開銷在最小期望解釋開銷至最大期望解釋開銷限定的可接受的解釋開銷的范圍內(nèi),則在步驟702繼續(xù)閾值監(jiān)測程序的執(zhí)行過程,接收操作系統(tǒng)的新的定時器信號。
下面結(jié)合圖8,描述按照本發(fā)明的一個實施例,減小一個閾值(即圖7的步驟712)的相關(guān)步驟。減少閾值的過程開始于步驟804,該步驟判斷閾值是否處于閾值下限。閾值下限一般被視為對閾值是合理的最小值。例如,盡管閾值下限的范圍變動很大,閾值下限大約在100~1000次的量級是比較合適的。在一個實施例中,閾值下限是大約500次調(diào)用。
如果步驟804判定閾值處于閾值下限,這暗示不能再減小閾值了。則減小閾值的過程視為完成。反之,如果步驟804判定閾值不處于閾值下限,則在步驟808判斷閾值在當(dāng)前時段是否曾經(jīng)被向下調(diào)整過。
如果判定閾值在最近的過去(或者當(dāng)前時段內(nèi))向下調(diào)整過,則在所述實施例中將不再減小閾值。在給定時段不允許向下調(diào)整閾值超過一次,是為了防止閾值被過分調(diào)整。如果判定不再減小閾值,則減小閾值的過程視為完成。
如果閾值在當(dāng)前時段內(nèi)未曾向下調(diào)整過,則過程流從步驟808轉(zhuǎn)移到步驟812,在步驟812中,閾值被除以一個閾值系數(shù)。各閾值系數(shù)一般都依賴總體計算機程序的要求而大不相同。在一個實施例中,閾值被除以的閾值系數(shù)等于討論圖6時所述增大閾值時用作乘數(shù)的閾值系數(shù)。在閾值被除以閾值系數(shù)之后,在步驟816設(shè)置間隔變化標志。在所述實施例中,間隔變化標志的置位用于指示閾值在當(dāng)前時段已經(jīng)向下作過調(diào)整。設(shè)置間隔變化標志后,減小閾值的過程完成。
除了監(jiān)測在執(zhí)行期間程序相關(guān)的編譯開銷之外,程序相關(guān)的解釋也要監(jiān)測。監(jiān)測解釋開銷實際上涉及監(jiān)測花費在解釋子程序上的總體程序開銷量。如前面討論圖7時所述,監(jiān)測解釋開銷的目的,至少部分是為了判斷是否要增大閾值或減小閾值。例如,如果解釋開銷太高,這暗示應(yīng)當(dāng)編譯更多子程序,要減小閾值以允許更多的子程序被編譯。
一般來說,可以用任何適當(dāng)?shù)倪^程來計算解釋開銷。以下結(jié)合圖9,描述按照本發(fā)明的一個實施例用于計算解釋開銷的一種適當(dāng)過程。該過程開始于步驟904,該步驟接收操作系統(tǒng)的一個定時器信號。接收定時器信號后,在步驟908獲得應(yīng)用程序過程的當(dāng)前程序計數(shù)器。在一個實施例中,程序計數(shù)器中是一個參考,它能確定總體程序的執(zhí)行當(dāng)前使用的是解釋代碼還是編譯代碼。
一旦獲得當(dāng)前程序計數(shù)器后,在步驟912判斷程序計數(shù)器是否引用(即指向)解釋程序。就是說,判斷當(dāng)前是否正在執(zhí)行解釋代碼。如果判定程序計數(shù)器不是指向解釋程序,這表示程序計數(shù)器正指向某個編譯程序,于是該計算解釋開銷的過程完成。如果在步驟912判定程序計數(shù)器確實指向解釋程序,則在步驟916,遞增解釋程序開銷計數(shù)器。最后在步驟918,用該解釋程序開銷計數(shù)器來計算解釋程序開銷的滑動平均數(shù),然后該計算解釋開銷的過程完成圖10表示一個適于實現(xiàn)本發(fā)明的通用計算機系統(tǒng)。計算機系統(tǒng)1030包括任意數(shù)量的處理器1032(也稱中央處理單元或CPU),處理器與內(nèi)存設(shè)備相連,內(nèi)存設(shè)備包括基本存儲器1034(一般是只讀存儲器即ROM)和基本存儲器1036(一般是隨機存取存儲器即RAM)。
計算機系統(tǒng)1030,更具體來說,CPU1032,可以被安排去支持一個虛擬機,這一點本領(lǐng)域的熟練人員都知道。下文討論圖11時將描述一例計算機系統(tǒng)1030支持的虛擬機。本領(lǐng)域眾所周知,ROM的作用是向CPU1032單向傳輸數(shù)據(jù)和指令,而RAM一般則用于雙向傳輸數(shù)據(jù)和指令。CPU1032一般可以包括任意數(shù)量的處理器,兩個基本存儲器1034和1036都可以包括任何計算機可讀的合適的介質(zhì)。二級存儲器1038一般是大容量存儲器,它也雙向地連接CPU1032,提供額外的存儲器量。大容量存儲器1038是一種計算機可讀的介質(zhì),可用于存儲包括計算機代碼、數(shù)據(jù)等的程序。一般來說,大容量存儲器1038是一種諸如硬盤或磁帶的存儲介質(zhì),速度一般比基本存儲器1034、1036慢。大容量存儲器1038的形式可以是磁帶機、紙帶機或其它已知設(shè)備。應(yīng)當(dāng)明白,大容量存儲器1038中存儲器的數(shù)據(jù),在適當(dāng)?shù)那闆r下可以采用與RAM 1036相同的方式而充當(dāng)虛擬內(nèi)存。諸如CD-ROM的特殊基本存儲器1034也可以單向地向CPU1032傳遞數(shù)據(jù)。
CPU1032也連接一個或多個輸入/輸出設(shè)備1040。輸入/輸出設(shè)備1040包括但不限于視頻監(jiān)視器、軌跡球、鼠標、鍵盤、麥克風(fēng)、觸摸屏、穿卡機、磁帶機、紙帶機、書寫板、記錄筆、聲音或手書識別器或其它已知的輸入設(shè)備,當(dāng)然也包括其它計算機。最后,CPU1032最好用圖中1012簡單表示的網(wǎng)絡(luò)連接,連接到計算機網(wǎng)絡(luò)或通信網(wǎng)絡(luò),例如局域網(wǎng)、內(nèi)連網(wǎng)或因特網(wǎng)。有了這種網(wǎng)絡(luò)連接,就可以考慮在執(zhí)行以上所述方法步驟的過程中用CPU1032從網(wǎng)絡(luò)接收信息,或者向網(wǎng)絡(luò)輸出信息。這種信息經(jīng)常表現(xiàn)為要由CPU1032執(zhí)行的指令序列,例如以在載波中體現(xiàn)的計算機數(shù)據(jù)信號的形式,既可以從網(wǎng)絡(luò)接收,也可以向網(wǎng)絡(luò)輸出。計算機軟件和硬件的熟練人員都知道上述設(shè)備和材料。
如上所述,計算機系統(tǒng)1030上可以運行一個虛擬機。圖11是表示一個由圖10的通用計算機系統(tǒng)1030支持的虛擬機的示意圖。當(dāng)計算機程序(例如用JavaTM程序設(shè)計語言編寫的計算機程序)執(zhí)行時,源代碼1110被提供給編譯時環(huán)境1105內(nèi)的編譯程序1120,Java是由美國加州Palo Alto的Sun Microsystems公司開發(fā)的一種程序設(shè)計語言。編譯程序1120將源代碼1110翻譯成字節(jié)代碼1130。一般來說,源代碼1110是在軟件開發(fā)人創(chuàng)建源代碼1110的時候被翻譯成字節(jié)代碼1130的。
字節(jié)代碼1130一般可以被復(fù)制、下載、或通過網(wǎng)絡(luò)(例如圖10的網(wǎng)絡(luò)1012)以其它方式分發(fā)、或者在圖10基本存儲器1034之類的存儲器上存儲。在所述實施例中,字節(jié)代碼1130是獨立于平臺的。就是說,字節(jié)代碼1130可以在運行適當(dāng)?shù)奶摂M機1140的幾乎任何計算機系統(tǒng)上執(zhí)行。例如,在JavaTM環(huán)境中,字節(jié)代碼1130可以在運行JavaTM虛擬機的計算機系統(tǒng)上執(zhí)行。
字節(jié)代碼1130被提供給包含虛擬機1140的運行時環(huán)境1135。運行時環(huán)境1135一般可用圖10的CPU1032之類的處理器執(zhí)行。虛擬機1140包括編譯程序1142、解釋程序1144和運行時系統(tǒng)1146。字節(jié)代碼1130一般既可以提供給編譯程序1142,也可以提供給解釋程序1144。
如果將字節(jié)代碼1130提供給編譯程序1142,如上所述,字節(jié)代碼1130中含有的子程序被翻譯成機器指令。另一方面,如果將字節(jié)代碼1140提供給解釋程序1144,則字節(jié)代碼1130被讀入解釋程序1144,一次一個字節(jié)代碼。解釋程序1144然后一邊讀入各字節(jié)代碼一邊執(zhí)行由各字節(jié)代碼定義的操作。一般來說,解釋程序1144幾乎是連續(xù)地處理字節(jié)代碼1130并執(zhí)行字節(jié)代碼1130相關(guān)的操作。
當(dāng)操作系統(tǒng)1160調(diào)用一個子程序時,如果判定調(diào)用的子程序是個被解釋的子程序,運行時系統(tǒng)1146就可以從解釋程序1144獲得該子程序。另一方面,如果判定調(diào)用的子程序是個編譯子程序,運行時系統(tǒng)1146就啟動編譯程序1146。編譯程序1146然后根據(jù)字節(jié)代碼1130輸出機器指令,并執(zhí)行這些機器語言指令。一般來說,當(dāng)虛擬機1140停止時,機器語言指令就被丟棄。
盡管本文只描述了本發(fā)明的幾個實施例,應(yīng)當(dāng)明白,在不偏離本發(fā)明本質(zhì)或范圍的前提下,本發(fā)明可以以許多其它方式實施。舉例來說,執(zhí)行重新編譯程序涉及的諸步驟可以調(diào)換順序,也可以增、減。此外在某些實施例中,將子程序直接插入子程序的調(diào)用程序這一選擇也可以棄之不用。一般來說,在不偏離本發(fā)明本質(zhì)或范圍的前提下,本發(fā)明的諸多方法所涉及的諸步驟均可以調(diào)換順序,也可以增、減。
盡管本文在描述重新編譯程序的執(zhí)行時,說的是判斷編譯程序是否要編譯一個給定子程序以及編譯給定子程序,不過應(yīng)當(dāng)明白,對給定子程序的編譯可能要推遲到判定應(yīng)當(dāng)編譯該給定子程序之后進行。如果有多個子程序幾乎同時在編譯,則對給定子程序的編譯可能要推遲到只有很少子程序在編譯時,例如編譯開銷降到最小期望編譯開銷以下時。推遲對給定子程序的編譯有助于防止編譯開銷超過最大期望編譯開銷。此外,推遲編譯還有助于防止程序執(zhí)行期間發(fā)生較長時間的編譯暫停。在一個實施例中,對程序的子程序的編譯可能會推遲到總體程序執(zhí)行中有暫停的時候。在這種實施例中,在總體程序執(zhí)行期間,可以將子程序插入一個在暫停期間或低工作量期間被訪問的隊列。
此外,本文在描述本發(fā)明時,說的是所有子程序初始時都被解釋,不過應(yīng)當(dāng)明白,當(dāng)字節(jié)代碼形式的計算機程序最初被提供到運行時環(huán)境時,至少有一些與該程序相關(guān)的子程序可以立即編譯。例如,為了在執(zhí)行開始時程序能符合期望的編譯開銷,有些子程序初始時被編譯,有些子程序初始時被解釋,直到對這些解釋子程序的調(diào)用次數(shù)超過某個閾值,這時才編譯這些解釋子程序。
盡管在某個解釋子程序內(nèi)設(shè)置的計數(shù)器(如上文說明圖3時所述)一般可以設(shè)置在子程序內(nèi)的任何位置,不過如果在子程序運行期間訪問該計數(shù)器,代價是昂貴的。因此,如果要在解釋子程序內(nèi)設(shè)置計數(shù)器,可以將計數(shù)器設(shè)置在子程序的開頭,這樣就可以更容易地訪問計數(shù)器。在有些實施例中,由于涉及到與訪問子程序中的計數(shù)器有關(guān)的代價,所有子程序使用一個全局計數(shù)器。當(dāng)全局計數(shù)器達到閾值時可以考慮對正在運行的子程序進行重新編譯,如同當(dāng)前子程序達到其調(diào)用計數(shù)器閾值一樣。
一般來說,計數(shù)器可以在調(diào)用含有計數(shù)器的子程序期間的任何時候遞增。例如,計數(shù)器可以在子程序內(nèi)部循環(huán)中執(zhí)行向后轉(zhuǎn)移時遞增。在循環(huán)的向后轉(zhuǎn)移時或者循環(huán)的幾乎任何位置遞增計數(shù)器,有利于發(fā)現(xiàn)子程序中的長運行循環(huán)。在子程序的一次調(diào)用期間,長運行循環(huán)可能會反復(fù)執(zhí)行。通過在循環(huán)內(nèi)-例如循環(huán)的向后轉(zhuǎn)移的位置-設(shè)置計數(shù)器,每次循環(huán)都作為調(diào)用該子程序而被計數(shù),由此能使占用大量執(zhí)行時間的子程序更可能會被編譯。應(yīng)當(dāng)明白,在有些實施例中,循環(huán)中的計數(shù)器遞增一個比子程序內(nèi)部計數(shù)器更容易訪問的“全局”循環(huán)計數(shù)器,這時因為在子程序運行時訪問子程序計數(shù)器的代價是昂貴的。
在一個使用“循環(huán)計數(shù)器閾值”的實施例中,循環(huán)計數(shù)器閾值不同于上述的調(diào)用閾值。循環(huán)計數(shù)器閾值也可以用不同的閾值系數(shù)進行增減。然而,一般來說,循環(huán)計數(shù)器閾值的調(diào)整與調(diào)用閾值的調(diào)整實際上是合作進行的。
計數(shù)器一般都被描述成是設(shè)置在子程序的內(nèi)部。然而應(yīng)當(dāng)明白,計數(shù)器除了設(shè)置在子程序內(nèi)部,也可以設(shè)置在每次調(diào)用子程序時能訪問的數(shù)據(jù)庫或表中。在對應(yīng)某計數(shù)器的子程序每次被調(diào)用時,該數(shù)據(jù)庫被更新,更確切地說,數(shù)據(jù)庫中的該計數(shù)器被更新一這并不偏離本發(fā)明的本質(zhì)或范圍。
一般來說,根據(jù)本發(fā)明的閾值,其范圍變動很大。例如,盡管閾值為1000時對有些執(zhí)行是足夠的,但是對幾乎所有子程序執(zhí)行次數(shù)都超過1000的執(zhí)行來說,采用更高的閾值才合適。與此類似,最小、最大期望編譯開銷以及最小、最大期望解釋開銷,根據(jù)特定系統(tǒng)的要求,它們值的范圍變動也很大。
閾值大小的選擇依據(jù),有各種不同的因素。這些因素其中包括但不限于程序執(zhí)行的百分率。換言之,閾值的選擇要使得占總體程序執(zhí)行的一定百分率(例如一半以上)的子程序被編譯。例如,可以這樣調(diào)整閾值,使得占總體程序執(zhí)行的95%的子程序被編譯。
此外,盡管本文在描述優(yōu)化字節(jié)編碼程序時,說的是采用一個編譯級或兩個編譯級,不過,執(zhí)行字節(jié)編碼程序相關(guān)的編譯級的個數(shù)的范圍變動一般可以很大-這并不偏離本發(fā)明的本質(zhì)或范圍。一般來說,許多不同因素決定著執(zhí)行字節(jié)編碼程序相關(guān)的編譯級的個數(shù),這些因素包括但不限于對優(yōu)化程序的期望程度。每個編譯級都有獨立的閾值,盡管幾乎所有編譯級的閾值可以是一樣的。對于有多個編譯級的系統(tǒng)來說,每次調(diào)用子程序時遞增的計數(shù)器可以被設(shè)置在各編譯子程序中。這些計數(shù)器與以上所述設(shè)置在解釋子程序中的計數(shù)器一樣,可用來判斷何時適于對編譯子程序進行重新編譯。
此外,盡管本文在對判斷是否要編譯子程序的說明中,所述的判斷要根據(jù)子程序相關(guān)的計數(shù)器的閾值而定,不過,判斷是否要編譯子程序也可以根據(jù)任意數(shù)量的不同因素而定。例如,整個操作系統(tǒng)中的時間“滴答”就可以用來發(fā)現(xiàn)那些執(zhí)行費時、編譯有益的子程序。就是說,在很多時間“滴答”中執(zhí)行的子程序,應(yīng)當(dāng)考慮對其編譯,以減少該執(zhí)行該過程花費的時間。
執(zhí)行計數(shù)器或調(diào)用計數(shù)器一般是每當(dāng)子程序被訪問時就遞增一次的計數(shù)器。應(yīng)當(dāng)明白,在有些實施例中,調(diào)用計數(shù)器會隨時間推移而衰減。例如,如果某子程序在程序執(zhí)行的開始部分被反復(fù)調(diào)用,但是在相當(dāng)長的時間內(nèi)沒有再被調(diào)用,那么調(diào)用計數(shù)器就會衰減,以降低如果該子程序以后被調(diào)用則要編譯該子程序的可能性。一旦某子程序的調(diào)用計數(shù)器已經(jīng)衰減,例如指數(shù)級地衰減,就不再有理由編譯該子程序。因此,本文的例子應(yīng)視為是解釋性的而不是限制性的,本發(fā)明也不局限于本文的所述的細節(jié),可以在權(quán)利要求的范圍內(nèi)作出改進。
權(quán)利要求
1.一個在運行期間處理計算機程序的計算機實現(xiàn)的過程,其中程序包含字節(jié)代碼,該計算機實現(xiàn)的過程包括調(diào)用一個從多個子程序中選定的子程序,其中,調(diào)用該選定子程序包括解釋該選定子程序;更新一個被安排去跟蹤該選定子程序的調(diào)用的調(diào)用跟蹤器;判定調(diào)用跟蹤器何時指示選定子程序的調(diào)用次數(shù)超過某個閾值;當(dāng)判定調(diào)用跟蹤器指示選定子程序的調(diào)用次數(shù)超過該閾值時,編譯該選定子程序。
2.權(quán)利要求1所述的計算機實現(xiàn)的過程,進一步包括檢測編譯該選定子程序相關(guān)的編譯開銷。
3.權(quán)利要求2所述的計算機實現(xiàn)的過程,進一步包括判定編譯開銷何時處于某個可接受的范圍內(nèi);當(dāng)判定編譯開銷不在可接受的范圍內(nèi)時,就調(diào)整該閾值。
4.權(quán)利要求2和3中之一所述的計算機實現(xiàn)的過程,其中,檢測編譯開銷包括計算編譯開銷的一個滑動平均數(shù)。
5.權(quán)利要求2~4所述的計算機實現(xiàn)的過程,進一步包括檢測解釋選定子程序相關(guān)的解釋開銷。
6.權(quán)利要求5所述的計算機實現(xiàn)的過程,進一步包括判定解釋開銷何時處于某個可接受的范圍內(nèi);當(dāng)判定解釋開銷不在該可接受的范圍內(nèi)時,就調(diào)整該閾值。
7.上述中各權(quán)利要求中任一個權(quán)利要求所述的計算機實現(xiàn)的過程,其中,調(diào)整該閾值包括增大該閾值和減小該閾值。
8.上述中各權(quán)利要求中任一個權(quán)利要求所述的計算機實現(xiàn)的過程,其中,更新調(diào)用跟蹤器包括遞增在選定子程序中設(shè)置的一個計數(shù)器。
9.上述中各權(quán)利要求中任一個權(quán)利要求所述的計算機實現(xiàn)的過程,進一步包括調(diào)用該編譯的選定子程序;更新一個用來記錄該編譯的選定子程序的調(diào)用次數(shù)的跟蹤機構(gòu);判斷跟蹤機構(gòu)何時指示該編譯的選定子程序的調(diào)用次數(shù)超過了某界限值;如果判定該跟蹤機構(gòu)指示該編譯的選定子程序的調(diào)用次數(shù)超過了該界限值,重新編譯該編譯的選定子程序。
10.一種用于執(zhí)行計算機程序的計算機實現(xiàn)的過程,其中計算機程序包括多個子程序,這多個子程序包括優(yōu)化狀態(tài)不同的選定子程序,該計算機實現(xiàn)的過程包括在計算機程序的執(zhí)行期間從多個子程序中選擇一個子程序,其中該子程序處于第一種優(yōu)化狀態(tài);在計算機程序的執(zhí)行期間將該子程序從第一種優(yōu)化狀態(tài)轉(zhuǎn)換到第二種優(yōu)化狀態(tài),其中該第二種優(yōu)化狀態(tài)比第一種優(yōu)化狀態(tài)更優(yōu)化,將該第一子程序從第一種優(yōu)化狀態(tài)到第二種優(yōu)化狀態(tài)的轉(zhuǎn)換包括平衡轉(zhuǎn)換該子程序的代價與轉(zhuǎn)換該子程序的好處。
11.權(quán)利要求11所述的計算機實現(xiàn)的過程,進一步包括執(zhí)行該子程序,其中執(zhí)行第一種優(yōu)化狀態(tài)下的該子程序比執(zhí)行第二種優(yōu)化狀態(tài)下的該第一子程序慢。
12.權(quán)利要求10和11中之一所述的計算機實現(xiàn)的過程,其中第一種優(yōu)化狀態(tài),是從由一個解釋狀態(tài)和一個編譯狀態(tài)組成的狀態(tài)組中選擇的一種狀態(tài)。
13.權(quán)利要求10~12中任意一項權(quán)利要求所述的計算機實現(xiàn)的過程,其中,從多個子程序中選擇該子程序包括在該計算機程序的執(zhí)行期間檢測該第一子程序的調(diào)用次數(shù)。
14.一種計算機實現(xiàn)的執(zhí)行計算機程序的方法,其中計算機程序包含多個子程序,該計算機實現(xiàn)的方法包括調(diào)用從多個子程序中選定的某第一子程序;判斷該第一所選子程序何時要被某編譯程序處理,其中,判斷該第一所選子程序何時要被該編譯程序處理根據(jù)的是與該第一所選子程序的調(diào)用相關(guān)的一個閾值;如果判定該第一子程序要被該編譯程序處理,則用該編譯程序處理該第一子程序;如果判定該第一子程序要被該編譯程序處理,調(diào)整與該計算機程序關(guān)聯(lián)的某種開銷的一個量度;判斷該種開銷的量度是否表示該種開銷是可以接受的;如果判定該種開銷是不可接受的,調(diào)整該閾值。
15.一個執(zhí)行字節(jié)代碼的計算機系統(tǒng),其中字節(jié)代碼被組織成多個子程序,該計算機系統(tǒng)包括一個解釋程序,它被安排去解釋從該多個子程序中選定的第一子程序;一個第一種跟蹤機構(gòu),它被安排去為該第一選定子程序的解釋計數(shù),該第一跟蹤機構(gòu)進一步被安排去判斷該第一選定子程序何時適合編譯;一個編譯程序,它被安排在判定該第一種選定子程序適合編譯時,編譯該第一選定子程序。
16.權(quán)利要求15所述的計算機系統(tǒng),進一步包括一個閾值機構(gòu),它被安排與第一種跟蹤機構(gòu)合作判斷該第一選定子程序何時適合編譯,其中該閾值機構(gòu)被安排去設(shè)置一個指示該第一選定子程序何時適合編譯的閾值。
17.權(quán)利要求15和16中之一所述的計算機系統(tǒng),進一步包括一個第二種跟蹤機構(gòu),它被安排去在該第一選定子程序被編譯時為該第一選定子程序的調(diào)用計數(shù),該第二種跟蹤機構(gòu)進一步被安排去判斷該第一選定子程序何時適合重新編譯;一個重新編譯程序,它被安排在判定該第一選定子程序適合重新編譯時,重新編譯該第一選定子程序。
18.一種用于處理計算機程序的計算機程序產(chǎn)品,其中計算機程序包括字節(jié)代碼,字節(jié)代碼被組織成多個子程序,該計算機程序產(chǎn)品包括調(diào)用從多個子程序中選擇的第一子程序的計算機代碼,其中調(diào)用該第一選定子程序包括解釋該第一選定子程序;更新某個被安排去跟蹤該第一選定子程序的調(diào)用的調(diào)用跟蹤器的計算機代碼;判斷調(diào)用跟蹤器何時指示該第一選定子程序的調(diào)用超過某個閾值的計算機代碼;當(dāng)判定該調(diào)用跟蹤器指示該第一選定子程序的調(diào)用超過某個閾值時編譯該第一選定子程序的計算機代碼。
19.根據(jù)權(quán)利要求18的計算機程序產(chǎn)品,其中,計算機程序產(chǎn)品是在載波中實現(xiàn)的數(shù)據(jù)信號。
全文摘要
本文介紹用于在運行期間動態(tài)地確定應(yīng)當(dāng)解釋還是編譯部分代碼,以優(yōu)化軟件應(yīng)用程序的方法和裝置。本發(fā)明的一個內(nèi)容是,對包含組織成多個子程序的字節(jié)代碼的計算機程序進行運行時處理的計算機實現(xiàn)的方法中,包括一個對該多個子程序中第一個選定子程序的調(diào)用。調(diào)用該第一個選定子程序,包括解釋該第一個選定子程序。被安排去跟蹤該第一個選定子程序的調(diào)用次數(shù)的一個調(diào)用跟蹤器被更新,對調(diào)用跟蹤器何時指示第一個選定子程序的調(diào)用次數(shù)超過某個閾值進行判定。當(dāng)判定調(diào)用跟蹤器指示第一個選定子程序的調(diào)用次數(shù)超過某個閾值時,該子程序被編譯。定期調(diào)整閾值,以保持編譯和解釋開銷在可接受的范圍內(nèi)。
文檔編號G06F9/45GK1234551SQ9811829
公開日1999年11月10日 申請日期1998年10月6日 優(yōu)先權(quán)日1997年10月6日
發(fā)明者U·赫爾茨勒, R·格雷瑟梅爾, D·格里斯沃爾德 申請人:太陽微系統(tǒng)有限公司