千家信息网

Java中的Stub类与StubQueue类的用法

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,本篇内容介绍了"Java中的Stub类与StubQueue类的用法"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能
千家信息网最后更新 2026年11月02日Java中的Stub类与StubQueue类的用法

本篇内容介绍了"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 * 1024int code_size = InterpreterCodeSize;_code = new StubQueue(                new InterpreterCodeletInterface,                 code_size,                 NULL,                "Interpreter");

StubQueue是用来保存生成的本地代码的Stub队列,队列每一个元素对应一个InterpreterCodelet对象,InterpreterCodelet对象继承自抽象基类Stub,包含了字节码对应的本地代码以及一些调试和输出信息。下面我们介绍一下StubQueue类及相关类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实例存储在StubQueue中,每个InterpreterCodelet实例都代表一段机器指令(包含了字节码对应的机器指令片段以及一些调试和输出信息),如每个字节码都有一个InterpreterCodelet实例,所以在解释执行时,如果要执行某个字节码,则执行的就是由InterpreterCodelet实例代表的机器指令片段。

类中定义了3个属性及一些函数,其内存布局如下图所示。

在对齐至CodeEntryAlignment后,紧接着InterpreterCodelet的就是生成的目标代码。

2、StubQueue类

StubQueue是用来保存生成的本地机器指令片段的Stub队列,队列每一个元素都是一个InterpreterCodelet实例。

StubQueue类的定义如下:

class StubQueue: public CHeapObj { 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的布局结构如下图所示。

队列中的InterpreterCodelet表示一个小例程,比如iconst_1对应的机器码,invokedynamic对应的机器码,异常处理对应的代码,方法入口点对应的代码,这些代码都是一个个InterpreterCodelet。整个解释器都是由这些小块代码例程组成的,每个小块例程完成解释器的部分功能,以此实现整个解释器。

"Java中的Stub类与StubQueue类的用法"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

函数 代码 内存 实例 机器 队列 字节 对象 属性 指令 解释 就是 片段 解释器 分配 生成 输出 代表 信息 元素 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 工业互联网科技新基建 科技服务与互联网 奇士达互联网科技 友谊互联网络科技 天扬科技互联网广告 恒生科技互联网指数分析 博兴的互联网电子科技公司 广州恒生互联网科技有限 来此购互联网科技有限公司 港股科技和互联网 湖南一路畅行互联网科技 搜狐科技互联网 洛阳昕诺飞互联网科技有限公司 深圳市优智互联网科技有限公司 沐思想互联网科技有限公司 互联网科技年终奖 易企秀互联网科技是做什么的 互联网科技职业技能培训学校 米泉互联网科技专业怎么样 株洲百竞科技的互联网营销顾问 麻工互联网科技 华宇互联网科技 成都狮子座互联网科技 海南购全球互联网科技 团飞科技与伯堂互联网服务平台 速维有品互联网信息科技(苏州)有限公司 35岁以上互联网科技行业 互联网科技接地气 福仕德教育科技互联网 平安好医生打造互联网科技医疗
0