專利名稱:分配堆棧槽的方法與裝置的制作方法
技術領域:
本發(fā)明總體涉及用于改進軟件應用程序的性能的方法與裝置。更具體來說,本發(fā)明涉及以與分配寄存器基本相同的方式分配堆棧槽的方法與裝置。
為了提高與計算機程序的執(zhí)行有關的效率,許多計算機程序被“優(yōu)化”。對計算機程序優(yōu)化的作用一般是去除實質上沒有用的部分計算機程序代碼。此外,對計算機程序優(yōu)化會調整計算操作,以使總體計算的執(zhí)行效率更高,由此降低對計算機資源的消耗。
配置優(yōu)化器是為了有效地將計算機程序(例如用諸如C++、FORTRAN或Java字節(jié)碼的程序設計語言編寫的計算機程序)轉換成為更快的程序。更快的或曰優(yōu)化的程序一般包括與原始的或曰未轉換的計算機程序基本上全部相同的可觀察到的行為。具體來說,優(yōu)化程序包括與其相關原始程序相同的數(shù)學行為。然而,優(yōu)化程序一般用更少的計算來再造同一個數(shù)學行為。
本領域的熟練人員會明白,優(yōu)化器一般包含一個寄存器分配程序,它用來控制在優(yōu)化的或其它方式編譯的內部程序表示內對寄存器的使用。寄存器分配程序分配能在其中存儲與程序有關的數(shù)據(jù)的寄存器空間。寄存器是與計算機的處理器相關聯(lián)的存取速度相對較快的位置—這種快速度是與計算機所關聯(lián)的“常規(guī)”存儲空間例如堆?;蚨芽臻g的存取速度相比而言的。
一個處理器中的寄存器數(shù)是固定的。所以,當沒有足夠的寄存器空間可用于數(shù)據(jù)存儲時,就標識“溢出代碼”(spill code)。溢出代碼是一種在寄存器全滿時在堆棧槽與寄存器之間轉移數(shù)據(jù)的代碼。堆棧槽是分配程序用來在寄存器全滿時保存信息的堆棧幀(stackframe)。優(yōu)化程序通常包含一個專用的堆棧槽分配程序,用來按需要為溢出代碼分配堆棧槽。當傳輸?shù)膮?shù)多于寄存器能容納的數(shù)量時,一般也需要堆棧槽。
圖1a是一個代碼段的示意圖。源代碼段104包括對變量的使用。例如,指令108包括使用一個在寄存器(例如寄存器R1)中存儲的變量A。指令108將變量B設定為等于變量A與整數(shù)“1”的和。可以將變量B存入寄存器R2。變量A除了用于指令108,也用于指令112。如圖所示,變量B用于指令114。
變量B的有效范圍即“B有效范圍”120的定義是段104內變量B必須保持有效的范圍。就是說,B有效范圍120是需要將變量B的值保留在寄存器(例如寄存器R2)中所在的“距離”。“A有效范圍”122即變量B的值必須保留在寄存器中所在的距離與B有效范圍重疊。重疊的有效范圍120、122表示要在一定的距離內同時將變量A和B二者保留在各自的寄存器中。如圖所示,第一個“C有效范圍”124表示,變量C只是在變量D被設定之前一直在寄存器中有效的。因此,在某些情況下可以將變量C和變量D分配給同一個寄存器。
可以對與段104關聯(lián)的干擾圖進行著色,以便向段104分配寄存器,而不產(chǎn)生沖突(例如沒有干擾)。著色以及隨后的寄存器分配,可以用各種不同的過程來執(zhí)行,這些過程包括但不限于Chaitin著色試探法(由設在美國紐約州Yorktown Heights的國際商用機器公司開發(fā))和Briggs-Chaitin著色算法。圖1b是與圖1a的段104相關聯(lián)的干擾圖的示意圖。干擾圖132包括與變量A、B、C、D相關聯(lián)的節(jié)點134。
在需要在相同時間有效的兩個節(jié)點之間添加邊線138。如圖所示,在節(jié)點A134a與節(jié)點D134d之間有邊線138a,由此變量A與變量D是同時有效的。類似地,節(jié)點B134b與節(jié)點C134c之間的邊線也表示變量B與變量C也需要同時有效。
對干擾圖132的處理使得當干擾圖被成功地著色時,可以沒有沖突地將寄存器分配給相關節(jié)點134。因此,用顏色為干擾圖132著色一般涉及向干擾圖132的節(jié)點134分配顏色,例如寄存器號。干擾圖132表示,圖1a所示的源代碼的段104需要3個寄存器。節(jié)點A134a和節(jié)點B134b每個需要各自的寄存器,而節(jié)點C134c和節(jié)點D134d可以共享一個寄存器。
一般來說,干擾圖不會總是以與CPU具有的寄存器數(shù)一樣少地被著色,所以將會發(fā)生某些數(shù)據(jù)被溢出到堆棧槽的溢出。例如,在任何給定時刻,當兩個變量或值試圖占用一個寄存器時就會發(fā)生溢出。當兩個值試圖幾乎同時占用一個寄存器時,由于寄存器分配程序已經(jīng)到了不可能保證每個值有其自己的寄存器的地步,所以必須將其中一個值溢出到堆棧槽中??梢砸绯龅蕉褩2壑械闹档臉酥颈灰暈槭且绯龊蜻x對象(spill candidate)的標志。
寄存器分配程序是這樣嘗試向干擾圖分配顏色的—使由邊線相連的兩個節(jié)點具有相同的顏色。此外,寄存器分配程序試圖使用不超過k種顏色,其中k是中央處理單元(CPU)中寄存器的數(shù)量(在Intel80×86 CPU中,k=8;在多數(shù)RISC CPU中,k=32)。如果不可能,或者如果用來對干擾圖著色的算法找不到k著色(a k coloring),則一定有一些有效范圍溢出。
對于有兩個寄存器的假想機來說,圖1b的干擾圖132是不可著色的。例如假設將變量A和B所關聯(lián)的有效范圍確定為溢出候選對象。如圖1c中所示,寄存器分配程序在定義(definitions)和使用(uses)指令的周圍插入存儲(stores)和加載(loads)指令。與此同時,必須分配堆棧槽,用于存儲溢出代碼。本例中將單獨的堆棧槽用于有效范圍A和有效范圍B,但在同一時間,這兩個有效范圍中只有一個是有效的。圖1d中給出了溢出程序(spilled program)104’的干擾圖。圖1d的干擾圖180可以只用2個顏色(例如機器寄存器)著色。
本領域的熟練人員明白,存儲(store)和加載(load)指令的使用,便于對值進行存儲和檢索。此外,存儲(store)和加載(load)指令的使用是與堆??臻g的分配相關聯(lián)的,更具體來說,是與堆棧槽的分配相關聯(lián)的。圖2示出與響應著色干擾圖分配堆??臻g相關的步驟的過程流程圖。與一段源代碼相關聯(lián)的分配存儲器的過程開始于步驟202,在該步驟中,為該段源代碼構建一個干擾圖,例如圖1b的干擾圖132。
構建了干擾圖后,就在步驟206嘗試對干擾圖著色。如上所述,可以應用各種方法來嘗試對干擾圖的著色。一旦在步驟206中嘗試對干擾圖著色后,就在步驟210判斷對干擾圖著色的嘗試是否成功。換言之,判斷是否成功地為干擾圖相關的每個變量分配了一個寄存器,而又沒有沖突。
如果判定對干擾圖著色的嘗試是不成功的,這意味著沒有足夠的寄存器能用于在沒有干擾的條件下分配給該段源代碼中的每個變量。于是,則過程流從步驟210轉移到步驟211,在該步驟中獲得作為溢出候選對象的有效范圍的清單。就是說,確定可以溢出到堆棧槽的變量。
一旦確定了溢出候選對象,則在步驟218中,在源代碼段中的定義(definitions)和使用(uses)指令的周圍分配加載(load)指令和存儲(store)指令。具體來說,在源代碼段中變量的使用之前插入一個加載變量的加載命令,在源代碼段中定義變量之后插入一個存儲變量的存儲指令。在分配了加載指令和存儲指令(即stores和loads)之后,在步驟222為每個有效范圍分配一個堆棧槽。一般來說,要用一個獨立于寄存器分配程序的堆棧槽分配程序來分配堆棧槽。盡管堆棧槽分配程序是獨立于寄存器分配程序的,應當明白,兩種分配程序都可以包含在優(yōu)化程序或編譯程序中。分配堆棧槽使溢出候選對象能被溢出到堆棧槽。過程流從步驟222返回步驟202,在此構建新的干擾圖。
返回到步驟210,如果判定對干擾圖著色的嘗試是成功的,表明每個變量都被成功地關聯(lián)到一個寄存器或者堆棧槽。因此,過程流轉移到步驟226,在該步驟中,清理含有堆棧槽的堆棧。本領域的熟練人員知道,清理堆棧槽包括的一系列步驟是相當簡單的。這種步驟通常包括轉換堆棧槽向實際偏移地址(offsets)的引用并將偏移地址置于相關的溢出指令中。
如果寄存器分配程序只是為每個溢出候選對象分配一個堆棧槽,就會生成使用輕松的堆棧幀。大型堆棧幀,諸如那些不緊湊的堆棧幀,既耗費內存以及數(shù)據(jù)高速緩存,又沒有明顯的好處。大型幀在不能直接訪問遠離堆棧指針的偏移地址的機器上也會產(chǎn)生問題。例如,Sparc計算機要求第二個指令訪問位于4096個字節(jié)以外的堆棧槽。分配程序通常嘗試重復利用堆棧槽,為的是使堆棧幀最小化。本領域的熟練人員知道,經(jīng)常用來重復利用堆棧槽的嘗試法,其行為一般來說是不可預見的,由此會產(chǎn)生不可靠的(例如充滿錯誤的)代碼。
堆棧槽分配程序的實現(xiàn)經(jīng)常是效率不高的,導致堆棧幀中充斥著一般不為大段程序使用的堆棧槽。這導致堆棧幀不必要地大,要求大量的存儲空間,并由此導致程序執(zhí)行速度的降低。此外,與堆棧槽分配程序的實現(xiàn)相關的嘗試法(例如嘗試重復利用堆棧槽)的操作方式是為特定目的而設置的。
因此,需要一種處理存儲在堆棧中的值的有效方法。特別是,需要一種分配和使用堆??臻g的有效方法和裝置,使得堆??臻g的分配和使用與寄存器的分配和使用相同。
本發(fā)明涉及分配和使用堆??臻g。按照本發(fā)明的一個方面,一種計算機實現(xiàn)的在基于對象的系統(tǒng)中分配堆棧空間的方法包括獲得適合編譯的源代碼并包括與變量相關聯(lián)的定義。一旦獲得了源代碼,就在源代碼中與變量相關聯(lián)的定義之后順序插入第一個復制(copy)指令。然后為第一個復制指令分配第一個堆棧槽,第一個堆棧槽與一個堆棧幀的大小確定的堆棧幀關聯(lián)。在一個實施例中,該方法進一步包括創(chuàng)建一個與源代碼相關聯(lián)的干擾圖,嘗試對干擾圖著色,并判斷對干擾圖著色的嘗試是否成功。如果著色的嘗試不成功,就將第一個復制指令插入源代碼。
通過在變量的定義或使用的周圍插入一個可能與加載(load)、存儲(store)或寄存器-寄存器復制(register-register copy)相關的復制指令,就可以用與分配寄存器所用的相同的機構(mechanism)來分配堆棧槽。用相同的機構來分配寄存器和堆棧槽,能避免與要用一般來說是復雜的、獨立的機構來分配堆棧槽值所相關的復雜性。所以,使用以分配寄存器所用的相同機構來執(zhí)行的堆棧分配的源代碼,一般來說執(zhí)行效率更高并且更可靠。
通過閱讀以下詳細說明并研究各個附圖,本發(fā)明的這些和其它優(yōu)點將顯而易見。
參考下面結合以下各附圖所作的說明能徹底了解本發(fā)明。附圖簡介圖1a是包括變量的有效范圍的源代碼的示意圖。
圖1b是與圖1a的源代碼104相關的干擾圖的示意圖。
圖1c是增加了存儲(store)指令和加載(load)指令的源代碼示意圖。
圖1d是與圖1c的代碼104’相關聯(lián)的干擾圖的示意圖。
圖2是表示根據(jù)對干擾圖的著色分配堆棧空間的相關步驟的過程流圖。
圖3a是按照本發(fā)明實施例的增加了復制(copy)指令的源代碼示意圖。
圖3b是按照本發(fā)明實施例的一個命名空間(namespace)的示意圖。
圖4是表示按照本發(fā)明實施例的、根據(jù)對干擾圖的著色分配堆棧槽的相關步驟的過程流圖。
圖5是一個適合實現(xiàn)本發(fā)明的通用計算機系統(tǒng)的示意圖。
圖6是一個由圖5的計算機系統(tǒng)支持的、適合實現(xiàn)本發(fā)明的虛擬機的示意圖。
優(yōu)化程序或編譯程序經(jīng)常含有一個堆棧槽分配程序,用來分配堆棧槽,以保存由于處理器的相關寄存器數(shù)量有限而不能在寄存器中存儲的變量。堆棧槽分配程序通常是在寄存器分配期間當通過干擾圖著色算法確定并非所有變量都能分配到寄存器而不致沖突時被啟動的。與處理基于堆棧的變量的嘗試法,如同例如試圖釋放與不使用的堆棧槽相關的空間時一樣,經(jīng)常導致在源代碼的執(zhí)行中發(fā)生故障。此外,堆棧槽的使用經(jīng)常效率不高,這是因為堆棧幀中的許多堆棧槽只用于程序的一小部分。
通過以與對待機器寄存器一樣的方式來處置基于堆棧的值或變量,就不需要用專用的堆棧槽分配程序。從寄存器分配過程中去除這種堆棧槽分配程序能提高用來減少寄存器使用的寄存器分配程序的穩(wěn)定性。用寄存器分配程序來分配堆棧槽能減少堆棧槽的使用,并且一般能使堆棧幀更小、更緊湊,能減少高速緩存的覆蓋面,改善運行期環(huán)境。此外,用寄存器分配程序來分配堆棧槽還能以對待寄存器一樣的方式來處置堆棧槽,由此去除了伴隨著通常用來處理堆棧槽中值的存儲的試探法而產(chǎn)生的故障。
為了有效地按寄存器實現(xiàn)堆棧槽,可以使寄存器分配程序不再將存儲和加載指令插入溢出代碼的周圍。相反,寄存器分配程序插入復制指令,復制指令的源和目的地既可以是真正的機器寄存器,也可以是堆棧槽。在分配成功后,隨后進行一次清理,將以堆棧槽和寄存器為源和以堆棧槽和寄存器為目的地的復制指令轉換為存儲或加載指令。
本領域的熟練人員明白,寄存器分配程序可以執(zhí)行復制合并(copycoalescing)以清除。因此,通過創(chuàng)建要在堆棧槽中存儲的變量的副本,最終就可以用寄存器分配程序來通過清除堆棧槽中不用的副本而減少堆棧槽的使用。參看圖3a來說明按照本發(fā)明實施例的包含復制指令的代碼段。代碼段304包括一個命令308或指令,它在變量C的定義中使用變量A和B。在所述實施例中,在變量的定義和變量的使用周圍分配復制指令。于是,既然命令308使用變量A和B,那么就對變量A和B進行復制—這分別由命令310和312表示。在命令308之后插入一個復制命令314,以便創(chuàng)建變量C的副本。
堆棧槽和寄存器通常是命名空間的一部分。一般來說,命名空間的大小隨命名空間所關聯(lián)的堆棧槽的數(shù)量而不同。由于與處理器相關的寄存器的數(shù)量是固定的,因此命名空間通常是固定的,所以應當明白,命名空間的大小實際上取決于命名空間中包含的堆棧槽的數(shù)量,或者說取決于命名空間中包含的由堆棧槽生成的堆棧幀的大小。
圖3b是按照本發(fā)明實施例的一個命名空間的示意圖。命名空間352可以包含任何位數(shù)。一般來說,位的數(shù)量視特定計算系統(tǒng)的要求而變化很大。舉例來說,位數(shù)的范圍可以從50位左右到100位以上。應當明白,理論上講,命名空間相關的位數(shù)可以是無限的。在所述實施例中,命名空間352是一個96位的命名空間。
命名空間352的第一個8位360是與保存整數(shù)的寄存器相關聯(lián)的。就是說,第一個8位360實際上構成了8個整數(shù)寄存器。本領域的熟練人員明白,一般來說,與寄存器相關聯(lián)的位的數(shù)量視與命名空間352相關聯(lián)的計算平臺而變化很大。例如,與Intel 80×86中央處理單元(CPU)所用寄存器相聯(lián)系的是8位,而RISC(精簡指令集計算機)CPU所用寄存器相聯(lián)系的則是32位。位集364(即第9到第25位)是與存儲浮點值的寄存器相關聯(lián)的。
在所述實施例中,從位26的位置開始的各個位指的是與在堆棧上傳送的輸入?yún)?shù)相關聯(lián)的堆棧槽。分配給輸入?yún)?shù)的位數(shù)取決于被編譯的子例程和所用的調用規(guī)約。有些參數(shù)可以傳送到寄存器中。在分配了輸入?yún)?shù)位之后,要分配輸出參數(shù)位。通常要為被傳送到被當前子例程調用的子例程的參數(shù)保留輸出參數(shù)位。在分配了輸出參數(shù)之后,就分配其余的所有位,用于代表溢出。
應當明白,用來將代碼溢出到與命名空間352相關聯(lián)的堆棧槽中的寄存器分配程序通常選擇第一個空閑的堆棧槽,將值溢出到該堆棧槽中。
通過有效地順序將代碼溢出到堆棧槽中,由堆棧槽構成的堆棧幀就會相當緊湊,這是因為在被占用的堆棧槽之間一般不會有空堆棧槽。此外,被占用的堆棧槽之間沒有有空堆棧槽,能使堆棧幀的大小調整得正好滿足需要。具體來說,堆棧幀的大小對應于被使用的最高堆棧槽。例如,當命名空間的第30位是被填充的最后一位時,與命名空間352相關聯(lián)的堆棧幀的大小就是4個字或者16個字節(jié)。
盡管可以由于各不同的原因來分配堆棧槽,在所述實施例中,堆棧槽是在寄存器分配過程期間沒有空閑的寄存器可用時被分配的。寄存器分配過程經(jīng)常與干擾圖著色過程相關聯(lián)。現(xiàn)在參看圖4來說明按照本發(fā)明實施例的、對源代碼執(zhí)行干擾圖著色的相關步驟。過程開始于步驟404,在該步驟中為特定源代碼段創(chuàng)建或“建立”一個干擾圖。該源代碼一般可以是一段可以幾乎以任何適當?shù)某绦蛟O計語言(例如C程序設計語言)編寫的軟件應用程序。正如前文所述,干擾圖的創(chuàng)建,一般涉及表示與源代碼中的變量或值相關聯(lián)的有效范圍以及表示有效范圍之間的干擾。
一旦建立了干擾圖,就在步驟408嘗試對干擾圖著色。對干擾圖著色涉及沒有沖突或干擾地將寄存器分配給不同的變量。應當明白,用來為干擾圖著色以進行寄存器分配的方法是多種多樣的。這種方法包括—但不限于—Briggs-Chaitin寄存器分配法、Chow式分配法和線性掃描分配法。
在步驟412判斷對干擾圖的著色是否成功。換言之,判斷是否可以在沒有沖突的條件下為干擾圖相關的所有變量分配寄存器。如果判定對干擾圖著色的嘗試是不成功的,這意味著沒有足夠的寄存器能用于在沒有干擾的條件下分配給與干擾圖相關的所有變量。于是,則過程流從步驟412轉移到步驟416,在該步驟中獲得與干擾圖相關的、作為溢出候選對象的有效范圍的清單。就是說,確定可以溢出到堆棧槽的值。
確定了溢出候選對象之后,在步驟420中,在溢出候選對象相關的定義和使用指令的周圍有效地分配或插入復制(copy)指令。在所述實施例中,在溢出候選對象相關的定義指令(definitions)之后并在溢出候選對象相關的指令—例如使用(uses)指令—之前分配一個復制指令。在定義和使用指令的周圍0分配的復制指令通常呈現(xiàn)為寄存器到寄存器(即“reg-reg”)復制指令。如本發(fā)明所指出的那樣,復制指令所用的“寄存器”可以是實際機器寄存器,也可以是堆棧槽。本領域的熟練人員明白,復制指令可能涉及在堆棧上放置值,但一般不要求在棧上放置值。
在步驟420中將復制指令分配到溢出候選對象相關的定義和使用指令的周圍之后,過程流返回到步驟402,建立新的干擾圖。所建立的新的干擾圖包括能被著色到堆棧槽寄存器的有效范圍。
返回到步驟412對著色嘗試是否成功的判斷,如果判定嘗試是成功的,則表明不在需要溢出。換言之,如果確定著色是成功的,則不需要另外的堆棧槽來存儲變量。于是,過程流轉移到步驟428,在該步驟中,對與在定義和使用指令周圍分配的復制命令相關聯(lián)的每個副本進行評估,判定它是存儲指令、加載指令還是寄存器到寄存器復制指令。這種判定是為了將復制指令轉換成一個與現(xiàn)有的實際CPU硬件相對應的指令所必需的。
過程從步驟428轉移到步驟432,在此確定包含在步驟424所分配的堆棧槽的堆棧幀的大小。盡管堆棧幀的大小取決于各種不同因素,在所述實施例中,堆棧幀的大小取決于相關命名空間(例如結合圖3b所述的96位命名空間)中最大的堆棧槽。一旦確定了堆棧幀的大小,就在步驟436清理堆棧。清理堆棧一般包括將復制指令恰當?shù)剞D換成加載指令和存儲指令。清理堆棧之后,對源代碼進行分配的過程即告結束。
圖5表示一個適合實現(xiàn)本發(fā)明的典型的通用計算機系統(tǒng)。計算機系統(tǒng)1030包括任意數(shù)量的處理器1032(也稱中央處理單元或CPU),處理器連接到存儲器,包括主存儲器1034(通常是隨機存取存儲器即RAM)和主存儲器1036(通常是只讀存儲器即ROM)。
本領域的熟練人員明白,可以用計算機系統(tǒng)1030-或更具體來說-CPU1032來支持一個虛擬機。下面將結合圖6來敘述一個在計算機系統(tǒng)1030上支持的虛擬機的例子。本領域中眾所周知,ROM的作用是向CPU1032單向傳輸數(shù)據(jù)和指令,而RAM則一般用來雙向傳輸數(shù)據(jù)和指令。CPU1032一般可包含任意數(shù)量的處理器。主存儲器1034和1036二者都可以包含任何合適的計算機可讀的媒體。二級存儲介質1038通常是海量存儲器,也與CPU1032雙向連接,提供額外的數(shù)據(jù)存儲容量。海量存儲器1038是一種計算機可讀的介質,可用來存儲包括計算機代碼、數(shù)據(jù)等等的程序。海量存儲器1038通常是諸如硬盤或磁帶的存儲介質,速度一般比主存儲器1034、1036慢。海量存儲器1038可以采用磁帶機或紙帶機的形式或采用某種其它已知的設備。應當明白,在適當?shù)那闆r下,可以將海量存儲器1038內存儲的信息按部分RAM1036的標準方式采用,充作虛擬存儲器。諸如CD-ROM的特定主存儲器也可以向CPU1032單向傳送數(shù)據(jù)。
CPU1032也連接到一個或多個輸入/輸出設備1040,它們包括—但不限于—視頻監(jiān)視器、跟蹤球、鼠標、鍵盤、麥克風、觸摸感應顯示器、傳感器讀卡機、磁帶或紙帶機、輸入板、輸入筆、語音或手寫識別器或者其它已知的輸入設備諸如計算機。最后,可以選擇利用如1032概括表示的網(wǎng)絡連接,將CPU1032連接到計算機或電信網(wǎng)絡,例如局域網(wǎng)、互連網(wǎng)或內部網(wǎng)。可以設想,利用這種網(wǎng)絡連接,CPU1032就可以在執(zhí)行上述方法步驟的過程中從網(wǎng)絡接收信息或者向網(wǎng)絡輸出信息。這種信息經(jīng)常呈現(xiàn)為一系列要由CPU1032執(zhí)行的指令,可以例如以載波中體現(xiàn)的計算機數(shù)據(jù)信號的形式從網(wǎng)絡接收或向網(wǎng)絡輸出。計算機硬件和軟件領域的熟練人員應當熟悉上述的設備和材料。
如前文上述,虛擬機可以在計算機系統(tǒng)1030上執(zhí)行。圖6是一個由圖5的計算機系統(tǒng)支持的、適合實現(xiàn)本發(fā)明的虛擬機。當執(zhí)行一個計算機程序(例如用設在美國加州Palo Alto的Sun微系統(tǒng)公司開發(fā)JavaTM程序設計語言編寫的計算機程序)時,向編譯時環(huán)境1105內的編譯程序1120提供源代碼1110。一般來說,源代碼110在軟件開發(fā)者創(chuàng)建源代碼1110時被譯成了字節(jié)碼1130。
字節(jié)碼1130一般可以通過網(wǎng)絡(例如圖5的網(wǎng)絡1012)復制、下載或以其它方式散布,或者在諸如圖5的主存儲器1034的存儲器上存儲。在所述實施例中,字節(jié)碼1130是獨立于平臺的。就是說,字節(jié)碼1130幾乎可以在任何運行適當虛擬機1140的計算機系統(tǒng)上執(zhí)行。例如,在JavaTM環(huán)境中,字節(jié)碼可以在運行JavaTM虛擬機的計算機系統(tǒng)上執(zhí)行。
字節(jié)碼1130被提供給一個包含虛擬機1140的運行環(huán)境1135。運行環(huán)境1135一般可以由諸如圖5的CPU1032的處理器來執(zhí)行。虛擬機1140包括編譯程序1140、解釋程序1142和運行系統(tǒng)1146。字節(jié)碼1130一般既可以向編譯程序1140也可以向解釋程序1142提供。
當字節(jié)碼1130被提供給編譯程序1140時,字節(jié)碼1130內含有的過程被編譯成機器指令,如上所述。另一方面,當字節(jié)碼1130被提供給解釋程序1142時,字節(jié)碼1130被每次一個字節(jié)碼地讀入解釋程序。解釋程序1144然后在每個字節(jié)碼被讀入解釋程序1144時執(zhí)行每個字節(jié)碼所定義的操作??傊?,解釋程序1144幾乎同時地處理字節(jié)碼1130和執(zhí)行字節(jié)碼1130的相關操作。
當操作系統(tǒng)1160調用某個過程時,如果確定該過程是要以解釋的過程調用的,運行系統(tǒng)1146可以從解釋程序1144獲得該過程。另一方面,如果確定該過程是要以編譯的過程調用的,運行系統(tǒng)1146就啟動編譯程序1142。編譯程序1142然后由字節(jié)碼1130生成機器指令,并執(zhí)行機器語言指令。一般來說,機器語言指令在虛擬機1140停止時被丟棄。
盡管只說明了本發(fā)明的若干實施例,應當明白,本發(fā)明可以以其它許多具體形式體現(xiàn),而不偏離本發(fā)明的精神或范圍。舉例來說,分配堆棧空間和對干擾圖著色的相關步驟是可以改變次序、刪除或者添加的。總之,本發(fā)明的過程中涉及的步驟都可以改變次序、刪除或者添加,而不偏離本發(fā)明的精神或范圍。
盡管是就為保存溢出數(shù)據(jù)而分配堆棧槽對本發(fā)明作出說明的,應當明白,可以由于各種不同原因而分配堆棧槽。例如在圖形應用中,有些操作,諸如將整數(shù)值轉換成浮點值的操作,實際上會要求進行堆棧槽的分配。另一方面,可以分配堆棧槽來使參數(shù)能在堆棧上傳送。因此,應將本文的舉例視為示例性的而不是限制性的,本發(fā)明并不限于本文所述細節(jié),而可以在后附的權利要求的范圍內修改。
權利要求
1.一種計算機實現(xiàn)的在基于對象的系統(tǒng)中分配堆??臻g的方法,該計算機實現(xiàn)的方法包含a)獲得源代碼,源代碼適合編譯,源代碼包括與變量相關聯(lián)的定義;b)在源代碼中插入第一個復制指令,第一個復制指令是在源代碼中與變量相關聯(lián)的定義之后順序插入的;c)為第一個復制指令分配第一個堆棧槽;d)將第一個堆棧槽與一個堆棧幀關聯(lián),其中,將第一個堆棧槽與該堆棧幀關聯(lián)包括確定該堆棧幀的大小。
2.權利要求1所述的計算機實現(xiàn)的方法,進一步包含e)創(chuàng)建一個與源代碼相關聯(lián)的干擾圖,其中,創(chuàng)建與源代碼相關聯(lián)的干擾圖包括為第一個復制命令分配第一個堆棧槽;f)嘗試對干擾圖著色;g)判斷對干擾圖著色的嘗試是否成功,其中,如果判定對干擾圖著色的嘗試不成功,就將第一個復制指令插入源代碼。
3.權利要求2所述的計算機實現(xiàn)的方法,進一步包含如果判定對干擾圖著色的嘗試不成功,就獲得一個溢出候選對象,該溢出候選對象是與第一個堆棧槽相關聯(lián)的。
4.權利要求2和3其中之一所述的計算機實現(xiàn)的方法,進一步包括重復步驟b)、c)、e)和f),直到確定對干擾圖著色的嘗試成功。
5.上述各權利要求的任意一項所述的計算機實現(xiàn)的方法,其中,源代碼包括至少一個變量的使用,獲得源代碼包括獲得至少一個變量的使用。
6.權利要求5所述的計算機實現(xiàn)的方法,進一步包括將第二個復制命令分配到源代碼,將第二個復制命令安排得順序地位于至少一個變量的使用的之后;為第二個復制命令分配第二個堆棧槽。
7.上述各權利要求的任意一項所述的計算機實現(xiàn)的方法,其中,第一個復制命令與加載指令、存儲指令和寄存器到寄存器復制指令的其中之一相關聯(lián)。
8.上述各權利要求的任意一項所述的計算機實現(xiàn)的方法,進一步判斷第一個復制命令是否是加載指令。
9.權利要求7所述的計算機實現(xiàn)的方法,進一步判斷第一個復制命令是否是加載指令。
10.一種用來在與計算機系統(tǒng)關聯(lián)的基于對象的系統(tǒng)中分配堆棧空間的計算機系統(tǒng),該計算機系統(tǒng)包含一個處理器;一個用于獲得源代碼的接收機構,源代碼適合編譯,源代碼包括與變量相關聯(lián)的定義;一個用于在源代碼中插入第一個復制指令編譯程序機構,第一個復制指令是在源代碼中與變量相關聯(lián)的定義之后順序插入的;一個用于為第一個復制指令分配第一個堆棧槽的寄存器分配機構,進一步使寄存器分配機構能分配機器寄存器;和一個用于將第一個堆棧槽與一個堆棧幀關聯(lián)的堆棧幀創(chuàng)建機構,其中,將第一個堆棧槽與該堆棧幀關聯(lián)包括確定該堆棧幀的大小。
11.按照權利要求10的計算機系統(tǒng),進一步包含一個用于創(chuàng)建與源代碼相關聯(lián)的干擾圖的繪圖器(grapher);一個用于嘗試對干擾圖著色的圖形著色機構;一個用于判斷對干擾圖著色的嘗試是否成功的判斷器(determinator),其中,如果判定對干擾圖著色的嘗試不成功,就將第一個復制指令插入源代碼。
12.按照權利要求10和11其中任何一項的計算機系統(tǒng),其中,源代碼包括至少一個變量的使用,該計算機系統(tǒng)進一步包括一個用于將第二個復制命令分配到源代碼的分配器(assigner),將第二個復制命令安排得順序地位于至少一個變量的使用的之后,其中進一步使寄存器分配機構為第二個復制命令分配第二個堆棧槽。
13.一種用于在基于對象的計算系統(tǒng)中分配堆??臻g的計算機程序產(chǎn)品,該計算機程序產(chǎn)品包含用來獲得源代碼的計算機代碼,源代碼適合編譯,源代碼包括與變量相關聯(lián)的定義;用來在源代碼中與變量相關聯(lián)的定義之后順序插入第一個復制指令的計算機代碼;用來為第一個復制指令分配第一個堆棧槽的計算機代碼;用來將第一個堆棧槽與一個堆棧幀關聯(lián)的計算機代碼,其中,用來將第一個堆棧槽與該堆棧幀關聯(lián)的計算機代碼包括用來確定堆棧幀的大小的計算機代碼。存儲計算機代碼的計算機可讀介質。
14.權利要求13的計算機程序產(chǎn)品,其中,計算機可讀介質的選擇范圍包括載波體現(xiàn)的數(shù)據(jù)信號、軟盤、CD-ROM、磁帶機、光驅、快閃存儲器和硬驅。
15.按照權利要求13和14其中一項的計算機程序產(chǎn)品,進一步包括用來創(chuàng)建一個與源代碼相關聯(lián)的干擾圖的計算機代碼,其中,創(chuàng)建與源代碼相關聯(lián)的干擾圖包括為第一個復制命令分配第一個堆棧槽;用來嘗試對干擾圖著色的計算機代碼;用來判斷對干擾圖著色的嘗試是否成功的計算機代碼,將用來判斷對干擾圖著色的嘗試是否成功的計算機代碼安排得能在判定對干擾圖著色的嘗試不成功時,將第一個復制指令插入源代碼。
全文摘要
本文披露了用于分配和使用堆??臻g的方法及裝置。按照本發(fā)明的一個方面,一種計算機實現(xiàn)的在基于對象的系統(tǒng)中分配堆棧空間的方法包括獲得適合編譯的源代碼并包括與變量相關聯(lián)的定義。在寄存器分配期間,對堆棧槽和機器寄存器的處置幾乎是類似的。這包括的步驟是,創(chuàng)建一干擾圖,復制合并(copy coalescing),嘗試對干擾圖著色,并判斷對干擾圖著色的嘗試是否成功。如果著色的嘗試不成功,在源代碼中插入的就不是的溢出代碼,而是寄存器到寄存器復制命令(例如“reg-reg”復制命令)。“reg-reg”復制命令包括與堆棧槽和機器寄存器二者相關的復制命令。
文檔編號G06F9/45GK1271887SQ0010701
公開日2000年11月1日 申請日期2000年4月24日 優(yōu)先權日1999年4月23日
發(fā)明者小C·N·克利克, C·A·維克, M·H·帕雷茨尼 申請人:太陽微系統(tǒng)有限公司