認(rèn)識(shí)Java中的Stub與StubQueue
在文章開始前先簡(jiǎn)單介紹TemplateInterpreter::initialize()函數(shù),在這個(gè)函數(shù)中會(huì)調(diào)用TemplateTable::initialize()函數(shù)初始化模板表,隨后會(huì)使用new關(guān)鍵字初始化定義在AbstractInterpreter類中的_code靜態(tài)屬性,如下:
static StubQueue* _code;
由于TemplateInterpreter繼承自AbstractInterpreter,所以在TemplateInterpreter中初始化的_code屬性其實(shí)就是AbstractInterpreter類中定義的_code屬性。
在initialize()函數(shù)中初始化_code變量的代碼如下:
// InterpreterCodeSize是在平臺(tái)相關(guān) // 的templateInterpreter_x86.hpp中 // 定義的,64位下是256 * 1024 int code_size = InterpreterCodeSize; _code = new StubQueue( new InterpreterCodeletInterface, code_size, NULL, "Interpreter");
StubQueue是用來保存生成的本地代碼的Stub隊(duì)列,隊(duì)列每一個(gè)元素對(duì)應(yīng)一個(gè)InterpreterCodelet
對(duì)象,InterpreterCodelet
對(duì)象繼承自抽象基類Stub,包含了字節(jié)碼對(duì)應(yīng)的本地代碼以及一些調(diào)試和輸出信息。下面我們介紹一下StubQueue類及相關(guān)類Stub
、InterpreterCodelet
類和CodeletMark
類。
1、InterpreterCodelet與Stub類
Stub類的定義如下:
class Stub VALUE_OBJ_CLASS_SPEC { ... };
InterpreterCodelet類繼承自Stub類,具體的定義如下:
class InterpreterCodelet: public Stub { private: int _size; // the size in bytes const char* _description; // a description of the codelet, for debugging & printing Bytecodes::Code _bytecode; // associated bytecode if any public: // Code info address code_begin() const { return (address)this + round_to(sizeof(InterpreterCodelet), CodeEntryAlignment); } address code_end() const { return (address)this + size(); } int size() const { return _size; } // ... int code_size() const { return code_end() - code_begin(); } // ... };
InterpreterCodelet
實(shí)例存儲(chǔ)在StubQueue
中,每個(gè)InterpreterCodelet
實(shí)例都代表一段機(jī)器指令(包含了字節(jié)碼對(duì)應(yīng)的機(jī)器指令片段以及一些調(diào)試和輸出信息),如每個(gè)字節(jié)碼都有一個(gè)InterpreterCodelet
實(shí)例,所以在解釋執(zhí)行時(shí),如果要執(zhí)行某個(gè)字節(jié)碼,則執(zhí)行的就是由InterpreterCodelet
實(shí)例代表的機(jī)器指令片段。
類中定義了3個(gè)屬性及一些函數(shù),其內(nèi)存布局如下圖所示。
在對(duì)齊至CodeEntryAlignment后,緊接著InterpreterCodelet的就是生成的目標(biāo)代碼。
2、StubQueue類
StubQueue是用來保存生成的本地機(jī)器指令片段的Stub隊(duì)列,隊(duì)列每一個(gè)元素都是一個(gè)InterpreterCodelet實(shí)例。
StubQueue類的定義如下:
class StubQueue: public CHeapObj<mtCode> { private: StubInterface* _stub_interface; // the interface prototype address _stub_buffer; // where all stubs are stored int _buffer_size; // the buffer size in bytes int _buffer_limit; // the (byte) index of the actual buffer limit (_buffer_limit <= _buffer_size) int _queue_begin; // the (byte) index of the first queue entry (word-aligned) int _queue_end; // the (byte) index of the first entry after the queue (word-aligned) int _number_of_stubs; // the number of buffered stubs bool is_contiguous() const { return _queue_begin <= _queue_end; } int index_of(Stub* s) const { int i = (address)s - _stub_buffer; return i; } Stub* stub_at(int i) const { return (Stub*)(_stub_buffer + i); } Stub* current_stub() const { return stub_at(_queue_end); } // ... }
這個(gè)類的構(gòu)造函數(shù)如下:
StubQueue::StubQueue( StubInterface* stub_interface, // InterpreterCodeletInterface對(duì)象 int buffer_size, // 256*1024 Mutex* lock, const char* name) : _mutex(lock) { intptr_t size = round_to(buffer_size, 2*BytesPerWord); // BytesPerWord的值為8 BufferBlob* blob = BufferBlob::create(name, size); // 在StubQueue中創(chuàng)建BufferBlob對(duì)象 _stub_interface = stub_interface; _buffer_size = blob->content_size(); _buffer_limit = blob->content_size(); _stub_buffer = blob->content_begin(); _queue_begin = 0; _queue_end = 0; _number_of_stubs = 0; }
stub_interface
用來保存一個(gè)InterpreterCodeletInterface
類型的實(shí)例,InterpreterCodeletInterface
類中定義了操作Stub的函數(shù),避免了在Stub中定義虛函數(shù)。每個(gè)StubQueue
都有一個(gè)InterpreterCodeletInterface
,可以通過這個(gè)來操作StubQueue
中存儲(chǔ)的每個(gè)Stub
實(shí)例。
調(diào)用BufferBlob::create()
函數(shù)為StubQueue
分配內(nèi)存,這里我們需要記住StubQueue用的內(nèi)存是通過BufferBlob分配出來的,也就是BufferBlob其本質(zhì)可能是一個(gè)StubQueue。下面就來詳細(xì)介紹下create()函數(shù)。
BufferBlob* BufferBlob::create(const char* name, int buffer_size) { // ... BufferBlob* blob = NULL; unsigned int size = sizeof(BufferBlob); // align the size to CodeEntryAlignment size = align_code_offset(size); size += round_to(buffer_size, oopSize); // oopSize是一個(gè)指針的寬度,在64位上就是8 { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); blob = new (size) BufferBlob(name, size); } return blob; }
通過new關(guān)鍵字為BufferBlob分配內(nèi)存,new重載運(yùn)算符如下:
void* BufferBlob::operator new(size_t s, unsigned size, bool is_critical) throw() { void* p = CodeCache::allocate(size, is_critical); return p; }
從codeCache
中分配內(nèi)存,CodeCache
使用的是本地內(nèi)存,有自己的內(nèi)存管理辦法,在后面將會(huì)詳細(xì)介紹。
StubQueue
的布局結(jié)構(gòu)如下圖所示。
隊(duì)列中的InterpreterCodelet
表示一個(gè)小例程,比如iconst_1
對(duì)應(yīng)的機(jī)器碼,invokedynamic
對(duì)應(yīng)的機(jī)器碼,異常處理對(duì)應(yīng)的代碼,方法入口點(diǎn)對(duì)應(yīng)的代碼,這些代碼都是一個(gè)個(gè)InterpreterCodelet
。整個(gè)解釋器都是由這些小塊代碼例程組成的,每個(gè)小塊例程完成解釋器的部分功能,以此實(shí)現(xiàn)整個(gè)解釋器。
到此這篇關(guān)于認(rèn)識(shí)Java中的Stub與StubQueue的文章就介紹到這了,更多相關(guān)Stub與StubQueue內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot實(shí)現(xiàn)多模塊項(xiàng)目添加一新模塊
這篇文章主要介紹了springboot實(shí)現(xiàn)多模塊項(xiàng)目添加一新模塊,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02springBoot定時(shí)任務(wù)處理類的實(shí)現(xiàn)代碼
這篇文章主要介紹了springBoot定時(shí)任務(wù)處理類,需要的朋友可以參考下2018-06-06Mybatis-Plus-AutoGenerator 最詳細(xì)使用方法
這篇文章主要介紹了Mybatis-Plus-AutoGenerator 最詳細(xì)使用方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03Java Runtime類詳解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
Runtime類封裝了運(yùn)行時(shí)的環(huán)境。每個(gè) Java 應(yīng)用程序都有一個(gè) Runtime 類實(shí)例,使應(yīng)用程序能夠與其運(yùn)行的環(huán)境相連接。下面通過本文給大家分享Java Runtime類詳解,需要的朋友參考下吧2017-04-04Mybatis動(dòng)態(tài)sql中@Param使用詳解
這篇文章主要介紹了Mybatis動(dòng)態(tài)sql中@Param使用詳解,當(dāng)方法的參數(shù)為非自定義pojo類型,且使用了動(dòng)態(tài)sql,那么就需要在參數(shù)前加上@Param注解,需要的朋友可以參考下2023-10-10springboot使用dubbo和zookeeper代碼實(shí)例
這篇文章主要介紹了springboot使用dubbo和zookeeper代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11javaweb servlet生成簡(jiǎn)單驗(yàn)證碼
這篇文章主要為大家詳細(xì)介紹了javaweb servlet生成簡(jiǎn)單驗(yàn)證碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-03-03關(guān)于Springboot | @RequestBody 接收到的參數(shù)對(duì)象屬性為空的問題
這篇文章主要介紹了關(guān)于Springboot | @RequestBody 接收到的參數(shù)對(duì)象屬性為空的問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03詳解在SpringBoot中使用MongoDb做單元測(cè)試的代碼
這篇文章主要介紹了詳解在SpringBoot中使用MongoDb做單元測(cè)試的代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11