QEMU/TCG 翻译块

复用已翻译的机器代码块

QEMU TCG 用 QHT 保存 TranslationBlock 索引,帮助复用与当前客体执行状态一致的翻译结果。

v9.2.0缓存与复用核验 2026-10-08
相关概念

工程问题#

重复翻译相同代码会浪费时间,但只按 PC 判断相同又不够:执行模式、标志和代码页信息也会影响翻译结果。

实际实现#

tb_htable_init 初始化可自动扩容的 QHT;tb_cmp 比较 TB 的相关属性。QHT 查找需要 RCU 读侧保护,删除对象需遵守延迟释放规则。

处理流程#

  1. 由执行上下文形成查询键
  2. 在 QHT 查找并比较完整属性
  3. 命中后复用翻译块
  4. 代码失效时移除相关索引

源码片段#

固定版本 · 原文摘录
accel/tcg/tb-maint.cv9.2.0 · L46–L64
查看原文件
46static bool tb_cmp(const void *ap, const void *bp)47{48    const TranslationBlock *a = ap;49    const TranslationBlock *b = bp;5051    return ((tb_cflags(a) & CF_PCREL || a->pc == b->pc) &&52            a->cs_base == b->cs_base &&53            a->flags == b->flags &&54            (tb_cflags(a) & ~CF_INVALID) == (tb_cflags(b) & ~CF_INVALID) &&55            tb_page_addr0(a) == tb_page_addr0(b) &&56            tb_page_addr1(a) == tb_page_addr1(b));57}5859void tb_htable_init(void)60{61    unsigned int mode = QHT_MODE_AUTO_RESIZE;6263    qht_init(&tb_ctx.htable, tb_cmp, CODE_GEN_HTABLE_SIZE, mode);64}
tb_cmp / tb_htable_init

QHT 初始化显式传入完整 TB 比较函数,并启用自动扩容。哈希命中后仍比较执行标志和代码页地址;CF_PCREL 允许跳过 PC 相等检查。此片段证明索引和等价判定,RCU 查找与失效处理在其他函数中。

收益与取舍#

工程分析

带来的收益

  • 减少重复翻译与编译开销
  • 读侧机制适配并发查询

付出的代价

  • 工程分析:哈希冲突仍需做完整比较
  • 失效传播与对象释放协议增加复杂度

可比较的选择

仅按 PC 的直接缓存访问路径更短,但容量、冲突和执行上下文区分需要额外处理。

版本与适用范围#

对应 QEMU TCG 动态翻译路径;KVM 执行客体代码的主要路径不依赖这套 TCG 翻译块缓存。

参考来源#

源码、官方文档与原始论文
01
qemu · tb_htable_init / tb_cmp

accel/tcg/tb-maint.c · tb_htable_init / tb_cmp

源码v9.2.0
02
qemu · qht_lookup / qht_remove

include/qemu/qht.h · qht_lookup / qht_remove

源码v9.2.0

相关实现与比较#

4 个相关案例
4 个匹配案例