From ac77287f20b63c1abd8f8ffd722cad3b3b7034db Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Mon, 14 Sep 2026 14:40:30 +0800 Subject: [PATCH] =?UTF-8?q?fix(phase2):=20=E7=83=AD=E7=82=B9=E6=8F=92?= =?UTF-8?q?=E6=A1=A9=E5=BC=BA=E5=88=B6=E9=87=8D=E8=AF=91=E6=97=B6=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=E5=A4=B1=E6=95=88=E6=97=A7=E7=9B=AE=E6=A0=87=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 启用 --hotspot-sites 时会跳过 .ll 与 .stub.ll+.text.ll 两个缓存分支而强制重译,但既有的 {sha1}.obj 未被清理:_compile_ll_files 的三处跳过判定只按 obj 是否存在(收集阶段、_compile_one、need_compile 二次过滤),会复用上一次未插桩的目标文件,导致部分模块的热点计时/计数静默缺失、其耗时被计入调用者 self。 在 App 源文件主循环内,hotspot_on 为真时先删除对应 {sha1}.obj;用未缓存的 os.path.isfile 判定而非 _CachedIsFile,避免把已存在写入只写存在性缓存后被删除、使后续三处判定读到过期值而漏编;删除失败仅告警不中断、不静默吞错。 该循环遍历全部可达源文件且本轮所有文件都进入 need_translate(串行与批处理共享同一列表),故覆盖本轮全部被强制重译的模块。未启用时整块被跳过,行为逐字节不变。 --- lib/Projectrans/Phase2Translator.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/Projectrans/Phase2Translator.py b/lib/Projectrans/Phase2Translator.py index 44fa4b2..ef7bfce 100644 --- a/lib/Projectrans/Phase2Translator.py +++ b/lib/Projectrans/Phase2Translator.py @@ -917,6 +917,22 @@ class Phase2Translator: raise _vlog().warning(f"收集源文件导入的 include 模块失败: {_e}", "Exception") + # --hotspot-sites:上面两个缓存/重组分支在 hotspot_on 时被跳过, + # 本轮每个模块都会强制重译 .ll;此时必须让旧的 {sha1}.obj 一并失效, + # 否则 _compile_ll_files 会因 .obj 已存在而跳过重编,复用上一次未插桩 + # 的目标文件,导致部分模块热点计时/计数静默缺失、耗时被计入调用者 self。 + # 这里用 os.path.isfile 而非 _CachedIsFile:避免把"已存在"写进存在性 + # 缓存后又被本函数删除,使后续 _compile_ll_files 读到过期缓存而漏编。 + if hotspot_on: + obj_path = os.path.join(self.output_dir, f"{sha1}.obj") + if os.path.isfile(obj_path): + try: + os.remove(obj_path) + except OSError as e: + # 不中断构建,但真实错误(如权限不足)必须打印告警,不静默吞掉 + _vlog().warning( + f"Phase2Translator: 删除热点插桩模块的旧目标文件失败: {obj_path}: {e}") + if not hotspot_on and _CachedIsFile(out_path): deps_changed = self._check_deps_changed(sha1, current_ModuleSha1Map) if not deps_changed: