LuaJIT Bytecode结构布局

news/2024/11/19 8:24:43/

一、Bytecode的存储结构

LuaJIT的Bytecode位宽为32位,在parse阶段用结构体BCInsLine表示,ins表示32位长的字字节码指令,line表示字节码的行号:

typedef struct BCInsLine {BCIns ins;            /* Bytecode instruction. */BCLine line;          /* Line number for this bytecode. */
} BCInsLine;

parse阶段的Bytecode指令集被存放在一个BCInsLine类型的动态数组中,数组的初始sizeLJ_MIN_VECSZ(值为8),每次动态扩充的大小为 size<< 1,最大扩充至LJ_MAX_BCINS(1<<26)FuncState->bcbase指向数组的基地址。以下字节码parse时在内存中的存放方式如图所示:

0001    KSHORT   0 132
0002    GSET     0   0      ; "a"
0003    KSTR     0   1      ; "qwer"
0004    GSET     0   2      ; "str"
0005    GGET     0   0      ; "a"
0006    SUBVN    0   0   0  ; 1
0007    GSET     0   0      ; "a"
0008    RET0     0   1

在这里插入图片描述
等parse完成后,会将Bytecode指令集重新组织,放入一个BCIns 类型的数组中,数组的size为Bytecode指令的条数,基地址为(BCIns *)((char *)pt + sizeof(GCproto)),这一过程在lj_parse.c:fs_finish函数中。这么做的原因也就是让取指令操作具有一个良好的空间局部性,下图为Bytecode指令集放入重新组织的数组中的结构:
在这里插入图片描述
假设现在有两个寄存器PC和INS,PC存放Bytecode的地址,INS存放PC对应地址处的Bytecode值,则可以利用以下伪代码对Bytecode访问,其中code_base是存放Bytecode连续内存(数组)的首地址:

mov  PC  code_base
load  INS  [PC]
...
// set INS to next bytecode
add  PC  PC  4
load  INS  [PC]
...

二、Instruction dispatch table

DynASM会将vm_loongarch64.dasc中的汇编代码在预处理阶段变成二进制机器码,然后再使用内存映射将机器码映射到虚拟内存,等运行时便可以直接运行被映射的二进制代码。在lj_dispatch.h中有一个结构GG_State,定义如下:

typedef struct GG_State {lua_State L;                          /* Main thread. */global_State g;                       /* Global state. */
#if LJ_HASJITjit_State J;                          /* JIT state. */HotCount hotcount[HOTCOUNT_SIZE];     /* Hot counters. */
#endifASMFunction dispatch[GG_LEN_DISP];    /* Instruction dispatch tables. */BCIns bcff[GG_NUM_ASMFF];          /* Bytecode for ASM fast functions. */
} GG_State;

字段dispatch是一个ASMFunction数组,而ASMFunction是函数指针类型,是Bytecode指令对应的汇编函数。运行时被映射的二进制代码的地址(函数指针),存放在dispatch数组中,且数组的下标为BCOp(定义在lj_bc.h中),存放与其对应的汇编函数指针。如dispatch[BC_POW]中存放函数指针为vm_loongarch64.dasc:BC_POW函数在虚拟内存中的映射地址。

解释器在解释执行Lua原型(GCproto)生成Bytecode指令集时,如Bytecode的存储结构中的指令集。首先从GCfuncL->pc内存地址处中取出第一条Bytecode指令(BC_FUNCF rbase lit),取出该指令的opcode(BC_FUNCF),以opcode为index在dispatch中查找相应的函数指针,再执行相应的函数。等解释执行的逻辑完成,开始让PC指向下一条Bytecode指令,重复同样的过程。


http://www.ppmy.cn/news/404544.html

相关文章

JUC高级-0614

5.LockSupport与线程中断 5.1 线程中断 蚂蚁金服面试题&#xff1a;如何中等一个线程&#xff0c;如何停止一个线程什么是中断机制 首先&#xff1a;一个线程不应该由其他线程来强制中断或停止&#xff0c;而是应该由线程自己自行停止。所以&#xff0c;Thread.stop, Thread.…

el-table点击单元格变成输入框,以及其自动获取焦点失效可能的原因(focus失效)

1.el-table点击单元格变成输入框 这里主要使用了el-table三个自带的方法/属性&#xff1a; <el-table:data"MesTableData"bordercell-click"clickCell":row-class-name"tableRowClassName":cell-class-name"tableCellClassName" …

React基础教程(二):React的基本使用

React基础教程(二)&#xff1a;React的基本使用 1、HelloReact 1.1 引入react基础依赖包 注意点&#xff1a;①必须要在②之前引入 <!-- 引入react核心库--><script src"../js/react.development.js"></script><!-- 引入react-dom&…

给你一棵二叉树的根节点 root,翻转这棵二叉树,并返回其根节点

public class TreeNode {int val;TreeNode left;TreeNode right;TreeNode(){}TreeNode(int val){this.val val;}public TreeNode(int val, TreeNode left, TreeNode right) {this.val val;this.left left;this.right right;} } /* 递归的进行翻转 保存原来的右子树*/ publi…

OCR识别系列之一-----场景文字识别

另一种方法应用比较广的就是深度学习方法&#xff0c;深度学习方法是将OCR识别划分为文字检测和文本识别部分 &#xff0c;这也是深度学习技术可以充分发挥功效的地方。使用比较广泛的网络结构是Differentiable Binarization CRNN。 Differentiable Binarization简称DB&#…

EasyDL OCR文字识别

这个功能还是挺吊的&#xff0c;应用场景也不少。 定制识别图片中的文字信息&#xff0c;结构化输出关键字段内容&#xff0c;极大提升OCR模型训练效率&#xff0c;满 足个性化卡证票据识别需求&#xff1b;支持公有云服务、私有化部署多种使用方式。 说白了就是一个图片里有…

利用OCR识别图像中的英文和文字

一、Tesseract—OCR简介 将图片翻译成文字一般称为光学文字识别&#xff08;Optical Character Recognition,OCR&#xff09;。可以实现OCR的底层并不多&#xff0c;目前很多库都是实用共同的几个底层OCR库&#xff0c;或者是在上面进行定制。 Tesseract是一个OCR库&#xff0…

超轻量级中文ocr,OcrLiteOnnx文字识别

原项目地址&#xff1a;https://github.com/benjaminwan/OcrLiteOnnx 本文是基于原项目编译好后的OcrLiteOnnx文字识别系统&#xff0c;可以实现提取图片中的文字及文字中心点坐标等功能。 相较于Tesseract这个OCR来说文字识别的准确度要高很多&#xff0c;识别速度也会快&…