Interpreter类,

class Interpreter: public CC_INTERP_ONLY(CppInterpreter) NOT_CC_INTERP(TemplateInterpreter) {

  public:
// Debugging/printing
static InterpreterCodelet* codelet_containing(address pc) { return (InterpreterCodelet*)_code->stub_containing(pc); }
#ifdef TARGET_ARCH_x86
# include "interpreter_x86.hpp"
#endif
};

看这俩个宏

#ifdef CC_INTERP
#define CC_INTERP_ONLY(code) code
#define NOT_CC_INTERP(code)
#else
#define CC_INTERP_ONLY(code)
#define NOT_CC_INTERP(code) code
#endif // CC_INTERP

啥也没干就是继承了,俩个类 CppInterpreter  和  TemplateInterpreter

说起来有点逗,java 是子类实现接口,这c++可好,子类继承了两个父类

class DispatchTable VALUE_OBJ_CLASS_SPEC {
public:
enum { length = 1 << BitsPerByte }; // an entry point for each byte value (also for undefined bytecodes) private:
address _table[number_of_states][length]; // dispatch tables, indexed by tosca and bytecode public:
// Attributes
EntryPoint entry(int i) const; // return entry point for a given bytecode i
void set_entry(int i, EntryPoint& entry); // set entry point for a given bytecode i
address* table_for(TosState state) { return _table[state]; }
address* table_for() { return table_for((TosState)0); }
int distance_from(address *table) { return table - table_for(); }
int distance_from(TosState state) { return distance_from(table_for(state)); } // Comparison
bool operator == (DispatchTable& y); // for debugging only
}; class TemplateInterpreter: public AbstractInterpreter {
friend class VMStructs;
friend class InterpreterMacroAssembler;
friend class TemplateInterpreterGenerator;
friend class InterpreterGenerator;
friend class TemplateTable;
// friend class Interpreter;
public: enum MoreConstants {
number_of_return_entries = number_of_states, // number of return entry points
number_of_deopt_entries = number_of_states, // number of deoptimization entry points
number_of_return_addrs = number_of_states // number of return addresses
}; protected: static address _throw_ArrayIndexOutOfBoundsException_entry;
static address _throw_ArrayStoreException_entry;
static address _throw_ArithmeticException_entry;
static address _throw_ClassCastException_entry;
static address _throw_WrongMethodType_entry;
static address _throw_NullPointerException_entry;
static address _throw_exception_entry; static address _throw_StackOverflowError_entry; static address _remove_activation_entry; // continuation address if an exception is not handled by current frame
#ifdef HOTSWAP
static address _remove_activation_preserving_args_entry; // continuation address when current frame is being popped
#endif // HOTSWAP #ifndef PRODUCT
static EntryPoint _trace_code;
#endif // !PRODUCT
static EntryPoint _return_entry[number_of_return_entries]; // entry points to return to from a call
static EntryPoint _earlyret_entry; // entry point to return early from a call
static EntryPoint _deopt_entry[number_of_deopt_entries]; // entry points to return to from a deoptimization
static EntryPoint _continuation_entry;
static EntryPoint _safept_entry; static address _return_3_addrs_by_index[number_of_return_addrs]; // for invokevirtual return entries
static address _return_5_addrs_by_index[number_of_return_addrs]; // for invokeinterface return entries static DispatchTable _active_table; // the active dispatch table (used by the interpreter for dispatch)
static DispatchTable _normal_table; // the normal dispatch table (used to set the active table in normal mode)
static DispatchTable _safept_table; // the safepoint dispatch table (used to set the active table for safepoints)
static address _wentry_point[DispatchTable::length]; // wide instructions only (vtos tosca always) public:
// Initialization/debugging
static void initialize();
// this only returns whether a pc is within generated code for the interpreter.
static bool contains(address pc) { return _code != NULL && _code->contains(pc); } public: static address remove_activation_early_entry(TosState state) { return _earlyret_entry.entry(state); }
#ifdef HOTSWAP
static address remove_activation_preserving_args_entry() { return _remove_activation_preserving_args_entry; }
#endif // HOTSWAP static address remove_activation_entry() { return _remove_activation_entry; }
static address throw_exception_entry() { return _throw_exception_entry; }
static address throw_ArithmeticException_entry() { return _throw_ArithmeticException_entry; }
static address throw_WrongMethodType_entry() { return _throw_WrongMethodType_entry; }
static address throw_NullPointerException_entry() { return _throw_NullPointerException_entry; }
static address throw_StackOverflowError_entry() { return _throw_StackOverflowError_entry; } // Code generation
#ifndef PRODUCT
static address trace_code (TosState state) { return _trace_code.entry(state); }
#endif // !PRODUCT
static address continuation (TosState state) { return _continuation_entry.entry(state); }
static address* dispatch_table(TosState state) { return _active_table.table_for(state); }
static address* dispatch_table() { return _active_table.table_for(); }
static int distance_from_dispatch_table(TosState state){ return _active_table.distance_from(state); }
static address* normal_table(TosState state) { return _normal_table.table_for(state); }
static address* normal_table() { return _normal_table.table_for(); } // Support for invokes
static address* return_3_addrs_by_index_table() { return _return_3_addrs_by_index; }
static address* return_5_addrs_by_index_table() { return _return_5_addrs_by_index; }
static int TosState_as_index(TosState state); // computes index into return_3_entry_by_index table static address return_entry (TosState state, int length);
static address deopt_entry (TosState state, int length); // Safepoint support
static void notice_safepoints(); // stops the thread when reaching a safepoint
static void ignore_safepoints(); // ignores safepoints // Deoptimization support
// Compute the entry address for continuation after
static address deopt_continue_after_entry(methodOop method,
address bcp,
int callee_parameters,
bool is_top_frame);
// Deoptimization should reexecute this bytecode
static bool bytecode_should_reexecute(Bytecodes::Code code);
// Compute the address for reexecution
static address deopt_reexecute_entry(methodOop method, address bcp); };

这里就看到真身了,  jmp(Address(rscratch1, rbx, Address::times_8));

  bind(no_safepoint);
lea(rscratch1, ExternalAddress((address)table));
bind(dispatch);
jmp(Address(rscratch1, rbx, Address::times_8));

这里将table地址给了 rscratch1

先看下执行一个add的字节码指令

     private static int add(int a, int b) {
int c=a+b;
int d=c+9;
return d;
} 0 iload_0
1 iload_1
2 iadd
3 istore_2
4 iload_2
5 bipush 9
7 iadd
8 istore_3
9 iload_3
10 ireturn

执行流程是 先得到

iload_0 ==>
iload_1==>
iadd

那就先取iload_0的指令地址,在dispatch_table表的某项,都值 jmp *(读到的值), 就跳到了  iload_1 对应的汇编指令去执行

形成了一个table表,从这个地址开始偏移00 代表 nop 这个指令的汇编指令地址

*table==>开始

*table+0x00

地址 内容  
*table+0x00 
0x0000000002cb6f40
nop
*table+0x8
0x0000000002cb6fc0
aconst_null  
*table+0x10
0x0000000002cb7040

iconst_m1  
*table+0x18
0x0000000002cb70c0

iconst_0  
----------------------------------------------------------------------
nop 0 nop [0x0000000002cb6f40, 0x0000000002cb6fa0] 96 bytes 0x0000000002cb6f40: push %rax
0x0000000002cb6f41: jmpq 0x0000000002cb6f70
0x0000000002cb6f46: sub $0x8,%rsp
0x0000000002cb6f4a: vmovss %xmm0,(%rsp)
0x0000000002cb6f4f: jmpq 0x0000000002cb6f70
0x0000000002cb6f54: sub $0x10,%rsp
0x0000000002cb6f58: vmovsd %xmm0,(%rsp)
0x0000000002cb6f5d: jmpq 0x0000000002cb6f70
0x0000000002cb6f62: sub $0x10,%rsp
0x0000000002cb6f66: mov %rax,(%rsp)
0x0000000002cb6f6a: jmpq 0x0000000002cb6f70
0x0000000002cb6f6f: push %rax
0x0000000002cb6f70: movzbl 0x1(%r13),%ebx
0x0000000002cb6f75: inc %r13
0x0000000002cb6f78: movabs $0x667c43f0,%r10
0x0000000002cb6f82: jmpq *(%r10,%rbx,8)
0x0000000002cb6f86: xchg %ax,%ax
0x0000000002cb6f88: add %al,(%rax)
0x0000000002cb6f8a: add %al,(%rax)
0x0000000002cb6f8c: add %al,(%rax)
0x0000000002cb6f8e: add %al,(%rax)
0x0000000002cb6f90: add %al,(%rax)
0x0000000002cb6f92: add %al,(%rax)
0x0000000002cb6f94: add %al,(%rax)
0x0000000002cb6f96: add %al,(%rax)
0x0000000002cb6f98: add %al,(%rax)
0x0000000002cb6f9a: add %al,(%rax)
0x0000000002cb6f9c: add %al,(%rax)
0x0000000002cb6f9e: add %al,(%rax) ----------------------------------------------------------------------
aconst_null 1 aconst_null [0x0000000002cb6fc0, 0x0000000002cb7020] 96 bytes 0x0000000002cb6fc0: push %rax
0x0000000002cb6fc1: jmpq 0x0000000002cb6ff0
0x0000000002cb6fc6: sub $0x8,%rsp
0x0000000002cb6fca: vmovss %xmm0,(%rsp)
0x0000000002cb6fcf: jmpq 0x0000000002cb6ff0
0x0000000002cb6fd4: sub $0x10,%rsp
0x0000000002cb6fd8: vmovsd %xmm0,(%rsp)
0x0000000002cb6fdd: jmpq 0x0000000002cb6ff0
0x0000000002cb6fe2: sub $0x10,%rsp
0x0000000002cb6fe6: mov %rax,(%rsp)
0x0000000002cb6fea: jmpq 0x0000000002cb6ff0
0x0000000002cb6fef: push %rax
0x0000000002cb6ff0: xor %eax,%eax
0x0000000002cb6ff2: movzbl 0x1(%r13),%ebx
0x0000000002cb6ff7: inc %r13
0x0000000002cb6ffa: movabs $0x667c3bf0,%r10
0x0000000002cb7004: jmpq *(%r10,%rbx,8)
0x0000000002cb7008: add %al,(%rax)
0x0000000002cb700a: add %al,(%rax)
0x0000000002cb700c: add %al,(%rax)
0x0000000002cb700e: add %al,(%rax)
0x0000000002cb7010: add %al,(%rax)
0x0000000002cb7012: add %al,(%rax)
0x0000000002cb7014: add %al,(%rax)
0x0000000002cb7016: add %al,(%rax)
0x0000000002cb7018: add %al,(%rax)
0x0000000002cb701a: add %al,(%rax)
0x0000000002cb701c: add %al,(%rax)
0x0000000002cb701e: add %al,(%rax) ----------------------------------------------------------------------
iconst_m1 2 iconst_m1 [0x0000000002cb7040, 0x0000000002cb70a0] 96 bytes 0x0000000002cb7040: push %rax
0x0000000002cb7041: jmpq 0x0000000002cb7070
0x0000000002cb7046: sub $0x8,%rsp
0x0000000002cb704a: vmovss %xmm0,(%rsp)
0x0000000002cb704f: jmpq 0x0000000002cb7070
0x0000000002cb7054: sub $0x10,%rsp
0x0000000002cb7058: vmovsd %xmm0,(%rsp)
0x0000000002cb705d: jmpq 0x0000000002cb7070
0x0000000002cb7062: sub $0x10,%rsp
0x0000000002cb7066: mov %rax,(%rsp)
0x0000000002cb706a: jmpq 0x0000000002cb7070
0x0000000002cb706f: push %rax
0x0000000002cb7070: mov $0xffffffff,%eax
0x0000000002cb7075: movzbl 0x1(%r13),%ebx
0x0000000002cb707a: inc %r13
0x0000000002cb707d: movabs $0x667c1bf0,%r10
0x0000000002cb7087: jmpq *(%r10,%rbx,8)
0x0000000002cb708b: nopl 0x0(%rax,%rax,1)
0x0000000002cb7090: add %al,(%rax)
0x0000000002cb7092: add %al,(%rax)
0x0000000002cb7094: add %al,(%rax)
0x0000000002cb7096: add %al,(%rax)
0x0000000002cb7098: add %al,(%rax)
0x0000000002cb709a: add %al,(%rax)
0x0000000002cb709c: add %al,(%rax)
0x0000000002cb709e: add %al,(%rax) ----------------------------------------------------------------------
iconst_0 3 iconst_0 [0x0000000002cb70c0, 0x0000000002cb7120] 96 bytes 0x0000000002cb70c0: push %rax
0x0000000002cb70c1: jmpq 0x0000000002cb70f0
0x0000000002cb70c6: sub $0x8,%rsp
0x0000000002cb70ca: vmovss %xmm0,(%rsp)
0x0000000002cb70cf: jmpq 0x0000000002cb70f0
0x0000000002cb70d4: sub $0x10,%rsp
0x0000000002cb70d8: vmovsd %xmm0,(%rsp)
0x0000000002cb70dd: jmpq 0x0000000002cb70f0
0x0000000002cb70e2: sub $0x10,%rsp
0x0000000002cb70e6: mov %rax,(%rsp)
0x0000000002cb70ea: jmpq 0x0000000002cb70f0
0x0000000002cb70ef: push %rax
0x0000000002cb70f0: xor %eax,%eax
0x0000000002cb70f2: movzbl 0x1(%r13),%ebx
0x0000000002cb70f7: inc %r13
0x0000000002cb70fa: movabs $0x667c1bf0,%r10
0x0000000002cb7104: jmpq *(%r10,%rbx,8)
0x0000000002cb7108: add %al,(%rax)
0x0000000002cb710a: add %al,(%rax)
0x0000000002cb710c: add %al,(%rax)
0x0000000002cb710e: add %al,(%rax)
0x0000000002cb7110: add %al,(%rax)
0x0000000002cb7112: add %al,(%rax)
0x0000000002cb7114: add %al,(%rax)
0x0000000002cb7116: add %al,(%rax)
0x0000000002cb7118: add %al,(%rax)
0x0000000002cb711a: add %al,(%rax)
0x0000000002cb711c: add %al,(%rax)
0x0000000002cb711e: add %al,(%rax)

这样就解释清楚了,这个table是什么为什么通过dispatch_table 取指_表 能获得指令

Table类的更多相关文章

  1. Windows Azure Table storage 之 动态Table类 DynamicTableEntity

    在一般情况下,当我们在.net中使用Azure table storage的时候都会为该表建立一个TableEntity的派生类,如下所示. public class CustomerEntity : ...

  2. ASP.Net:Table类的使用

    在做Asp.Net的时候,很多情况下数据的绑定都是使用GridView或者我之前提到的ListView,但是这两个适合用于数据的绑定,而有些时候,数据需要在后台进行处理,例如数据据内地某一条数据的特殊 ...

  3. Table 类(数据表基类)

    只修改数据表某条记录的部分字段(究极进化): public class TableHelper { private Dictionary<string, object> temp; pub ...

  4. Selenium Webdriver——Table类封装

    WebTable.java import java.util.List; import org.openqa.selenium.By; import org.openqa.selenium.WebEl ...

  5. SQLAlchemy Table(表)类方式 - Table类和Column类

    Table 构造方法 Table(name, metadata[, *column_list][, **kwargs]) 参数说明: name 表名 metadata 元数据对象 column_lis ...

  6. 基于Java使用Flink读取CSV文件,针对批处理,多表联合两种方式Table类和Join方法的实现数据处理,再入CSV文件

    Maven依赖 源头 <dependencies> <dependency> <groupId>org.projectlombok</groupId> ...

  7. bootstrap panel 和table的使用

    一.HTML中的页面内容 <div class="col-sm-12"> <!-- <div class="m-b-md" style= ...

  8. 关于SWT中的表格(TableViewer类)

    JFace是SWT的扩展.它提供了一组功能强大的界面组件.其中包含表格,树,列表.对话框,向导对话框等. 表格是一种在软件系统中很常用的数据表现形式.特别是基于数据库的应用系统.表格更是不可缺少的界面 ...

  9. 排版-标题及table

    排版-标题 在标题中还可以包含small标签,可以用来标记副标题 副标题灰色,比主标题小    <h1>我是标题 <small>我是小标题</small></ ...

随机推荐

  1. JVM调优的反思与总结

    垃圾回收的悖论 所谓"成也萧何败萧何".Java的垃圾回收确实带来了很多好处,为开发带来了便利.但是在一些高性能.高并发的情况下,垃圾回收确成为了制约Java应用的瓶颈.目前JDK ...

  2. DOS命令行(10)——reg/regini-注册表编辑命令行工具

    注册表的介绍 注册表(Registry,台湾.港澳译作登錄檔)是Microsoft Windows中的一个重要的数据库,用于存储系统和应用程序的设置信息.   1. 数据结构 注册表由键(key,或称 ...

  3. WEB安全新玩法 [5] 防范水平越权之查看他人订单信息

    水平越权是指系统中的用户在未经授权的情况下,查看到另一个同级别用户所拥有的资源.水平越权会导致信息泄露,其产生原因是软件业务设计或编码上的缺陷.iFlow 业务安全加固平台可以缓解部分场景下的水平越权 ...

  4. 16、编译安装ansible

    16.1.python版本说明: Ansible是一种批量部署工具,现在运维人员用的最多的三种开源集中化管理工具有:puppet,saltstack,ansible,各有各的优缺点, 其中saltst ...

  5. echarts 根据geojson 数据绘制区域图(精确到镇)

    步骤:1)先获取区域(县.镇)json数据 :2)使用echarts 绘制地图: 先上一波效果图(昆明市东川区) 一.获取区域json数据 1.下载工具"水经微图", 2.下载东川 ...

  6. AcWing 239. 奇偶游戏

    小A和小B在玩一个游戏. 首先,小A写了一个由0和1组成的序列S,长度为N. 然后,小B向小A提出了M个问题. 在每个问题中,小B指定两个数 l 和 r,小A回答 S[l~r] 中有奇数个1还是偶数个 ...

  7. Nginx-多服务绑定80端口及映射域名

    多服务绑定80端口及映射域名 说明:业务需要配置的样例模板,如需深入了解,请查看官方文档 1.Nginx配置文件nginx.conf(可拆分多台机器部署) worker_processes  1; e ...

  8. JSR - 133 都解决了哪些问题?

    究竟什么是内存模型? 在多处理系统中,每个 CPU 通常都包含一层或者多层内存缓存,这样设计的原因是为了加快数据访问速度(因为数据会更靠近处理器) 并且能够减少共享内存总线上的流量(因为可以满足许多内 ...

  9. ubuntu16.04上编译android的可执行文件并调用本地so库

    前言: 找了蛮多资料的,发现目前实现的编译方式大致就两种,一种是直接使用android源码中的编译工具链,另一种就是使用独立的交叉编译工具链,第二种我还在实现中,配置步骤挺多的 ,第一种实现方式挺方便 ...

  10. Linux学习之路第十天(磁盘情况查询)

    一.查询系统整体磁盘使用情况 :基本语法 df -h 二.查询指定目录的磁盘占用情况 :基本语法 du -h /目录 查询指定目录的磁盘占用情况,默认为当前目录 选项 应用案例 查询/opt目录,深度 ...