• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

      基于結(jié)構(gòu)描述的HotSpot C2即時(shí)編譯器

      2022-11-22 07:28:21鄭艷
      中國(guó)新通信 2022年16期

      摘要:OpenJDK的開源吸引了很多想弄明白Java虛擬機(jī)如何運(yùn)行的開發(fā)人員。本文基于HotSpot虛擬機(jī)源碼,分析了Java虛擬機(jī)的運(yùn)行機(jī)制,并進(jìn)一步深入研究了服務(wù)器端C2即時(shí)編譯框架,指出了HotSpot虛擬機(jī)高效運(yùn)行的原因,為下一步深入優(yōu)化打好基礎(chǔ)。

      關(guān)鍵詞: Java虛擬機(jī);HotSpot虛擬機(jī);服務(wù)器端編譯器;結(jié)構(gòu)描述文件

      一、引言

      Java虛擬機(jī)技術(shù)提供Java標(biāo)準(zhǔn)平臺(tái)的基礎(chǔ)設(shè)施,提供對(duì)快速開發(fā)、部署關(guān)鍵業(yè)務(wù)的桌面和企業(yè)應(yīng)用程序的解決方案。Java無(wú)處不在,而Java虛擬機(jī)正是支撐Java運(yùn)行的秘密武器,它是一個(gè)在硬件平臺(tái)、操作系統(tǒng)之上的一個(gè)龐大復(fù)雜的軟件,涉及的理論和技術(shù)非常廣而寬。

      HotSpot虛擬機(jī)是Sun/Oracle JDK和OpenJDK的默認(rèn)Java虛擬機(jī)[1],是基于Java虛擬機(jī)規(guī)范[2]的一個(gè)高效虛擬機(jī)實(shí)現(xiàn),也是全世界使用最廣泛、最具影響力的Java虛擬機(jī)。很多程序員默認(rèn)HotSpot虛擬機(jī)等同于Java虛擬機(jī)。

      二、HotSpot虛擬機(jī)

      (二)執(zhí)行架構(gòu)

      HotSpot虛擬機(jī)的執(zhí)行架構(gòu)示意圖如圖1所示[4-5]。

      HotSpot虛擬機(jī)采用解釋器與編譯器并存的架構(gòu),解釋器和編譯器是相輔相成地配合工作的。解釋器和編譯器兩者各有優(yōu)勢(shì):當(dāng)程序需要迅速啟動(dòng)和執(zhí)行的時(shí)候,解釋器可以省去編譯的時(shí)間,立即執(zhí)行;當(dāng)程序運(yùn)行后,隨著時(shí)間的推移,編譯器逐漸發(fā)揮作用,把越來(lái)越多的代碼編譯成本地代碼之后,可以獲取更高的執(zhí)行效率。在某些特定情況下編譯模式也能夠通過(guò)“逆優(yōu)化”(deoptimization)退回到解釋模式下繼續(xù)執(zhí)行。

      (二)解釋編譯交互

      同時(shí)存在解釋執(zhí)行和編譯執(zhí)行,涉及解釋執(zhí)行和編譯執(zhí)行互相轉(zhuǎn)化,圖2說(shuō)明了解釋執(zhí)行和編譯執(zhí)行互相轉(zhuǎn)換的途徑[6]。

      Java虛擬機(jī)中如果某個(gè)方法被編譯,則下次執(zhí)行同樣的方法時(shí)切換為編譯執(zhí)行。編譯執(zhí)行的入口有2種情況:方法編譯和核心循環(huán)編譯。方法編譯在下次執(zhí)行前要切換方法調(diào)用的入口,改寫成i2c adapter的首地址,這個(gè)adapter完成從解釋執(zhí)行轉(zhuǎn)為編譯執(zhí)行的功能;同時(shí)要完成把解釋執(zhí)行的參數(shù)拷貝到編譯執(zhí)行的參數(shù)區(qū),解釋執(zhí)行時(shí),參數(shù)區(qū)直接位于棧中,對(duì)于編譯執(zhí)行,參數(shù)一部分位于寄存器中,一部分位于棧中,所以,移植過(guò)程中需要考慮傳遞參數(shù)的這種情況。核心循環(huán)編譯是由循環(huán)體出發(fā)的,但編譯器依然會(huì)以整個(gè)方法作為編譯對(duì)象,執(zhí)行的是棧上替換OSR算法,即在運(yùn)行過(guò)程中直接用編譯執(zhí)行的方法替換解釋執(zhí)行的方法,而不是下次調(diào)用該方法時(shí)再做替換,OSR關(guān)鍵的是要復(fù)制解釋執(zhí)行時(shí)產(chǎn)生的局部變量,同步鎖等。

      編譯執(zhí)行到解釋執(zhí)行的也有2個(gè)入口,最普通的入口是編譯執(zhí)行的方法調(diào)用解釋執(zhí)行的方法;另一個(gè)入口叫逆(deoptimization)操作。在編譯執(zhí)行的方法中進(jìn)行方法調(diào)用時(shí)會(huì)查詢方法的入口地址,如果是靜態(tài)方法,直接解析方法入口地址,否則就將解析方法入口地址,這個(gè)函數(shù)會(huì)判斷被調(diào)用的方法是否已經(jīng)被編譯過(guò)了,如果沒有被編譯過(guò)就進(jìn)入編譯轉(zhuǎn)解釋執(zhí)行的入口。逆優(yōu)化則可能是在編譯執(zhí)行方法時(shí)可能由于某種原因需要重新解釋執(zhí)行。

      三、C2即時(shí)編譯

      服務(wù)器版編譯器是一個(gè)專門面向服務(wù)器典型應(yīng)用的充分優(yōu)化過(guò)的先進(jìn)自適應(yīng)編譯器,它支持和傳統(tǒng)編譯器如C++編譯器類似的許多編譯優(yōu)化流程,以及一些傳統(tǒng)編譯器所不能做的自適應(yīng)優(yōu)化。

      (一)編譯框架

      C2即時(shí)編譯器通過(guò)目標(biāo)處理器平臺(tái)的結(jié)構(gòu)描述文件和指令匹配規(guī)則,提升優(yōu)化效率,其結(jié)構(gòu)圖如圖3所示:

      編譯器首先分析字節(jié)碼并生成中間表示Ideal圖,所有優(yōu)化和代碼產(chǎn)生都是基于它;接著進(jìn)行平臺(tái)無(wú)關(guān)優(yōu)化并生成平臺(tái)相關(guān)的MachNode圖;最后進(jìn)行平臺(tái)相關(guān)優(yōu)化,包括指令選擇、代碼重排、寄存器分配、窺孔優(yōu)化,直至輸出目標(biāo)機(jī)器代碼。

      在指令匹配選擇階段,基于確定有限狀態(tài)機(jī)生成器(DFA)匹配最優(yōu)的指令和操作數(shù),通過(guò)指令的屬性,如指令的訪存代價(jià)、流水線結(jié)構(gòu)等眾多屬性分析每種指令的優(yōu)劣并作出最優(yōu)匹配選擇,這些重要的屬性都是通過(guò)國(guó)產(chǎn)處理器的結(jié)構(gòu)描述文件(Architecture Description File,AD文件)通過(guò)結(jié)構(gòu)描述語(yǔ)言編譯器(ADL)編譯生成獲得;接著進(jìn)行機(jī)器平臺(tái)相關(guān)的優(yōu)化,如寄存器分配、窺孔優(yōu)化等,直至最后生成熱方法的本地機(jī)器代碼,服務(wù)器版編譯器寄存器分配是一個(gè)全局圖著色分配器,它可以充分利用處理器的大寄存器集合。

      (二)結(jié)構(gòu)描述文件

      結(jié)構(gòu)描述文件(Architecture Description File,AD文件)的準(zhǔn)確描述,對(duì)服務(wù)器版即時(shí)編譯器的移植工作非常關(guān)鍵,這是性能版虛擬機(jī)高性能的基礎(chǔ)。它描述目標(biāo)處理器的結(jié)構(gòu),并通過(guò)專門的ADL編譯器將結(jié)構(gòu)描述文件創(chuàng)建為JIT包含的結(jié)構(gòu)相關(guān)優(yōu)化源碼,以便JIT生成高效正確的本地代碼。

      AD文件描述了三類基本的不同結(jié)構(gòu)特征:目標(biāo)平臺(tái)的指令集(包括操作數(shù))、寄存器(以及寄存器分配相關(guān)信息)以及針對(duì)調(diào)度優(yōu)化的目標(biāo)平臺(tái)流水線結(jié)構(gòu)信息,另外還有部分為了簡(jiǎn)化描述而增加的一些輔助定義。

      1. 寄存器描述

      寄存器格式的定義如下:

      “reg_def” name ( register save type, C convention save type,

      ideal register type, encoding, vm name );

      函數(shù)的各個(gè)參數(shù)意思明確,“save type”表示寄存器分配寄存器在方法調(diào)用之間的保留類型,有不保存、調(diào)用處保存、調(diào)用前保存及調(diào)用前和調(diào)用處都保存等四種類型;第三個(gè)參數(shù)“ideal register type”用來(lái)確定如何保留恢復(fù)一個(gè)寄存器,“encoding”是由于有寄存器擴(kuò)展,用于表示放置在opcodes中實(shí)際的位數(shù)。

      寄存器描述中還包括reg_class和alloc_class,如整形寄存器、浮點(diǎn)寄存器、特殊寄存器(如標(biāo)志寄存器)以及定義具有相同屬性的寄存器類等,它們整個(gè)是為指令選擇和寄存器分配提供信息,所有寄存器均是用戶可見或普通指令涉及的寄存器,不包括特權(quán)或處理器內(nèi)部寄存器。

      2. 指令集描述

      指令集在結(jié)構(gòu)描述文件中的工作占著很大比重,一是由于申威平臺(tái)指令較多,每條指令都需要描述;另一個(gè)是還需要描述操作碼、操作數(shù)屬性、考慮如何與中間表示匹配、匯編輸出格式以及硬件執(zhí)行上屬于什么流水分類等。

      下面我們以下兩個(gè)具體實(shí)例來(lái)說(shuō)明這些屬性設(shè)置的含義:

      實(shí)例1:

      1. Instruct addI_reg_reg(iRegI dst, iRegI src1, iRegI src2) %{

      2. match(Set dst (AddI src1 src2));

      3.

      4.? size(4);

      5. Format %{ “ADD? ? $src1,$src2,$dst” %}

      6. ins_encode %{

      7.? ? __ add($src1$$Register, $src2$$Register, $dst$$Register);

      8.? %}

      9.? ins_pipe(ialu_reg_reg);

      10. %}

      實(shí)例2:

      1. Instruct addI_reg_imm13(iRegI dst, iRegI src1, immI13 src2) %{

      2. match(Set dst (AddI src1 src2));

      3.

      4.? size(4);

      5.? Format %{ “ADD? ? $src1,$src2,$dst” %}

      6.? opcode(Assembler::add_op3, Assembler::arith_op);

      7.? ins_encode( form3_rs1_simm13_rd(src1, src2, dst) );

      8.? ins_pipe(ialu_reg_imm);

      9.? %}

      instruct:指定機(jī)器指令的入口。實(shí)例中說(shuō)明長(zhǎng)字加指令的入口,前一個(gè)是指操作數(shù)都為寄存器時(shí)addl指令的入口,后面的指操作數(shù)一是寄存器一是13位立即數(shù)時(shí)addl指令的入口。

      match:指定指令的中間表示匹配規(guī)則。

      size:指令默認(rèn)長(zhǎng)度,申威處理器指令長(zhǎng)度均為32位。

      encode:指定指令的編碼規(guī)則。在instruct定義中,有兩種方式生成本地機(jī)器碼,一種是通過(guò)ins_encode語(yǔ)句塊直接指定指令序列;另一種是通過(guò)opcode和ins_encode配合完成,opcode指定指令的操作碼(包括主操作碼和輔助操作碼),ins_encode指定指令的其他部分如何編碼,這是通過(guò)enc_class來(lái)完成。

      enc_class定義了若干指令編碼類供instruct使用,通過(guò)這種方式,可把編碼規(guī)則相同的指令用一個(gè)enc_class代替,這樣可有效降低instruct定義的工作量且可降低出錯(cuò)概率。

      ins_pipe:指定當(dāng)前指令使用哪些pipe_class。這在處理器流水線的特征里進(jìn)行了描述,包括指令長(zhǎng)度、是否有延遲槽等的屬性描述、指令執(zhí)行部件資源描述和不同類型的操作涉及了流水線的哪些階段的流水分類描述等。

      format:匯編指令的輸出格式。若為多條指令,應(yīng)一起輸出。

      指令描述的其他信息描述也都比較簡(jiǎn)單,從文檔中能夠明顯看出,這里不作詳述。指令集定義完成被ADL編譯器生成后,在指令選擇階段利用一個(gè)DFA來(lái)選擇匹配最優(yōu)的操作數(shù)和指令。

      3. 流水線結(jié)構(gòu)

      結(jié)構(gòu)描述文件還定義了處理器流水線的特征,它描述了指令執(zhí)行在硬件流水線上的特征。該部分描述涉及四部分:

      屬性(attributes):定義了指令長(zhǎng)度、是否有延遲槽等。

      資源(resources):定義指令執(zhí)行的功能部件。

      流水線描述(pipe_desc):定義流水線站臺(tái)。

      流水線分類(pipe_class):定義不同類型的操作涉及了流水線的哪些階段,,在指令集描述中的ins_pipe就是用于指定指令屬于哪個(gè)流水線分類。

      (三)指令匹配

      在解析Java字節(jié)碼并生成IR,進(jìn)而形成抽象語(yǔ)法樹(Abstract Syntax Tree, AST)中間文件,樹中的節(jié)點(diǎn)表示諸如加減乘除等操作,其子節(jié)點(diǎn)表示其輸入操作數(shù),比如圖4(a)表示寄存器形式的加法,該加法有兩個(gè)整數(shù)寄存器(iRegI)操作數(shù)和一個(gè)標(biāo)志寄存器操作數(shù)。這個(gè)樹最終可簡(jiǎn)單對(duì)應(yīng)到一條本地的addl指令。

      如果節(jié)點(diǎn)包含子樹,形成嵌套,則可表示更復(fù)雜的操作,如圖4(b)所示,mull有3個(gè)操作數(shù),其運(yùn)算結(jié)果又作為addl的操作數(shù)之一。該樹可能生成mull和addl兩條本地指令,也可能生成1條乘加指令。對(duì)于更復(fù)雜的樹,生成本地指令時(shí)可能面臨更復(fù)雜的多樣化選擇。為了生成最優(yōu)的指令,Hotspot中采用自底向上重寫系統(tǒng)(bottom-up rewrite system,BURS)算法[7],根據(jù)目標(biāo)機(jī)器體系結(jié)構(gòu)描述,如本地指令與中間指令的關(guān)系、指令開銷等自下而上匹配AST,選擇最優(yōu)本地指令。

      四、結(jié)束語(yǔ)

      Java虛擬機(jī)與體系結(jié)構(gòu)密切相關(guān),涉及處理器、操作系統(tǒng)核心、編譯器、基礎(chǔ)運(yùn)行時(shí)庫(kù)等模塊,涉及機(jī)器碼、匯編、C、C++、Java語(yǔ)言,其自身結(jié)構(gòu)復(fù)雜、技術(shù)先進(jìn)、代碼龐大。為了滿足企業(yè)級(jí)應(yīng)用對(duì)性能的最高要求,即時(shí)編譯模式不斷采用大量靜態(tài)編譯和激進(jìn)編譯優(yōu)化技術(shù),同時(shí)又盡可能降低運(yùn)行時(shí)開銷。

      C2即時(shí)編譯器是一個(gè)專門面向服務(wù)器典型應(yīng)用的充分優(yōu)化過(guò)的先進(jìn)自適應(yīng)編譯器,強(qiáng)調(diào)的是程序運(yùn)行的峰值性能。它支持許多和C++編譯器支持的相同類型的優(yōu)化,以及一些傳統(tǒng)編譯器所不能做的自適應(yīng)優(yōu)化,如虛擬方法調(diào)用間的積極樂(lè)觀內(nèi)聯(lián)(aggressive optimistic inlining)。與靜態(tài)編譯器相比,自適應(yīng)編譯器是非常靈活的,在優(yōu)化層面上有著無(wú)可比擬的競(jìng)爭(zhēng)優(yōu)勢(shì),典型情況下甚至比先進(jìn)的靜態(tài)分析和編譯技術(shù)更優(yōu)秀、輸出的代碼質(zhì)量更高。

      本文深入分析HotSpot虛擬機(jī)的運(yùn)行機(jī)制和C2即時(shí)編譯框架,為下一步深入面向平臺(tái)進(jìn)行軟硬件協(xié)同優(yōu)化打下好的基礎(chǔ)。

      作者單位:鄭艷? ? 無(wú)錫城市職業(yè)技術(shù)學(xué)院

      參? 考? 文? 獻(xiàn)

      [1]周志明. 深入理解Java虛擬機(jī)-JAVA虛擬機(jī)高級(jí)特性與最佳實(shí)踐(第2版). 機(jī)械工業(yè)出版社, 2013.6

      [2] Tim Lindholm, etc. The Java? Virtual Machine Specification. Oracle Corporation, Inc.

      [3] Peter B. Kessler. Java HotSpot? Virtual Machine. http://openjdk.java.net/groups/hotspot/docs/FOSDEM-2007-HotSpot.pdf, 2007

      [4] Sun Microsystems. The Java HotSpot Virtual Machine. A Technical White Paper.

      [5] Michael Paleczny, Christopher Vick, and Cliff Click. The Java HotSpot Server Compiler. In Proceedings of the Java Virtual Machine Research and Technology Symposium, 1-12,USENIX, 2001

      [6] ADL語(yǔ)法規(guī)范. JavaSoft HotSpot Architecture Description Language Syntax Specification. 1997.9

      [7]Eduardo Pelegrí-Llopart, Susan L. Graham. Optimal Code Generation for Expression Trees: an Application BURS Theory. In Proceedings of the 15th ACM Symposium on Principles of Programming Languages, ACM Press, 294-308, 1988

      烟台市| 江源县| 三门峡市| 固阳县| 营山县| 莫力| 岐山县| 集安市| 开阳县| 无锡市| 普格县| 依兰县| 江达县| 鸡泽县| 奉贤区| 济宁市| 龙泉市| 三台县| 渭源县| 左云县| 临泉县| 凤城市| 无锡市| 姚安县| 咸阳市| 泾源县| 河东区| 新巴尔虎右旗| 灵璧县| 仲巴县| 上高县| 昆明市| 汤阴县| 定边县| 金阳县| 法库县| 漳浦县| 辽宁省| 新乡市| 巴中市| 枞阳县|