zoukankan      html  css  js  c++  java
  • Table类

    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 取指_表 能获得指令

  • 相关阅读:
    get请求乱码情况
    write()和prinln()的区别?
    校验码实现
    下载图片代码并且解析乱码
    servlet下根据相对路径找资源
    url-pattern配置
    获取网站资源 getResourceAsStream
    Servlet线程安全性
    http1.1 协议响应方面参数
    HTTP1.1协议请求方面参数
  • 原文地址:https://www.cnblogs.com/zytcomeon/p/14529031.html
Copyright © 2011-2022 走看看