重构 J2V8 编译

AI 摘要围绕升级 J2V8 与适配新版本 V8,梳理程序内存、编译与链接等基础知识。

J2V8 是一个 Java 控制 V8 的工具,可惜里面的 V8 引擎已经过时了,我们需要修改它的代码来迎合最新版本的 V8。

前置知识

什么是程序

从操作系统的角度来看,程序在内存中包含:Kernel Space、Stack、Mmap、Heap、BSS Segment、Data Segment、Text Segment。

重要知识点:

  1. 计算机设计中,全部具体的内存会被映射成为一个一维线性空间
  2. 对于任何一个程序,都采取虚拟内存,程序与程序是相互隔离的

不妨把可执行文件理解成程序在内存中的映射的说明文件。线程之间的内存是共享的,而进程间通过需要复制数据到 kernel 空间来完成数据共享。

编译的过程

  • 编译:把编译单元(cpp文件)转换成二进制(obj文件)
  • 链接:把多个代码段或数据段合成一个

头文件是解决并行编译的关键钥匙——把函数签名提取出来,使用 include 指令告诉编译器。

库文件

  • 静态链接库:目标文件打包,链接时合并
  • 动态库:运行时才加载到内存中,以 dll 形式单独存在

什么是 JNI

通过 Java 程序访问 C++ 程序的接口。使用 System.loadLibrary 加载动态库,使用关键字 native 定义 native 方法。

V8

V8 是一组 cpp 代码,输入是 JS 字符串,输出是计算结果。经过词法分析和语法分析后,AST 有两个去处:字节码和机器码。

J2V8概述

步骤拆分:

  1. 把 V8 编译成一个静态库(v8_monolith.lib)
  2. 把 J2V8 的 Java 代码拷贝过来,修改不需要的
  3. Java 代码生成 cpp 头文件
  4. 根据 cpp 头文件实现函数,生成动态库
  5. 进行单元测试,打包成 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 搞崩。