diff --git a/lib/Projectrans/Phase2Translator.py b/lib/Projectrans/Phase2Translator.py index ef7bfce..bcf3913 100644 --- a/lib/Projectrans/Phase2Translator.py +++ b/lib/Projectrans/Phase2Translator.py @@ -2715,6 +2715,12 @@ class Phase2Translator: sorted_files, file_deps = self._sort_include_files_by_deps(self.extra_py_files) _vlog().info(f"\n[includes 编译] 找到 {len(sorted_files)} 个 Python 源文件") + # --hotspot-sites:include 模块同样被插桩(hotspot_sites_file 经 worker 透传), + # 故启用时必须让旧 .obj 失效并强制重译,否则会复用上一次未插桩的目标文件, + # 使 include 模块的热点计数/计时 IR 静默缺失。未启用时 hotspot_on=False, + # 本函数行为与改动前逐字节一致(零影响)。 + hotspot_on: bool = bool(self.hotspot_sites_file) + # 构建 include 文件的模块 SHA1 映射(预计算所有文件,构建完整映射) include_ModuleSha1Map = self._build_current_ModuleSha1Map(None) need_translate = [] # [(src_path, sha1, module_name, ll_path, obj_path, precompiled_obj)] @@ -2753,6 +2759,21 @@ class Phase2Translator: self._collect_inline_symbols(src_path) continue + # --hotspot-sites:include 的 .py 未变时下面两处会因旧 .obj 存在而直接跳过, + # 复用上一次可能未插桩的目标文件。启用热点时先让这两类旧 .obj 一并失效, + # 使其必然走入 need_translate 重新翻译并嵌入热点计数/计时 IR。 + # 用 os.path.isfile 而非 _CachedIsFile:避免把"已存在"写入存在性缓存后又被 + # 本处删除,使下面两处判定读到过期缓存而漏编(与 App 主循环同一写法)。 + if hotspot_on: + for _stale_obj in (precompiled_obj, obj_path): + if _stale_obj and os.path.isfile(_stale_obj): + try: + os.remove(_stale_obj) + except OSError as e: + # 不中断构建,但真实错误(如权限不足)必须打印告警,不静默吞掉 + _vlog().warning( + f"Phase2Translator: 删除热点插桩 include 模块的旧目标文件失败: {_stale_obj}: {e}") + # 优先检查 includes.binary 预编译缓存(跨项目共享) if not self.force_recompile_includes and precompiled_obj and _CachedIsFile(precompiled_obj): _vlog().info(f" 跳过(预编译): {module_name}.py -> {os.path.basename(precompiled_obj)}")