feat(hotspot): 新增 --hotspot-sites 逐调用点计数并带源码 file:line

为匹配白名单的直接 call 点插桩 internal i64 __fhs_site_<K>(call 前 +1),计数天然包含循环内放大的真实执行次数,可把热点定位到具体调用点。

新增 --hotspot-callees 覆盖白名单、--hotspot-sites-all 全量;按去 16 位 sha1 前缀后的基名匹配。Ctrl+C 落盘独立文件 hotspot_sites.txt(# sites 分段,含调用方/被调方/计数/源码位置),按计数降序;不破坏既有 hotspot.txt 格式。

在 AST->IR 生成期由 _HotspotSiteBuilder 为每条新生成的 call 指令轻量挂载 _src_file/_src_line,插桩时作为可选尾字段输出;取不到则留空不伪造。开关关闭时改用原生 ir.IRBuilder,零影响。
This commit is contained in:
TermiNexus committed 2026-09-13 23:29:32 +08:00
1 parent 0ffaadc95e
commit 2021c0edb7
11 files changed
+567 -25

No files matched your search

+36
View File
@@ -340,6 +340,30 @@ class TransPyC:
else:
error('--func-hotspot requires an argument')
sys.exit(1)
elif sys.argv[I] == '--hotspot-sites':
# 调用点热点统计:可选路径(省略时默认 hotspot_sites.txt,运行期由
# 处理器按计数降序写入)。空串表示"已启用但未给路径"。
if I + 1 < len(sys.argv) and not sys.argv[I + 1].startswith('-'):
self.Args['HotspotSites'] = sys.argv[I + 1]
I += 2
else:
self.Args['HotspotSites'] = ''
I += 1
elif sys.argv[I].startswith('--hotspot-callees='):
# --hotspot-sites 白名单覆盖(逗号分隔的基名)
self.Args['HotspotCallees'] = sys.argv[I][len('--hotspot-callees='):]
I += 1
elif sys.argv[I] == '--hotspot-callees':
if I + 1 < len(sys.argv):
self.Args['HotspotCallees'] = sys.argv[I + 1]
I += 2
else:
error('--hotspot-callees requires an argument')
sys.exit(1)
elif sys.argv[I] == '--hotspot-sites-all':
# --hotspot-sites 对全部直接 call 点插桩(忽略白名单)
self.Args['HotspotSitesAll'] = True
I += 1
else:
error(f'Unknown argument {sys.argv[I]}')
sys.exit(1)
@@ -607,6 +631,18 @@ class TransPyC:
# 函数热点统计(--func-hotspot):绑定到翻译器;未传时为 None(零影响)
self.translator.FuncHotspotFile = self.Args.get('FuncHotspot')
# 调用点热点统计(--hotspot-sites):None=未启用(零影响);''=启用但未给
# 路径(默认 hotspot_sites.txt)。注册走种子单模块路径(main 入口注册)。
HotspotSites: str | None = self.Args.get('HotspotSites')
if HotspotSites is not None:
if HotspotSites == '':
HotspotSites = 'hotspot_sites.txt'
self.translator.HotspotSitesFile = os.path.abspath(HotspotSites)
self.translator.HotspotSitesAll = bool(self.Args.get('HotspotSitesAll'))
HotspotCallees: str | None = self.Args.get('HotspotCallees')
if HotspotCallees:
self.translator.HotspotCallees = [c.strip() for c in HotspotCallees.split(',') if c.strip()]
# 检查是否有预处理符号文件的请求
if 'PreSym' in self.Args:
PresymConfig: dict[str, Any] = self.Args['PreSym']