认识Java中的Stub与StubQueue
目录
- 1、InterpreterCodelet与Stub类
- 2、StubQueue类
static StubQueue* _code;
由于TemplateInterpreter继承自AbstractInterpreter,所以在TemplateInterpreter中初始化的_code属性其实就是AbstractInterpreter类中定义的_code属性。
在initialize()函数中初始化_code变量的代码如下:
// InterpreterCodeSize是在平台相关// 的templateInterpreter_x86.hpp中// 定义的,64位下是256 * 1024int code_size = InterpreterCodeSize; _code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL,"Interpreter");
StubQueue是用来保存生成的本地代码的Stub队列,队列每一个元素对应一个
InterpreterCodelet
对象,InterpreterCodelet
对象继承自抽象基类Stub,包含了字节码对应的本地代码以及一些调试和输出信息。下面我们介绍一下StubQueue类及相关类Stub
、InterpreterCodelet
类和CodeletMark
类。【认识Java中的Stub与StubQueue】
1、InterpreterCodelet与Stub类 Stub类的定义如下:
class Stub VALUE_OBJ_CLASS_SPEC { ... };
InterpreterCodelet类继承自Stub类,具体的定义如下:
class InterpreterCodelet: public Stub { private:int_size; // the size in bytesconst char*_description; // a description of the codelet, for debugging & printingBytecodes::Code_bytecode; // associated bytecode if any public:// Code infoaddress 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个属性及一些函数,其内存布局如下图所示。
文章图片
在对齐至CodeEntryAlignment后,紧接着InterpreterCodelet的就是生成的目标代码。
2、StubQueue类 StubQueue是用来保存生成的本地机器指令片段的Stub队列,队列每一个元素都是一个InterpreterCodelet实例。
StubQueue类的定义如下:
class StubQueue: public CHeapObj{ private:StubInterface* _stub_interface; // the interface prototypeaddress_stub_buffer; // where all stubs are stored int_buffer_size; // the buffer size in bytesint_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对象 intbuffer_size,// 256*1024 Mutex*lock, const char*name) : _mutex(lock){intptr_tsize = round_to(buffer_size, 2*BytesPerWord); // BytesPerWord的值为8BufferBlob*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 intsize = sizeof(BufferBlob); // align the size to CodeEntryAlignmentsize = 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
的布局结构如下图所示。文章图片
队列中的
InterpreterCodelet
表示一个小例程,比如iconst_1
对应的机器码,invokedynamic
对应的机器码,异常处理对应的代码,方法入口点对应的代码,这些代码都是一个个InterpreterCodelet
。整个解释器都是由这些小块代码例程组成的,每个小块例程完成解释器的部分功能,以此实现整个解释器。到此这篇关于认识Java中的Stub与StubQueue的文章就介绍到这了,更多相关Stub与StubQueue内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- 热闹中的孤独
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- JS中的各种宽高度定义及其应用
- 我眼中的佛系经纪人
- 《魔法科高中的劣等生》第26卷(Invasion篇)发售
- Android中的AES加密-下
- 事件代理
- 放下心中的偶像包袱吧
- C语言字符函数中的isalnum()和iscntrl()你都知道吗
- Java|Java OpenCV图像处理之SIFT角点检测详解