亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中的Stub類與StubQueue類的用法

發布時間:2021-09-10 19:08:50 來源:億速云 閱讀:176 作者:chen 欄目:開發技術

本篇內容介紹了“Java中的Stub類與StubQueue類的用法”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

目錄
  • 1、InterpreterCodelet與Stub類

  • 2、StubQueue類

在文章開始前先簡單介紹TemplateInterpreter::initialize()函數,在這個函數中會調用TemplateTable::initialize()函數初始化模板表,隨后會使用new關鍵字初始化定義在AbstractInterpreter類中的_code靜態屬性,如下:

static StubQueue* _code;

由于TemplateInterpreter繼承自AbstractInterpreter,所以在TemplateInterpreter中初始化的_code屬性其實就是AbstractInterpreter類中定義的_code屬性。

在initialize()函數中初始化_code變量的代碼如下

// InterpreterCodeSize是在平臺相關
// 的templateInterpreter_x86.hpp中
// 定義的,64位下是256 * 1024
int code_size = InterpreterCodeSize;
_code = new StubQueue(
                new InterpreterCodeletInterface, 
                code_size, 
                NULL,
                "Interpreter");

StubQueue是用來保存生成的本地代碼的Stub隊列,隊列每一個元素對應一個InterpreterCodelet對象,InterpreterCodelet對象繼承自抽象基類Stub,包含了字節碼對應的本地代碼以及一些調試和輸出信息。下面我們介紹一下StubQueue類及相關類StubInterpreterCodelet類和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實例存儲在StubQueue中,每個InterpreterCodelet實例都代表一段機器指令(包含了字節碼對應的機器指令片段以及一些調試和輸出信息),如每個字節碼都有一個InterpreterCodelet實例,所以在解釋執行時,如果要執行某個字節碼,則執行的就是由InterpreterCodelet實例代表的機器指令片段。

類中定義了3個屬性及一些函數,其內存布局如下圖所示。

  Java中的Stub類與StubQueue類的用法

在對齊至CodeEntryAlignment后,緊接著InterpreterCodelet的就是生成的目標代碼。

2、StubQueue類

StubQueue是用來保存生成的本地機器指令片段的Stub隊列,隊列每一個元素都是一個InterpreterCodelet實例。

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);
  }
 
  // ...
}

這個類的構造函數如下:

StubQueue::StubQueue(
 StubInterface* stub_interface,  // InterpreterCodeletInterface對象
 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中創建BufferBlob對象
 
  _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用來保存一個InterpreterCodeletInterface類型的實例,InterpreterCodeletInterface類中定義了操作Stub的函數,避免了在Stub中定義虛函數。每個StubQueue都有一個InterpreterCodeletInterface,可以通過這個來操作StubQueue中存儲的每個Stub實例。

調用BufferBlob::create()函數為StubQueue分配內存,這里我們需要記住StubQueue用的內存是通過BufferBlob分配出來的,也就是BufferBlob其本質可能是一個StubQueue。下面就來詳細介紹下create()函數。

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是一個指針的寬度,在64位上就是8
 
  {
     MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
     blob = new (size) BufferBlob(name, size);
  }
 
  return blob;
}

通過new關鍵字為BufferBlob分配內存,new重載運算符如下:

void* BufferBlob::operator new(size_t s, unsigned size, bool is_critical) throw() {
  void* p = CodeCache::allocate(size, is_critical);
  return p;
}

codeCache中分配內存,CodeCache使用的是本地內存,有自己的內存管理辦法,在后面將會詳細介紹。

StubQueue的布局結構如下圖所示。

Java中的Stub類與StubQueue類的用法

隊列中的InterpreterCodelet表示一個小例程,比如iconst_1對應的機器碼,invokedynamic對應的機器碼,異常處理對應的代碼,方法入口點對應的代碼,這些代碼都是一個個InterpreterCodelet。整個解釋器都是由這些小塊代碼例程組成的,每個小塊例程完成解釋器的部分功能,以此實現整個解釋器。

“Java中的Stub類與StubQueue類的用法”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

故城县| 梅州市| 宝丰县| 千阳县| 成安县| 怀远县| 沙湾县| 阳东县| 涞水县| 当雄县| 天水市| 永善县| 泗水县| 新闻| 兖州市| 阜阳市| 竹溪县| 蒲江县| 三台县| 巴中市| 金溪县| 房产| 馆陶县| 嵊泗县| 蒙山县| 彰化县| 涡阳县| 波密县| 蓝田县| 英吉沙县| 南城县| 武威市| 馆陶县| 邯郸县| 福鼎市| 洪江市| 民勤县| 连云港市| 石狮市| 高安市| 卢龙县|