Skip to content

test(jit): add x86_64 JIT unit test suite#151

Closed
CN-TangLin wants to merge 5 commits into
qmonnet:mainfrom
CN-TangLin:feat/jit-tests
Closed

test(jit): add x86_64 JIT unit test suite#151
CN-TangLin wants to merge 5 commits into
qmonnet:mainfrom
CN-TangLin:feat/jit-tests

Conversation

@CN-TangLin

Copy link
Copy Markdown

问题

当前 JIT 后端没有单元测试,无法在 CI 中验证 x86_64 代码生成的正确性。

变更内容

  • src/jit_x86_64.rs:新增 #[cfg(test)] mod tests(+159 行),包含 6 个单元测试

测试用例

  1. test_alu_add32:验证 ADD32_IMM 生成 add eax 编码(81 c0 ii ii ii ii)
  2. test_alu_sub64:验证 SUB64_IMM 生成 sub rax 编码(48 81 e8 ii ii ii ii)
  3. test_bpf_end_be16:验证 BE16 生成 ROL+mask 序列(66 c1 c0 08 + 81 e0 ff ff 00 00)
  4. test_jmp_ja:验证无条件跳转生成 e9 编码且偏移为正
  5. test_ldx_stx:验证 STXDW/LDXDW 生成 48 89 45 f8 / 48 8b 7d f8
  6. test_prologue_epilogue:验证完整栈帧 push/pop 序列和 push_rbp < pop_r15 顺序

测试基础设施

  • make_jit_memory:在 Vec 缓冲区上构造 JitMemory,兼容 std/no_std
  • compile:编译 eBPF 字节码并返回生成的机器码
  • contains_subsequence:字节序列匹配辅助函数

验证

cargo test --lib 全部 123 测试通过,cargo clippy 无警告。

依赖

本 PR 包含 #148#149#150 的提交,应在 #150 合并后审查。

Add a RISC-V 64-bit JIT compiler (RiscV64Compiler) based on the existing
x86_64 JitCompiler pattern. The backend supports the full eBPF instruction
set for 64-bit RISC-V targets, using a three-field relocation scheme
(pc_locs / jumps / special_targets) consistent with the existing x86_64
compiler.

Refactor JitMemory::new() to use #[cfg(target_arch)] dispatch so both
x86_64 and riscv64 backends coexist. Make the jit module public so users
can call JitMemory::new() directly for custom executable memory control,
which is required for integration into OS kernels or custom runtimes.

The module remains private on Windows where executable memory allocation
is not supported.
Add a new AArch64 JIT compiler (Aarch64Compiler) that translates eBPF
bytecode to native AArch64 machine code. The backend follows the same
pattern as the existing RiscV64Compiler:

- Single-pass compilation with pc_locs/jumps/special_targets relocation
- All A64 instruction encodings (ADD/SUB/AND/ORR/EOR/MADD/UDIV, UBFM/SBFM
  for shifts, LDR/STR variants, STP/LDP for frame management, conditional
  and unconditional branches)
- BPF_END handled via native REV16/REV32/REV64 instructions
- Full ALU32/ALU64, LDX/ST/STX, JMP32/JMP64, CALL, and EXIT support
- Register mapping: BPF R0-R5 → x0-x5, BPF R6-R9 → x19-x22, BPF R10 → x25
- Frame: 512-byte BPF stack + 64-byte callee-saved area (x19-x22,x25,x29,x30)

Integrated into JitMemory::new() via #[cfg(target_arch = "aarch64")]
dispatch, matching the existing x86_64 and riscv64 patterns.
Add 6 unit tests covering ALU ops, BPF_END byte swap, unconditional jump,
memory load/store, and prologue/epilogue sequences.
@qmonnet

qmonnet commented Jun 13, 2026

Copy link
Copy Markdown
Owner
  • Please try to write in English if you can, I can't read Chinese.

  • There's no point in opening 4 Pull Requests if they all contain an incremental number of stacked commits. You can 1) open one Pull Request with all five commits, like this one, or 2) open the 4 Pull Requests, but without stacking commits from other Pull Requests, and then dealing with merge conflicts, if any, or 3) base your Pull Requests on your own branches, although I guess this option doesn't work well until your branches are in this repo.

  • You still haven't replied to my question, about whether the existing JIT could satisfy your use case. I was hesitant to take one new JIT-compiler, now you come back with two at once! Who's going to maintain these?

  • What's the objective of the main commit in this particular Pull Request? The little I tried to translate says “The current JIT backend has no unit testing and cannot verify the correctness of the x86_64 code generation in CI”. We have 3,600+ lines of tests for the JIT in tests/ubpf_jit_x86_64.rs...?

@CN-TangLin

Copy link
Copy Markdown
Author

Thank you for the detailed feedback, and apologies for the late response and the Chinese descriptions.

I have reorganized everything into a single PR with 3 commits: #152. The stacked PRs (#148-151) have been closed.

To address your specific concerns:

  1. Regarding Cranelift vs. native backends: I have answered this in detail in the new PR description. In short — Cranelift is great for user-space, but native backends are needed for kernel/embedded integration (no_std, zero dependencies, caller-provided executable memory). They complement rather than replace each other.

  2. Regarding the test commit: You are right — the existing tests/ubpf_jit_x86_64.rs (3,600+ lines) is far more comprehensive. I have dropped the inline byte-level tests from this submission.

  3. Regarding maintainership: These backends are already used in the StarryOS kernel and we will maintain them. Happy to discuss any concerns further.

  4. Regarding writing in English: Done for all descriptions this time.

Please take a look at #152 when you get a chance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants