重构 J2V8 编译
AI 摘要围绕升级 J2V8 与适配新版本 V8,梳理程序内存、编译与链接等基础知识。
J2V8 是一个 Java 控制 V8 的工具,可惜里面的 V8 引擎已经过时了,我们需要修改它的代码来迎合最新版本的 V8。
前置知识
什么是程序
从操作系统的角度来看,程序在内存中包含:Kernel Space、Stack、Mmap、Heap、BSS Segment、Data Segment、Text Segment。
重要知识点:
- 计算机设计中,全部具体的内存会被映射成为一个一维线性空间
- 对于任何一个程序,都采取虚拟内存,程序与程序是相互隔离的
不妨把可执行文件理解成程序在内存中的映射的说明文件。线程之间的内存是共享的,而进程间通过需要复制数据到 kernel 空间来完成数据共享。
编译的过程
- 编译:把编译单元(cpp文件)转换成二进制(obj文件)
- 链接:把多个代码段或数据段合成一个
头文件是解决并行编译的关键钥匙——把函数签名提取出来,使用 include 指令告诉编译器。
库文件
- 静态链接库:目标文件打包,链接时合并
- 动态库:运行时才加载到内存中,以 dll 形式单独存在
什么是 JNI
通过 Java 程序访问 C++ 程序的接口。使用 System.loadLibrary 加载动态库,使用关键字 native 定义 native 方法。
V8
V8 是一组 cpp 代码,输入是 JS 字符串,输出是计算结果。经过词法分析和语法分析后,AST 有两个去处:字节码和机器码。
J2V8概述
步骤拆分:
- 把 V8 编译成一个静态库(v8_monolith.lib)
- 把 J2V8 的 Java 代码拷贝过来,修改不需要的
- Java 代码生成 cpp 头文件
- 根据 cpp 头文件实现函数,生成动态库
- 进行单元测试,打包成 jar 包
环境安装
- Windows: Visual Studio + C++ 开发工具
- Linux/Mac: gcc + g++
- cmake 工具
- VPN(命令行需要单独配置代理)
- depot_tools(V8 编译工具链)
V8 的编译
mkdir v8 && cd v8
fetch v8
gn args out.cl/x64.release.sample
ninja -C out.cl/x64.release.sample
建议 gcc 版本使用 9 以上,且使用较低的 glibc。
编译动态链接库
已写好 cmake 脚本,支持 Mac M1、WindowsX86、LinuxX86。
打包成 jar 包
通过 gradle 脚本打包,每个平台的动态链接库打包到一个 jar 里。通过了 1000 个测试用例。
Glibc
glibc 是 GNU C Library,提供程序运行时所需的基本功能。V8 引擎对 Glibc 版本有一定要求。升级有风险,很容易把 linux 搞崩。