当前位置: 首页 > news >正文

揭秘OpenJDK 17字节码解释引擎:模板解释器深度解析

Java字节码的执行是JVM的核心能力,而OpenJDK 17的模板解释器(Template Interpreter)则是高效解释执行的关键。本文将深入剖析其工作原理,带您一窥Java程序在JVM中的执行奥秘。

一、模板解释器的核心设计

模板解释器通过预编译机器码模板代替传统的switch-case解释循环,其核心是模板表初始化过程:

cpp

// 字节码模板定义示例
def(Bytecodes::_iadd, ____|____|____|____, itos, itos, iop2, add);
def(Bytecodes::_new, ubcp|____|clvm|____, vtos, atos, _new, _);

每个模板定义包含:

  1. 字节码标识(如_iadd

  2. 标志位(是否使用常量池/需要分派等)

  3. 输入/输出栈顶状态(itos整型输入输出)

  4. 生成器函数(iop2执行整数运算)

  5. 附加参数(add指定加法操作)

二、字节码执行四步流程

步骤1:入口点绑定

cpp

void set_entry_points(Bytecodes::Code code) {Template* t = TemplateTable::template_for(code);set_short_entry_points(t, bep, cep, sep...); Interpreter::_normal_table.set_entry(code, entry);
}

根据字节码类型绑定预生成的机器码入口,后续执行直接跳转无需解析。

步骤2:栈帧初始化

方法调用时构建完整的调用环境:

cpp

void generate_normal_entry(bool synchronized) {// 1. 计算参数和局部变量大小__ load_unsigned_short(rcx, size_of_parameters); // 2. 栈溢出检查generate_stack_overflow_check(); // 3. 分配局部变量空间__ lea(rlocals, Address(rsp, rcx, Interpreter::stackElementScale(), -wordSize));// 4. 构建固定帧结构generate_fixed_frame(false);
}
步骤3:字节码分派

通过高效分派机制跳转到目标字节码处理:

cpp

void dispatch_next(TosState state, int step) {load_unsigned_byte(rbx, Address(_bcp_register, step)); // 加载下一字节码increment(_bcp_register, step); // 更新字节码指针dispatch_base(state, Interpreter::dispatch_table(state));
}
步骤4:模板执行

针对具体字节码执行预编译的机器码:

cpp

void generate_and_dispatch(Template* t) {t->generate(_masm); // 生成当前字节码的机器码__ dispatch_epilog(tos_out, step); // 分派到下一字节码
}

三、关键优化技术

  1. 栈顶状态敏感优化

    cpp

    switch (t->tos_in()) {case atos: __ pop(atos); generate_and_dispatch(t); break;case itos: __ pop(itos); generate_and_dispatch(t); break;//...
    }

    根据输入/输出类型生成特化代码,避免冗余类型转换。

  2. 快速路径指令

    cpp

    def(Bytecodes::_fast_igetfield, ubcp|____|____|____, atos, itos, fast_accessfield, itos);

    对字段访问等高频操作提供快速路径,绕过常规查找流程。

  3. 调用计数器

    cpp

    Label invocation_counter_overflow;
    generate_counter_incr(&invocation_counter_overflow);

    统计方法调用次数,触发JIT编译的黄金标准。

  4. 安全点轮询

    cpp

    if (generate_poll) {testb(Address(thread, JavaThread::polling_word_offset()), poll_bit());jcc(Assembler::notZero, handle_safepoint);
    }

    在分派点插入安全点检查,实现GC等操作的协同。

四、性能对比:模板解释器 vs 传统解释器

特性模板解释器传统解释器
执行机制预编译机器码模板switch-case循环
分派开销1次内存跳转多次条件判断
类型转换生成特化代码运行时动态判断
编译开销启动时预生成
平均性能提升2-5倍基准

五、技术演进思考

  1. 分层编译的基石:模板解释器作为"第0层编译器",为C1/C2编译器提供性能分析数据

  2. 与AOT的协同:预编译机制为GraalVM原生镜像提供技术铺垫

  3. 未来优化方向

    • SIMD指令在模板中的利用

    • 基于AI的模板自动优化

    • 异构计算设备支持

结语

OpenJDK 17的模板解释器通过预编译+直接分派的核心设计,在解释执行和编译执行间架起高效桥梁。这种"用空间换时间"的策略,使Java在启动速度和长期运行性能间取得精妙平衡,奠定了现代JVM高效执行的基础。随着Java虚拟线程等新技术的发展,解释器作为执行引擎基石的角色将更加重要。

 ##源码

void TemplateTable::initialize() {
#ifdef ASSERTstatic bool is_initialized = false;assert(!is_initialized, "must only initialize once");is_initialized = true;
#endif// For better readabilityconst char _    = ' ';const int  ____ = 0;const int  ubcp = 1 << Template::uses_bcp_bit;const int  disp = 1 << Template::does_dispatch_bit;const int  clvm = 1 << Template::calls_vm_bit;const int  iswd = 1 << Template::wide_bit;//                                    interpr. templates// Java spec bytecodes                ubcp|disp|clvm|iswd  in    out   generator             argumentdef(Bytecodes::_nop                 , ____|____|____|____, vtos, vtos, nop                 ,  _           );def(Bytecodes::_aconst_null         , ____|____|____|____, vtos, atos, aconst_null         ,  _           );def(Bytecodes::_iconst_m1           , ____|____|____|____, vtos, itos, iconst              , -1           );def(Bytecodes::_iconst_0            , ____|____|____|____, vtos, itos, iconst              ,  0           );def(Bytecodes::_iconst_1            , ____|____|____|____, vtos, itos, iconst              ,  1           );def(Bytecodes::_iconst_2            , ____|____|____|____, vtos, itos, iconst              ,  2           );def(Bytecodes::_iconst_3            , ____|____|____|____, vtos, itos, iconst              ,  3           );def(Bytecodes::_iconst_4            , ____|____|____|____, vtos, itos, iconst              ,  4           );def(Bytecodes::_iconst_5            , ____|____|____|____, vtos, itos, iconst              ,  5           );def(Bytecodes::_lconst_0            , ____|____|____|____, vtos, ltos, lconst              ,  0           );def(Bytecodes::_lconst_1            , ____|____|____|____, vtos, ltos, lconst              ,  1           );def(Bytecodes::_fconst_0            , ____|____|____|____, vtos, ftos, fconst              ,  0           );def(Bytecodes::_fconst_1            , ____|____|____|____, vtos, ftos, fconst              ,  1           );def(Bytecodes::_fconst_2            , ____|____|____|____, vtos, ftos, fconst              ,  2           );def(Bytecodes::_dconst_0            , ____|____|____|____, vtos, dtos, dconst              ,  0           );def(Bytecodes::_dconst_1            , ____|____|____|____, vtos, dtos, dconst              ,  1           );def(Bytecodes::_bipush              , ubcp|____|____|____, vtos, itos, bipush              ,  _           );def(Bytecodes::_sipush              , ubcp|____|____|____, vtos, itos, sipush              ,  _           );def(Bytecodes::_ldc                 , ubcp|____|clvm|____, vtos, vtos, ldc                 ,  false       );def(Bytecodes::_ldc_w               , ubcp|____|clvm|____, vtos, vtos, ldc                 ,  true        );def(Bytecodes::_ldc2_w              , ubcp|____|clvm|____, vtos, vtos, ldc2_w              ,  _           );def(Bytecodes::_iload               , ubcp|____|clvm|____, vtos, itos, iload               ,  _           );def(Bytecodes::_lload               , ubcp|____|____|____, vtos, ltos, lload               ,  _           );def(Bytecodes::_fload               , ubcp|____|____|____, vtos, ftos, fload               ,  _           );def(Bytecodes::_dload               , ubcp|____|____|____, vtos, dtos, dload               ,  _           );def(Bytecodes::_aload               , ubcp|____|clvm|____, vtos, atos, aload               ,  _           );def(Bytecodes::_iload_0             , ____|____|____|____, vtos, itos, iload               ,  0           );def(Bytecodes::_iload_1             , ____|____|____|____, vtos, itos, iload               ,  1           );def(Bytecodes::_iload_2             , ____|____|____|____, vtos, itos, iload               ,  2           );def(Bytecodes::_iload_3             , ____|____|____|____, vtos, itos, iload               ,  3           );def(Bytecodes::_lload_0             , ____|____|____|____, vtos, ltos, lload               ,  0           );def(Bytecodes::_lload_1             , ____|____|____|____, vtos, ltos, lload               ,  1           );def(Bytecodes::_lload_2             , ____|____|____|____, vtos, ltos, lload               ,  2           );def(Bytecodes::_lload_3             , ____|____|____|____, vtos, ltos, lload               ,  3           );def(Bytecodes::_fload_0             , ____|____|____|____, vtos, ftos, fload               ,  0           );def(Bytecodes::_fload_1             , ____|____|____|____, vtos, ftos, fload               ,  1           );def(Bytecodes::_fload_2             , ____|____|____|____, vtos, ftos, fload               ,  2           );def(Bytecodes::_fload_3             , ____|____|____|____, vtos, ftos, fload               ,  3           );def(Bytecodes::_dload_0             , ____|____|____|____, vtos, dtos, dload               ,  0           );def(Bytecodes::_dload_1             , ____|____|____|____, vtos, dtos, dload               ,  1           );def(Bytecodes::_dload_2             , ____|____|____|____, vtos, dtos, dload               ,  2           );def(Bytecodes::_dload_3             , ____|____|____|____, vtos, dtos, dload               ,  3           );def(Bytecodes::_aload_0             , ubcp|____|clvm|____, vtos, atos, aload_0             ,  _           );def(Bytecodes::_aload_1             , ____|____|____|____, vtos, atos, aload               ,  1           );def(Bytecodes::_aload_2             , ____|____|____|____, vtos, atos, aload               ,  2           );def(Bytecodes::_aload_3             , ____|____|____|____, vtos, atos, aload               ,  3           );def(Bytecodes::_iaload              , ____|____|____|____, itos, itos, iaload              ,  _           );def(Bytecodes::_laload              , ____|____|____|____, itos, ltos, laload              ,  _           );def(Bytecodes::_faload              , ____|____|____|____, itos, ftos, faload              ,  _           );def(Bytecodes::_daload              , ____|____|____|____, itos, dtos, daload              ,  _           );def(Bytecodes::_aaload              , ____|____|____|____, itos, atos, aaload              ,  _           );def(Bytecodes::_baload              , ____|____|____|____, itos, itos, baload              ,  _           );def(Bytecodes::_caload              , ____|____|____|____, itos, itos, caload              ,  _           );def(Bytecodes::_saload              , ____|____|____|____, itos, itos, saload              ,  _           );def(Bytecodes::_istore              , ubcp|____|clvm|____, itos, vtos, istore              ,  _           );def(Bytecodes::_lstore              , ubcp|____|____|____, ltos, vtos, lstore              ,  _           );def(Bytecodes::_fstore              , ubcp|____|____|____, ftos, vtos, fstore              ,  _           );def(Bytecodes::_dstore              , ubcp|____|____|____, dtos, vtos, dstore              ,  _           );def(Bytecodes::_astore              , ubcp|____|clvm|____, vtos, vtos, astore              ,  _           );def(Bytecodes::_istore_0            , ____|____|____|____, itos, vtos, istore              ,  0           );def(Bytecodes::_istore_1            , ____|____|____|____, itos, vtos, istore              ,  1           );def(Bytecodes::_istore_2            , ____|____|____|____, itos, vtos, istore              ,  2           );def(Bytecodes::_istore_3            , ____|____|____|____, itos, vtos, istore              ,  3           );def(Bytecodes::_lstore_0            , ____|____|____|____, ltos, vtos, lstore              ,  0           );def(Bytecodes::_lstore_1            , ____|____|____|____, ltos, vtos, lstore              ,  1           );def(Bytecodes::_lstore_2            , ____|____|____|____, ltos, vtos, lstore              ,  2           );def(Bytecodes::_lstore_3            , ____|____|____|____, ltos, vtos, lstore              ,  3           );def(Bytecodes::_fstore_0            , ____|____|____|____, ftos, vtos, fstore              ,  0           );def(Bytecodes::_fstore_1            , ____|____|____|____, ftos, vtos, fstore              ,  1           );def(Bytecodes::_fstore_2            , ____|____|____|____, ftos, vtos, fstore              ,  2           );def(Bytecodes::_fstore_3            , ____|____|____|____, ftos, vtos, fstore              ,  3           );def(Bytecodes::_dstore_0            , ____|____|____|____, dtos, vtos, dstore              ,  0           );def(Bytecodes::_dstore_1            , ____|____|____|____, dtos, vtos, dstore              ,  1           );def(Bytecodes::_dstore_2            , ____|____|____|____, dtos, vtos, dstore              ,  2           );def(Bytecodes::_dstore_3            , ____|____|____|____, dtos, vtos, dstore              ,  3           );def(Bytecodes::_astore_0            , ____|____|____|____, vtos, vtos, astore              ,  0           );def(Bytecodes::_astore_1            , ____|____|____|____, vtos, vtos, astore              ,  1           );def(Bytecodes::_astore_2            , ____|____|____|____, vtos, vtos, astore              ,  2           );def(Bytecodes::_astore_3            , ____|____|____|____, vtos, vtos, astore              ,  3           );def(Bytecodes::_iastore             , ____|____|____|____, itos, vtos, iastore             ,  _           );def(Bytecodes::_lastore             , ____|____|____|____, ltos, vtos, lastore             ,  _           );def(Bytecodes::_fastore             , ____|____|____|____, ftos, vtos, fastore             ,  _           );def(Bytecodes::_dastore             , ____|____|____|____, dtos, vtos, dastore             ,  _           );def(Bytecodes::_aastore             , ____|____|clvm|____, vtos, vtos, aastore             ,  _           );def(Bytecodes::_bastore             , ____|____|____|____, itos, vtos, bastore             ,  _           );def(Bytecodes::_castore             , ____|____|____|____, itos, vtos, castore             ,  _           );def(Bytecodes::_sastore             , ____|____|____|____, itos, vtos, sastore             ,  _           );def(Bytecodes::_pop                 , ____|____|____|____, vtos, vtos, pop                 ,  _           );def(Bytecodes::_pop2                , ____|____|____|____, vtos, vtos, pop2                ,  _           );def(Bytecodes::_dup                 , ____|____|____|____, vtos, vtos, dup                 ,  _           );def(Bytecodes::_dup_x1              , ____|____|____|____, vtos, vtos, dup_x1              ,  _           );def(Bytecodes::_dup_x2              , ____|____|____|____, vtos, vtos, dup_x2              ,  _           );def(Bytecodes::_dup2                , ____|____|____|____, vtos, vtos, dup2                ,  _           );def(Bytecodes::_dup2_x1             , ____|____|____|____, vtos, vtos, dup2_x1             ,  _           );def(Bytecodes::_dup2_x2             , ____|____|____|____, vtos, vtos, dup2_x2             ,  _           );def(Bytecodes::_swap                , ____|____|____|____, vtos, vtos, swap                ,  _           );def(Bytecodes::_iadd                , ____|____|____|____, itos, itos, iop2                , add          );def(Bytecodes::_ladd                , ____|____|____|____, ltos, ltos, lop2                , add          );def(Bytecodes::_fadd                , ____|____|____|____, ftos, ftos, fop2                , add          );def(Bytecodes::_dadd                , ____|____|____|____, dtos, dtos, dop2                , add          );def(Bytecodes::_isub                , ____|____|____|____, itos, itos, iop2                , sub          );def(Bytecodes::_lsub                , ____|____|____|____, ltos, ltos, lop2                , sub          );def(Bytecodes::_fsub                , ____|____|____|____, ftos, ftos, fop2                , sub          );def(Bytecodes::_dsub                , ____|____|____|____, dtos, dtos, dop2                , sub          );def(Bytecodes::_imul                , ____|____|____|____, itos, itos, iop2                , mul          );def(Bytecodes::_lmul                , ____|____|____|____, ltos, ltos, lmul                ,  _           );def(Bytecodes::_fmul                , ____|____|____|____, ftos, ftos, fop2                , mul          );def(Bytecodes::_dmul                , ____|____|____|____, dtos, dtos, dop2                , mul          );def(Bytecodes::_idiv                , ____|____|____|____, itos, itos, idiv                ,  _           );def(Bytecodes::_ldiv                , ____|____|____|____, ltos, ltos, ldiv                ,  _           );def(Bytecodes::_fdiv                , ____|____|____|____, ftos, ftos, fop2                , div          );def(Bytecodes::_ddiv                , ____|____|____|____, dtos, dtos, dop2                , div          );def(Bytecodes::_irem                , ____|____|____|____, itos, itos, irem                ,  _           );def(Bytecodes::_lrem                , ____|____|____|____, ltos, ltos, lrem                ,  _           );def(Bytecodes::_frem                , ____|____|____|____, ftos, ftos, fop2                , rem          );def(Bytecodes::_drem                , ____|____|____|____, dtos, dtos, dop2                , rem          );def(Bytecodes::_ineg                , ____|____|____|____, itos, itos, ineg                ,  _           );def(Bytecodes::_lneg                , ____|____|____|____, ltos, ltos, lneg                ,  _           );def(Bytecodes::_fneg                , ____|____|____|____, ftos, ftos, fneg                ,  _           );def(Bytecodes::_dneg                , ____|____|____|____, dtos, dtos, dneg                ,  _           );def(Bytecodes::_ishl                , ____|____|____|____, itos, itos, iop2                , shl          );def(Bytecodes::_lshl                , ____|____|____|____, itos, ltos, lshl                ,  _           );def(Bytecodes::_ishr                , ____|____|____|____, itos, itos, iop2                , shr          );def(Bytecodes::_lshr                , ____|____|____|____, itos, ltos, lshr                ,  _           );def(Bytecodes::_iushr               , ____|____|____|____, itos, itos, iop2                , ushr         );def(Bytecodes::_lushr               , ____|____|____|____, itos, ltos, lushr               ,  _           );def(Bytecodes::_iand                , ____|____|____|____, itos, itos, iop2                , _and         );def(Bytecodes::_land                , ____|____|____|____, ltos, ltos, lop2                , _and         );def(Bytecodes::_ior                 , ____|____|____|____, itos, itos, iop2                , _or          );def(Bytecodes::_lor                 , ____|____|____|____, ltos, ltos, lop2                , _or          );def(Bytecodes::_ixor                , ____|____|____|____, itos, itos, iop2                , _xor         );def(Bytecodes::_lxor                , ____|____|____|____, ltos, ltos, lop2                , _xor         );def(Bytecodes::_iinc                , ubcp|____|clvm|____, vtos, vtos, iinc                ,  _           );def(Bytecodes::_i2l                 , ____|____|____|____, itos, ltos, convert             ,  _           );def(Bytecodes::_i2f                 , ____|____|____|____, itos, ftos, convert             ,  _           );def(Bytecodes::_i2d                 , ____|____|____|____, itos, dtos, convert             ,  _           );def(Bytecodes::_l2i                 , ____|____|____|____, ltos, itos, convert             ,  _           );def(Bytecodes::_l2f                 , ____|____|____|____, ltos, ftos, convert             ,  _           );def(Bytecodes::_l2d                 , ____|____|____|____, ltos, dtos, convert             ,  _           );def(Bytecodes::_f2i                 , ____|____|____|____, ftos, itos, convert             ,  _           );def(Bytecodes::_f2l                 , ____|____|____|____, ftos, ltos, convert             ,  _           );def(Bytecodes::_f2d                 , ____|____|____|____, ftos, dtos, convert             ,  _           );def(Bytecodes::_d2i                 , ____|____|____|____, dtos, itos, convert             ,  _           );def(Bytecodes::_d2l                 , ____|____|____|____, dtos, ltos, convert             ,  _           );def(Bytecodes::_d2f                 , ____|____|____|____, dtos, ftos, convert             ,  _           );def(Bytecodes::_i2b                 , ____|____|____|____, itos, itos, convert             ,  _           );def(Bytecodes::_i2c                 , ____|____|____|____, itos, itos, convert             ,  _           );def(Bytecodes::_i2s                 , ____|____|____|____, itos, itos, convert             ,  _           );def(Bytecodes::_lcmp                , ____|____|____|____, ltos, itos, lcmp                ,  _           );def(Bytecodes::_fcmpl               , ____|____|____|____, ftos, itos, float_cmp           , -1           );def(Bytecodes::_fcmpg               , ____|____|____|____, ftos, itos, float_cmp           ,  1           );def(Bytecodes::_dcmpl               , ____|____|____|____, dtos, itos, double_cmp          , -1           );def(Bytecodes::_dcmpg               , ____|____|____|____, dtos, itos, double_cmp          ,  1           );def(Bytecodes::_ifeq                , ubcp|____|clvm|____, itos, vtos, if_0cmp             , equal        );def(Bytecodes::_ifne                , ubcp|____|clvm|____, itos, vtos, if_0cmp             , not_equal    );def(Bytecodes::_iflt                , ubcp|____|clvm|____, itos, vtos, if_0cmp             , less         );def(Bytecodes::_ifge                , ubcp|____|clvm|____, itos, vtos, if_0cmp             , greater_equal);def(Bytecodes::_ifgt                , ubcp|____|clvm|____, itos, vtos, if_0cmp             , greater      );def(Bytecodes::_ifle                , ubcp|____|clvm|____, itos, vtos, if_0cmp             , less_equal   );def(Bytecodes::_if_icmpeq           , ubcp|____|clvm|____, itos, vtos, if_icmp             , equal        );def(Bytecodes::_if_icmpne           , ubcp|____|clvm|____, itos, vtos, if_icmp             , not_equal    );def(Bytecodes::_if_icmplt           , ubcp|____|clvm|____, itos, vtos, if_icmp             , less         );def(Bytecodes::_if_icmpge           , ubcp|____|clvm|____, itos, vtos, if_icmp             , greater_equal);def(Bytecodes::_if_icmpgt           , ubcp|____|clvm|____, itos, vtos, if_icmp             , greater      );def(Bytecodes::_if_icmple           , ubcp|____|clvm|____, itos, vtos, if_icmp             , less_equal   );def(Bytecodes::_if_acmpeq           , ubcp|____|clvm|____, atos, vtos, if_acmp             , equal        );def(Bytecodes::_if_acmpne           , ubcp|____|clvm|____, atos, vtos, if_acmp             , not_equal    );def(Bytecodes::_goto                , ubcp|disp|clvm|____, vtos, vtos, _goto               ,  _           );def(Bytecodes::_jsr                 , ubcp|disp|____|____, vtos, vtos, jsr                 ,  _           ); // result is not an oop, so do not transition to atosdef(Bytecodes::_ret                 , ubcp|disp|____|____, vtos, vtos, ret                 ,  _           );def(Bytecodes::_tableswitch         , ubcp|disp|____|____, itos, vtos, tableswitch         ,  _           );def(Bytecodes::_lookupswitch        , ubcp|disp|____|____, itos, itos, lookupswitch        ,  _           );def(Bytecodes::_ireturn             , ____|disp|clvm|____, itos, itos, _return             , itos         );def(Bytecodes::_lreturn             , ____|disp|clvm|____, ltos, ltos, _return             , ltos         );def(Bytecodes::_freturn             , ____|disp|clvm|____, ftos, ftos, _return             , ftos         );def(Bytecodes::_dreturn             , ____|disp|clvm|____, dtos, dtos, _return             , dtos         );def(Bytecodes::_areturn             , ____|disp|clvm|____, atos, atos, _return             , atos         );def(Bytecodes::_return              , ____|disp|clvm|____, vtos, vtos, _return             , vtos         );def(Bytecodes::_getstatic           , ubcp|____|clvm|____, vtos, vtos, getstatic           , f1_byte      );def(Bytecodes::_putstatic           , ubcp|____|clvm|____, vtos, vtos, putstatic           , f2_byte      );def(Bytecodes::_getfield            , ubcp|____|clvm|____, vtos, vtos, getfield            , f1_byte      );def(Bytecodes::_putfield            , ubcp|____|clvm|____, vtos, vtos, putfield            , f2_byte      );def(Bytecodes::_invokevirtual       , ubcp|disp|clvm|____, vtos, vtos, invokevirtual       , f2_byte      );def(Bytecodes::_invokespecial       , ubcp|disp|clvm|____, vtos, vtos, invokespecial       , f1_byte      );def(Bytecodes::_invokestatic        , ubcp|disp|clvm|____, vtos, vtos, invokestatic        , f1_byte      );def(Bytecodes::_invokeinterface     , ubcp|disp|clvm|____, vtos, vtos, invokeinterface     , f1_byte      );def(Bytecodes::_invokedynamic       , ubcp|disp|clvm|____, vtos, vtos, invokedynamic       , f1_byte      );def(Bytecodes::_new                 , ubcp|____|clvm|____, vtos, atos, _new                ,  _           );def(Bytecodes::_newarray            , ubcp|____|clvm|____, itos, atos, newarray            ,  _           );def(Bytecodes::_anewarray           , ubcp|____|clvm|____, itos, atos, anewarray           ,  _           );def(Bytecodes::_arraylength         , ____|____|____|____, atos, itos, arraylength         ,  _           );def(Bytecodes::_athrow              , ____|disp|____|____, atos, vtos, athrow              ,  _           );def(Bytecodes::_checkcast           , ubcp|____|clvm|____, atos, atos, checkcast           ,  _           );def(Bytecodes::_instanceof          , ubcp|____|clvm|____, atos, itos, instanceof          ,  _           );def(Bytecodes::_monitorenter        , ____|disp|clvm|____, atos, vtos, monitorenter        ,  _           );def(Bytecodes::_monitorexit         , ____|____|clvm|____, atos, vtos, monitorexit         ,  _           );def(Bytecodes::_wide                , ubcp|disp|____|____, vtos, vtos, wide                ,  _           );def(Bytecodes::_multianewarray      , ubcp|____|clvm|____, vtos, atos, multianewarray      ,  _           );def(Bytecodes::_ifnull              , ubcp|____|clvm|____, atos, vtos, if_nullcmp          , equal        );def(Bytecodes::_ifnonnull           , ubcp|____|clvm|____, atos, vtos, if_nullcmp          , not_equal    );def(Bytecodes::_goto_w              , ubcp|____|clvm|____, vtos, vtos, goto_w              ,  _           );def(Bytecodes::_jsr_w               , ubcp|____|____|____, vtos, vtos, jsr_w               ,  _           );// wide Java spec bytecodesdef(Bytecodes::_iload               , ubcp|____|____|iswd, vtos, itos, wide_iload          ,  _           );def(Bytecodes::_lload               , ubcp|____|____|iswd, vtos, ltos, wide_lload          ,  _           );def(Bytecodes::_fload               , ubcp|____|____|iswd, vtos, ftos, wide_fload          ,  _           );def(Bytecodes::_dload               , ubcp|____|____|iswd, vtos, dtos, wide_dload          ,  _           );def(Bytecodes::_aload               , ubcp|____|____|iswd, vtos, atos, wide_aload          ,  _           );def(Bytecodes::_istore              , ubcp|____|____|iswd, vtos, vtos, wide_istore         ,  _           );def(Bytecodes::_lstore              , ubcp|____|____|iswd, vtos, vtos, wide_lstore         ,  _           );def(Bytecodes::_fstore              , ubcp|____|____|iswd, vtos, vtos, wide_fstore         ,  _           );def(Bytecodes::_dstore              , ubcp|____|____|iswd, vtos, vtos, wide_dstore         ,  _           );def(Bytecodes::_astore              , ubcp|____|____|iswd, vtos, vtos, wide_astore         ,  _           );def(Bytecodes::_iinc                , ubcp|____|____|iswd, vtos, vtos, wide_iinc           ,  _           );def(Bytecodes::_ret                 , ubcp|disp|____|iswd, vtos, vtos, wide_ret            ,  _           );def(Bytecodes::_breakpoint          , ubcp|disp|clvm|____, vtos, vtos, _breakpoint         ,  _           );// JVM bytecodesdef(Bytecodes::_fast_agetfield      , ubcp|____|____|____, atos, atos, fast_accessfield    ,  atos        );def(Bytecodes::_fast_bgetfield      , ubcp|____|____|____, atos, itos, fast_accessfield    ,  itos        );def(Bytecodes::_fast_cgetfield      , ubcp|____|____|____, atos, itos, fast_accessfield    ,  itos        );def(Bytecodes::_fast_dgetfield      , ubcp|____|____|____, atos, dtos, fast_accessfield    ,  dtos        );def(Bytecodes::_fast_fgetfield      , ubcp|____|____|____, atos, ftos, fast_accessfield    ,  ftos        );def(Bytecodes::_fast_igetfield      , ubcp|____|____|____, atos, itos, fast_accessfield    ,  itos        );def(Bytecodes::_fast_lgetfield      , ubcp|____|____|____, atos, ltos, fast_accessfield    ,  ltos        );def(Bytecodes::_fast_sgetfield      , ubcp|____|____|____, atos, itos, fast_accessfield    ,  itos        );def(Bytecodes::_fast_aputfield      , ubcp|____|____|____, atos, vtos, fast_storefield ,   atos        );def(Bytecodes::_fast_bputfield      , ubcp|____|____|____, itos, vtos, fast_storefield ,   itos        );def(Bytecodes::_fast_zputfield      , ubcp|____|____|____, itos, vtos, fast_storefield ,   itos        );def(Bytecodes::_fast_cputfield      , ubcp|____|____|____, itos, vtos, fast_storefield  ,  itos        );def(Bytecodes::_fast_dputfield      , ubcp|____|____|____, dtos, vtos, fast_storefield  ,  dtos        );def(Bytecodes::_fast_fputfield      , ubcp|____|____|____, ftos, vtos, fast_storefield  ,  ftos        );def(Bytecodes::_fast_iputfield      , ubcp|____|____|____, itos, vtos, fast_storefield  ,  itos        );def(Bytecodes::_fast_lputfield      , ubcp|____|____|____, ltos, vtos, fast_storefield  ,  ltos        );def(Bytecodes::_fast_sputfield      , ubcp|____|____|____, itos, vtos, fast_storefield  ,  itos        );def(Bytecodes::_fast_aload_0        , ____|____|____|____, vtos, atos, aload               ,  0           );def(Bytecodes::_fast_iaccess_0      , ubcp|____|____|____, vtos, itos, fast_xaccess        ,  itos        );def(Bytecodes::_fast_aaccess_0      , ubcp|____|____|____, vtos, atos, fast_xaccess        ,  atos        );def(Bytecodes::_fast_faccess_0      , ubcp|____|____|____, vtos, ftos, fast_xaccess        ,  ftos        );def(Bytecodes::_fast_iload          , ubcp|____|____|____, vtos, itos, fast_iload          ,  _       );def(Bytecodes::_fast_iload2         , ubcp|____|____|____, vtos, itos, fast_iload2         ,  _       );def(Bytecodes::_fast_icaload        , ubcp|____|____|____, vtos, itos, fast_icaload        ,  _       );def(Bytecodes::_fast_invokevfinal   , ubcp|disp|clvm|____, vtos, vtos, fast_invokevfinal   , f2_byte      );def(Bytecodes::_fast_linearswitch   , ubcp|disp|____|____, itos, vtos, fast_linearswitch   ,  _           );def(Bytecodes::_fast_binaryswitch   , ubcp|disp|____|____, itos, vtos, fast_binaryswitch   ,  _           );def(Bytecodes::_fast_aldc           , ubcp|____|clvm|____, vtos, atos, fast_aldc           ,  false       );def(Bytecodes::_fast_aldc_w         , ubcp|____|clvm|____, vtos, atos, fast_aldc           ,  true        );def(Bytecodes::_return_register_finalizer , ____|disp|clvm|____, vtos, vtos, _return       ,  vtos        );def(Bytecodes::_invokehandle        , ubcp|disp|clvm|____, vtos, vtos, invokehandle        , f1_byte      );def(Bytecodes::_nofast_getfield     , ubcp|____|clvm|____, vtos, vtos, nofast_getfield     , f1_byte      );def(Bytecodes::_nofast_putfield     , ubcp|____|clvm|____, vtos, vtos, nofast_putfield     , f2_byte      );def(Bytecodes::_nofast_aload_0      , ____|____|clvm|____, vtos, atos, nofast_aload_0      ,  _           );def(Bytecodes::_nofast_iload        , ubcp|____|clvm|____, vtos, itos, nofast_iload        ,  _           );def(Bytecodes::_shouldnotreachhere   , ____|____|____|____, vtos, vtos, shouldnotreachhere ,  _           );
}void TemplateInterpreterGenerator::set_entry_points(Bytecodes::Code code) {CodeletMark cm(_masm, Bytecodes::name(code), code);// initialize entry pointsassert(_unimplemented_bytecode    != NULL, "should have been generated before");assert(_illegal_bytecode_sequence != NULL, "should have been generated before");address bep = _illegal_bytecode_sequence;address zep = _illegal_bytecode_sequence;address cep = _illegal_bytecode_sequence;address sep = _illegal_bytecode_sequence;address aep = _illegal_bytecode_sequence;address iep = _illegal_bytecode_sequence;address lep = _illegal_bytecode_sequence;address fep = _illegal_bytecode_sequence;address dep = _illegal_bytecode_sequence;address vep = _unimplemented_bytecode;address wep = _unimplemented_bytecode;// code for short & wide version of bytecodeif (Bytecodes::is_defined(code)) {Template* t = TemplateTable::template_for(code);assert(t->is_valid(), "just checking");set_short_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep);}if (Bytecodes::wide_is_defined(code)) {Template* t = TemplateTable::template_for_wide(code);assert(t->is_valid(), "just checking");set_wide_entry_point(t, wep);}// set entry pointsEntryPoint entry(bep, zep, cep, sep, aep, iep, lep, fep, dep, vep);Interpreter::_normal_table.set_entry(code, entry);Interpreter::_wentry_point[code] = wep;
}void TemplateInterpreterGenerator::set_short_entry_points(Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep) {assert(t->is_valid(), "template must exist");switch (t->tos_in()) {case btos:case ztos:case ctos:case stos:ShouldNotReachHere();  // btos/ctos/stos should use itos.break;case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break;case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break;case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break;case ftos: vep = __ pc(); __ pop(ftos); fep = __ pc(); generate_and_dispatch(t); break;case dtos: vep = __ pc(); __ pop(dtos); dep = __ pc(); generate_and_dispatch(t); break;case vtos: set_vtos_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep);     break;default  : ShouldNotReachHere();                                                 break;}
}void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) {if (PrintBytecodeHistogram)                                    histogram_bytecode(t);
#ifndef PRODUCT// debugging codeif (CountBytecodes || TraceBytecodes || StopInterpreterAt > 0) count_bytecode();if (PrintBytecodePairHistogram)                                histogram_bytecode_pair(t);if (TraceBytecodes)                                            trace_bytecode(t);if (StopInterpreterAt > 0)                                     stop_interpreter_at();__ verify_FPU(1, t->tos_in());
#endif // !PRODUCTint step = 0;if (!t->does_dispatch()) {step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode());if (tos_out == ilgl) tos_out = t->tos_out();// compute bytecode sizeassert(step > 0, "just checkin'");// setup stuff for dispatching next bytecodeif (ProfileInterpreter && VerifyDataPointer&& MethodData::bytecode_has_profile(t->bytecode())) {__ verify_method_data_pointer();}__ dispatch_prolog(tos_out, step);}// generate templatet->generate(_masm);// advanceif (t->does_dispatch()) {
#ifdef ASSERT// make sure execution doesn't go beyond this point if code is broken__ should_not_reach_here();
#endif // ASSERT} else {// dispatch to next bytecode__ dispatch_epilog(tos_out, step);}// std::cout << "@@@@yym%%%%" << "::generate_and_dispatch" << "----end" << std::endl;
}void InterpreterMacroAssembler::dispatch_epilog(TosState state, int step) {dispatch_next(state, step);
}//
// Generic interpreted method entry to (asm) interpreter
//
address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {// determine code generation flagsbool inc_counter  = UseCompiler || CountCompiledCalls || LogTouchedMethods;// ebx: Method*// rbcp: sender spaddress entry_point = __ pc();const Address constMethod(rbx, Method::const_offset());const Address access_flags(rbx, Method::access_flags_offset());const Address size_of_parameters(rdx,ConstMethod::size_of_parameters_offset());const Address size_of_locals(rdx, ConstMethod::size_of_locals_offset());// get parameter size (always needed)__ movptr(rdx, constMethod);__ load_unsigned_short(rcx, size_of_parameters);// rbx: Method*// rcx: size of parameters// rbcp: sender_sp (could differ from sp+wordSize if we were called via c2i )__ load_unsigned_short(rdx, size_of_locals); // get size of locals in words__ subl(rdx, rcx); // rdx = no. of additional locals// YYY
//   __ incrementl(rdx);
//   __ andl(rdx, -2);// see if we've got enough room on the stack for locals plus overhead.generate_stack_overflow_check();//yym-gaizao// #ifdef DEBUG_PRINT_METHOD_NAME// ---yym--- 打印代码移动到堆栈检查之后{// 保存寄存器状态__ push(rax);__ push(rcx);__ push(rdx);__ push(rdi);__ push(rsi);__ push(r8);__ push(r9);__ push(r10);__ push(r11);NOT_LP64(__ get_thread(r15_thread));__ push(r15);// 准备调用参数__ movptr(rdi, rbx);    // Method* 作为第一个参数__ lea(rsi, Address(rsp, 14*wordSize)); // 原始rsp地址__ mov(r8, rcx);        // 参数大小__ mov(r9, rdx);        // 本地变量大小// 调用调试信息输出函数__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, ::TemplateInterpreterGenerator::print_debug_info)));// 恢复寄存器__ pop(r15);NOT_LP64(__ restore_thread(r15_thread));__ pop(r11);__ pop(r10);__ pop(r9);__ pop(r8);__ pop(rsi);__ pop(rdi);__ pop(rdx);__ pop(rcx);__ pop(rax);}// #endif// get return address__ pop(rax);// compute beginning of parameters__ lea(rlocals, Address(rsp, rcx, Interpreter::stackElementScale(), -wordSize));// rdx - # of additional locals// allocate space for locals// explicitly initialize locals{Label exit, loop;__ testl(rdx, rdx);__ jcc(Assembler::lessEqual, exit); // do nothing if rdx <= 0__ bind(loop);__ push((int) NULL_WORD); // initialize local variables__ decrementl(rdx); // until everything initialized__ jcc(Assembler::greater, loop);__ bind(exit);}// initialize fixed part of activation framegenerate_fixed_frame(false);// make sure method is not native & not abstract
#ifdef ASSERT__ movl(rax, access_flags);{Label L;__ testl(rax, JVM_ACC_NATIVE);__ jcc(Assembler::zero, L);__ stop("tried to execute native method as non-native");__ bind(L);}{Label L;__ testl(rax, JVM_ACC_ABSTRACT);__ jcc(Assembler::zero, L);__ stop("tried to execute abstract method in interpreter");__ bind(L);}
#endif// Since at this point in the method invocation the exception// handler would try to exit the monitor of synchronized methods// which hasn't been entered yet, we set the thread local variable// _do_not_unlock_if_synchronized to true. The remove_activation// will check this flag.const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);NOT_LP64(__ get_thread(thread));const Address do_not_unlock_if_synchronized(thread,in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()));__ movbool(do_not_unlock_if_synchronized, true);__ profile_parameters_type(rax, rcx, rdx);// increment invocation count & check for overflowLabel invocation_counter_overflow;if (inc_counter) {generate_counter_incr(&invocation_counter_overflow);}Label continue_after_compile;__ bind(continue_after_compile);// check for synchronized interpreted methodsbang_stack_shadow_pages(false);// reset the _do_not_unlock_if_synchronized flagNOT_LP64(__ get_thread(thread));__ movbool(do_not_unlock_if_synchronized, false);// check for synchronized methods// Must happen AFTER invocation_counter check and stack overflow check,// so method is not locked if overflows.if (synchronized) {// Allocate monitor and lock methodlock_method();} else {// no synchronization necessary
#ifdef ASSERT{Label L;__ movl(rax, access_flags);__ testl(rax, JVM_ACC_SYNCHRONIZED);__ jcc(Assembler::zero, L);__ stop("method needs synchronization");__ bind(L);}
#endif}// start execution
#ifdef ASSERT{Label L;const Address monitor_block_top (rbp,frame::interpreter_frame_monitor_block_top_offset * wordSize);__ movptr(rax, monitor_block_top);__ cmpptr(rax, rsp);__ jcc(Assembler::equal, L);__ stop("broken stack frame setup in interpreter");__ bind(L);}
#endif// jvmti support__ notify_method_entry();__ dispatch_next(vtos);// invocation counter overflowif (inc_counter) {// Handle overflow of counter and compile method__ bind(invocation_counter_overflow);generate_counter_overflow(continue_after_compile);}return entry_point;
}void InterpreterMacroAssembler::dispatch_next(TosState state, int step, bool generate_poll) {// load next bytecode (load before advancing _bcp_register to prevent AGI)load_unsigned_byte(rbx, Address(_bcp_register, step));// advance _bcp_registerincrement(_bcp_register, step);dispatch_base(state, Interpreter::dispatch_table(state), true, generate_poll);
}void InterpreterMacroAssembler::dispatch_base(TosState state,address* table,bool verifyoop,bool generate_poll) {verify_FPU(1, state);if (VerifyActivationFrameSize) {Label L;mov(rcx, rbp);subptr(rcx, rsp);int32_t min_frame_size =(frame::link_offset - frame::interpreter_frame_initial_sp_offset) *wordSize;cmpptr(rcx, (int32_t)min_frame_size);jcc(Assembler::greaterEqual, L);stop("broken stack frame");bind(L);}if (verifyoop) {interp_verify_oop(rax, state);}address* const safepoint_table = Interpreter::safept_table(state);
#ifdef _LP64Label no_safepoint, dispatch;if (table != safepoint_table && generate_poll) {NOT_PRODUCT(block_comment("Thread-local Safepoint poll"));testb(Address(r15_thread, JavaThread::polling_word_offset()), SafepointMechanism::poll_bit());jccb(Assembler::zero, no_safepoint);lea(rscratch1, ExternalAddress((address)safepoint_table));jmpb(dispatch);}bind(no_safepoint);lea(rscratch1, ExternalAddress((address)table));bind(dispatch);jmp(Address(rscratch1, rbx, Address::times_8));#elseAddress index(noreg, rbx, Address::times_ptr);if (table != safepoint_table && generate_poll) {NOT_PRODUCT(block_comment("Thread-local Safepoint poll"));Label no_safepoint;const Register thread = rcx;get_thread(thread);testb(Address(thread, JavaThread::polling_word_offset()), SafepointMechanism::poll_bit());jccb(Assembler::zero, no_safepoint);ArrayAddress dispatch_addr(ExternalAddress((address)safepoint_table), index);jump(dispatch_addr);bind(no_safepoint);}{ArrayAddress dispatch_addr(ExternalAddress((address)table), index);jump(dispatch_addr);}
#endif // _LP64
}static address*   dispatch_table(TosState state)              { return _active_table.table_for(state); }void TemplateInterpreter::initialize_code() {AbstractInterpreter::initialize();TemplateTable::initialize();// generate interpreter{ ResourceMark rm;TraceTime timer("Interpreter generation", TRACETIME_LOG(Info, startuptime));TemplateInterpreterGenerator g(_code);// Free the unused memory not occupied by the interpreter and the stubs_code->deallocate_unused_tail();}if (PrintInterpreter) {ResourceMark rm;print();}// initialize dispatch table_active_table = _normal_table;
}

相关文章:

  • 从零开始了解数据采集(三十)——什么是工业AI?
  • Git将本地文件推送到GitHub仓库
  • 十大UI测试工具
  • 基于Java项目的Karate UI测试
  • innodb 数据页结构
  • MH2213 32位Arm® Cortex®-M3 Core核心并内嵌闪存和SRAM
  • 认识 Python 【适合0基础】
  • Java 中高级开发岗技能与面试要点梳理
  • STL 4函数对象
  • 前端6月份之前的部分技术更新记录
  • 创始人IP打造:创客匠人的实战经验与启示
  • 编译原理 学习 2025年6月10日11:17:54
  • MongoDB 基础
  • RAG文档解析难点2:excel数据“大海捞针”,超大Excel解析与精准行列查询指南
  • 如何查看电脑系统启动时间?
  • spring cloud
  • VQA新突破:零样本推理与多智能体策略引领看图回答新时代
  • 论文解析:一文弄懂Vision Transformer!
  • SaaS(软件即服务)和 PaaS(平台即服务)的定义及区别(服务对象不同、管理责任边界、典型应用场景)
  • 计算机基础(一):ASCll、GB2312、GBK、Unicode、UTF-32、UTF-16、UTF-8深度解析
  • 长沙市建设委员会网站/什么是seo关键词优化
  • dede拷贝其他网站文章/南宁网站seo大概多少钱
  • 如何使用c 进行网站开发/传统营销与网络营销的区别
  • 给别人做网站去掉版权/百度快速收录3元一条
  • 桐城网站定制/百度推广方式有哪些
  • 怎么做游戏网站编辑/快速提升网站排名