尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
SpiderMonkey 的 iongraph:用 GraphViz 可视化 IonMonkey 优化图的完整指南
SpiderMonkey 的 iongraph用 GraphViz 可视化 IonMonkey 优化图的完整指南【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo本文基于 iongraph 官方文档 撰写并结合 SpiderMonkey 源码中 JIT Spew 子系统JitSpewer.cpp、JSONSpewer.cpp与 iongraph 工具本体 进行深度扩充。导读iongraph是 SpiderMonkeyMozilla 的 JavaScript 引擎内嵌于本仓库 MongoDB 的src/third_party/mozjs中自带的 IonMonkey 优化中间表示IR可视化工具它把 JIT 编译过程中产生的 MIR/LIR 图序列导出为 GraphViz 的 Dot 格式再渲染成 PDF/SVG/PNG帮助引擎开发者直观看到每次优化 pass 前后指令流与控制流的变化。读完本文你将掌握从 Debug 构建、IONFLAGSlogs采集日志到iongraph一键出图的完整工作流并能读懂输出图中每种颜色、线型、标注背后对应的 MIR 标志位含义。iongraph 是什么iongraph位于仓库的 devtools/iongraph 目录 下是一个 Python 3 脚本原名iongraph最初由 Sean Stangl 编写见目录内 LICENSE。其官方定位一句话即可概括Visualizer for IonMonkey graphs using GraphViz.它的工作本质是一条流水线采集以IONFLAGSlogs环境变量运行jsSpiderMonkey 的 shellIonMonkey 编译器在每一个优化 pass 前后把 MIR/LIR 图以 JSON 形式写到磁盘转换iongraph读取 JSON为每个 pass 构造两个 Dot 图MIR 一张、LIR 一张优先输出 LIR渲染调用 GraphViz 的dot程序把 Dot 图渲染成 PDF默认或 SVG/PNG并按函数/ pass 命名输出文件。在 iongraph 脚本 中可以看到完整的数据流json.loads(parenthesize(s))读取 JSON其中parenthesize()会在日志因崩溃而截断时补全缺失的闭合括号保证还能解析出已写完的部分随后buildGraphs(func)/buildOnlyFinalPass(func)构造 Dot 图最后由genfiles/genmergedpdfs调用dot渲染iongraph。环境要求与前置条件使用 iongraph 需要以下组件组件用途备注SpiderMonkeyDebug 构建的jsshell产出 IONFLAGS 日志官方 README 明确要求 debug build因为 JIT Spew 代码被#ifdef JS_JITSPEW包裹见 JitSpewer.cpp只有 debug 构建才启用GraphViz 的dot可执行文件渲染 Dot 图为最终格式缺失时脚本直接报错退出ERROR: graphviz (dot) is not installediongraphpdftk或qpdf仅当输出格式为合并的pdf时需要用于把单个函数的多个 pass 页面合并成一个 PDF不安装也可以改用--format pdfs生成每图一个 PDFiongraph此外日志默认写到/tmp/ion.jsonLinux/macOSWindows 上默认写到当前目录.Android 上写到/data/local/tmp这一默认值由 JitSpewer.cpp 中的JIT_SPEW_DIR宏决定。基本使用步骤第一步采集 IonMonkey 日志用IONFLAGSlogs环境变量运行一个 JS 模块IONFLAGSlogs js -m mymodule.mjsSpiderMonkey 会把编译过程中关于图状态的观测信息每个 pass 的 MIR/LIR、指令属性、ResumePoint、寄存器分配区间等dump 到/tmp/ion.json。第二步生成图iongraph此时工作目录下会为日志中的每个函数生成一个 PDF默认格式每个 pass 对应一页。两步合一iongraph js子命令为了方便iongraph 提供了js子命令把运行js与生成图合并为一次调用iongraph js -- -m mymodule.mjs以--为界--之前的参数属于iongraph--之后的参数原样传给js。例如只针对 1 号函数出图iongraph js --funcnum 1 -- -m mymodule.mjs从源码看js_and_gen会先把logs强制追加进IONFLAGS即使你只设了别的 flag 也会保证日志开启再执行js最后自动以/tmp/ion.json为输入调用生成流程iongraph。命令行参数详解以下参数定义来自 iongraph 脚本的add_main_arguments对顶层命令、js子命令与jit-test子命令都适用参数说明默认值-o, --outdir输出文件存放目录.当前目录-f, --funcnum只处理指定下标的函数多个用逗号分隔如1,5,234全部-n, --funcname只处理指定名字的函数多个用逗号分隔如foo,bar,baz全部-p, --passnum只处理指定序号的 pass多个用逗号分隔全部--format输出格式可选gv/pdf/pdfs/png/svgpdf--final只生成最终优化后的 MIR/LIR 图关--out-mir把选中的 MIR 图写入指定文件无--out-lir把选中的 LIR 图写入指定文件无input位置参数IonMonkey 生成的 JSON 日志路径/tmp/ion.json几个值得注意的行为细节pdf与pdfs的区别pdf会把每个函数的所有 pass 图合并成一个多页 PDF依赖pdftk/qpdfpdfs与其它格式一样每张图单独一个文件iongraph。默认输出策略每个 pass 通常只输出 MIR/LIR 中的一种优先 LIR因为 LIR 图不含后继信息绘制边时需要借助 MIR 图见下文原理。只有在--final模式下才同时输出 MIR 与 LIRiongraph。--funcnum与--passnum的下标函数序号取自 JSON 中functions数组的下标从 0 开始pass 序号同理。日志中没有指定函数时会提示abort during SSA construction正常则打印success; N passesiongraph。jit-test 子命令除了js子命令iongraph 还支持jit-test子命令可配合 SpiderMonkey 的jit_test.py运行单个测试用例并出图iongraph jit-test --funcnum 1 -- category/test.js它内部以js/src/jit-test/jit_test.py --one test的形式执行测试同样自动追加logs到IONFLAGSiongraph。输出文件命名与格式生成的 Dot 文件命名规则在 outputPass 函数 中定义funcNN-passNN-pass名-mir|lir.gv函数序号与 pass 序号都是两位补零如func01-pass03图名使用 pass 名如LICM、GVN等优化 pass 名称mir/lir后缀标明是 MIR 图还是 LIR 图。渲染后gv原样拷贝png/svg/pdf(s)调用dot -Tformat转换pdf模式再用pdftk/qpdf把同一函数的所有页面合并genmergedpdfs。生成的 Dot 图中图的标题标签是「函数名 - pass 名」并附带图例蓝色movable、下划线guard、红色in worklist、灰色recovered on bailoutiongraph。读懂输出图图形属性语义这一节是官方 README 的核心内容逐条对应到源码实现块Block的属性绿色边框limegreen循环头loop header。对应 JSON 中块的loopheader属性源码在 JSONSpewer.cpp 中由block-isLoopHeader()输出iongraph 据此给节点加color: limegreeniongraph。红色边框crimson包含循环回边loop backedge的块即其某个后继是循环头。对应 JSON 的backedge属性由block-isLoopBackedge()输出iongraph 给节点加color: crimsonJSONSpewer.cpp、iongraph。虚线边框dashed临界边分裂critical edge splitting过程中创建的块。对应splitedge属性由block-isSplitEdge()输出iongraph 给节点加style: dashedJSONSpewer.cpp、iongraph。此外块标签中还会显示块使用计数Count: N与上述属性的文字标注如(loop header)、(backedge)、(split edge)见 getBlockLabel。指令Instruction的属性蓝色可移动Movable指令。iongraph 在指令属性列表里检测到Movable时把指令名染成蓝色iongraph。下划线Guard守卫指令例如类型检查、边界检查等。检测到Guard属性时给指令名加下划线iongraph。红色仍在 worklist 中的指令InWorklistSSA 构建/处理期间的状态检测到该属性时染红iongraph。灰色gray50发生 bailout退出优化时被恢复RecoveredOnBailout的指令表示该指令的结果可以在遇到 bailout 时由 interpreter 重新计算无需保存在栈快照里iongraph。这些属性全部来自 MIR 定义上的标志位由 JSONSpewer.cpp 的spewMDef通过MIR_FLAG_LIST宏展开后逐个输出到 JSON 的attributes列表中。MResumePointMResumePoint 作为指令行呈现着色为灰色。每个 MResumePoint 保存了指令执行点处的环境快照用于 bailout 恢复与 OSR。JSON 中它以resumePoint字段出现包含caller内联调用者所属块、mode如At/After等来自ResumeModeToString以及按序排列的operands跨内联调用链时用|分隔见 JSONSpewer.cpp 的spewMResumePoint。iongraph 中 ResumePoint 行显示为resumepoint 操作数列表同样以灰色渲染getResumePointRow。块入口处的 ResumePoint 会出现在块顶部指令自带的 ResumePoint 则以At/After两种 mode 分别出现在指令前/后。边的标注以条件分支结尾的块其出边会用真值 0 或 1 标注。实现上当块有 2 个后继时指向successors[0]的边标1真分支指向successors[1]的边标0假分支iongraph。这对应控制流图中条件的布尔真值与 MIR 中分支指令的两个出边约定一致。关于 MIR 与 LIR 两套图每个 pass 会输出 MIR 与 LIR 两张候选图buildGraphsForPass。两者共享相同的块划分LIR 图不含后继successor信息因此绘制 LIR 图的边时直接复用 MIR 图中对应块的successors列表见 buildGraphForIR 的注释。这解释了为什么默认只输出 LIR 而非同时输出两张。底层原理JSON 日志是如何产生的日志的产生完全在 SpiderMonkey 侧与 iongraph 无关理解它有助于排查为什么没有输出的问题。IONFLAGS 环境变量IONFLAGS是逗号分隔的 flag 列表在 JitSpewer.cpp 的CheckLogging()中被解析。与 iongraph 相关的两个关键 flaglogs开启异步JSON 日志EnableIonDebugAsyncLogging。所谓异步是指每个 pass 的图先缓存在内存中到函数编译结束时才一次性写入文件对应 endFunction 中的 dump 时机。logs-sync开启同步日志EnableIonDebugSyncLogging。每个 pass 结束后立即 flush 到文件对应 spewPass这在编译中途崩溃时能保留更多现场但官方注释建议此时关闭 off-thread 编译。在 shell 中可用IONFLAGShelp js打印完整的 flag 列表其中包括logs JSON visualization logging与logs-sync Same as logs, but flushes between each pass等说明JitSpewer.cpp。输出文件与 JSON 结构文件路径固定为JIT_SPEW_DIR/ion.jsonLinux 上即/tmp/ion.json若设置了环境变量ION_SPEW_BY_PID则改为/tmp/ionpid.json便于多进程并行实验JitSpewer.cpp。文件顶层结构为{functions: [...]}JitSpewer.cpp 与析构时的\n]}收尾。每个函数条目由 JSONSpewer.cpp 写出beginFunction记录函数名格式为文件名:行号如mymodule.mjs:12并开启passes列表L21-L25每个 pass 记录name、mir块列表与lir块列表L33-L36、L134-L239MIR 块包含number、attributes、predecessors、successors、instructions、入口resumePointL138-L186每个 MIR 指令包含id、opcode、attributes、inputs操作数 id、uses使用方 id、memInputs内存依赖、typeMIRType含范围分析结果与截断标记(t)以及可选的resumePointL65-L132在带寄存器分配的 pass 中还会额外输出ranges记录每个虚拟寄存器vreg的活跃区间allocation、start、end这是回溯式寄存器分配器BacktrackingAllocator的输出L241-L282。IONFILTER只记录关心的函数日志可能极其庞大。环境变量IONFILTER提供了按源文件/行号过滤的机制值为逗号分隔的文件或文件:行号表达式只有匹配的函数才会被记录不匹配时计入filteredOutCompilations见 JitSpewer.cpp 的FilterContainsLocation。例如IONFILTERmymodule.mjs IONFLAGSlogs js -m mymodule.mjs典型调试工作流示例综合以上内容一个完整的端到端示例# 1) 只记录 mymodule.mjs 中的函数异步采集日志 IONFILTERmymodule.mjs IONFLAGSlogs js -m mymodule.mjs # 2) 只处理第 1 个函数、只生成最终优化后的 MIR/LIR输出为 SVG iongraph -f 1 --final --format svg # 3) 或一步到位先运行 js 再出图-- 后的参数传给 js iongraph js --funcnum 1 --format png -- -m mymodule.mjs # 4) 需要单页 PDF不依赖 pdftk/qpdf时 iongraph --format pdfs出图后在生成的func01-passNN-pass名-mir.gv或-lir.gv中绿框定位循环结构、红框定位回边、蓝字定位可移动指令、下划线定位守卫指令、灰色定位可恢复指令与 ResumePoint配合0/1边标注即可逐 pass 追踪优化前后的形态差异。局限与注意事项必须是 Debug 构建JitSpewer与JSONSpewer的实现都包裹在#ifdef JS_JITSPEW内JitSpewer.cpp、JSONSpewer.cppRelease 构建不会编译这些代码也不会有任何日志输出。日志默认路径固定为/tmp/ion.json可用ION_SPEW_BY_PID改为带 pid 的文件名若目录不可写或文件被占用init()会失败并返回 falseJitSpewer.cpp。合并 PDF 需要额外工具不装pdftk/qpdf时请改用--format pdfs否则脚本会报错退出。JSON 容错iongraph的parenthesize()会为崩溃截断的日志补全闭合括号尽量保住已生成的部分iongraph但它明确不处理转义字符串极端场景下可能解析失败。参考文件索引官方使用文档README.mdiongraph 工具本体Python 3iongraphIONFLAGS 解析与日志写出JitSpewer.cppJSON 图序列化MIR/LIR/ResumePoint/RangesJSONSpewer.cpp【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

IEC 101规约C语言实现:帧结构解析与南瑞RTU调试实战

IEC 101规约C语言实现:帧结构解析与南瑞RTU调试实战

简介:面向电力系统远动通信、RTU设备调试及IEC 60870-5-101规约初学者,这份来自南瑞工程现场的RTU101小工具压缩包,将规约文档与可运行源码整合在一起,帮助快速绕开协议细节的弯路。包内共有2个文件,1个cpp源码文件用于…

📅 2026/9/16 19:39:12
PESpin 脱壳实战:从查壳到 OEP 定位与 IAT 修复

PESpin 脱壳实战:从查壳到 OEP 定位与 IAT 修复

1. 先搞清楚"脱壳"这件事到底在做什么前阵子有个做客户端安全的朋友找我,说他手上一个早年的练习样本套了 PESpin 的壳,用调试器挂上去以后,入口点一看全是乱七八糟的跳转和垃圾指令,单步几下就不知道跑哪去了&#xff…

📅 2026/9/16 19:39:12
DICOM转PNG临床级转换:窗宽窗位与像素标定实战

DICOM转PNG临床级转换:窗宽窗位与像素标定实战

1. 为什么医生和影像工程师总在DICOM转图上反复踩坑?我第一次接手医院PACS系统对接项目时,被要求把2000张CT序列导出成JPG用于教学演示。当时想得很简单:用pydicom读出来,PIL转存不就完了?结果跑完发现——87%的图片全…

📅 2026/9/16 19:39:12
MORE NEWS

更多资讯

📰

WPS在Linux下打不开中文文件?KDE桌面启动器修复指南

如果你也是在 Arch Linux 上装 KDE 当主力桌面,又习惯用 WPS 打开同事发来的docx、xlsx、pptx,大概率迟早会撞见这个对话框:WPS 突然弹出来一句“无法找到“”。请检查文件名的拼写,并检查文件位置是否正确。”。我第一次看到的时…

📰

MATLAB实现改进型SEIR3疫情传播模型与参数敏感性分析

简介:本资源是一套面向流行病学建模研究者与公共卫生数据分析学习者的改进型SEIR疫情仿真方案,聚焦COVID-19传播动力学分析,提供可复现、可调参的MATLAB实现框架。压缩包共106个文件,含103份PDF技术文档(含全国每日疫情…

📰

Linux动态库undefined symbol定位与修复实战

上周三晚上十一点,同事在群里甩了一张截图,程序启动直接抛出error while loading shared libraries: libparse.so: undefined symbol: _Z8parse_docPKc,后面跟了一句:本地机器编得好好的,怎么一到部署环境就炸了。这种…

📰

OpenCV轮廓匹配实战:用Hu矩实现5分钟形状识别

开头先聊点实在的。做图像处理这些年,形状识别算是我被问到最多的需求之一:分拣线上的零件方向对不对、PCB板上的元件有没有放反、OCR之前先把目标区域定位出来……这些场景看起来五花八门,但落到OpenCV层面,核心思路高度一致——…

📰

基于ZYNQ的FPGA DDS信号发生器设计与实现

简介:面向FPGA开发者的ZYNQ7100 DDS信号发生器完整工程,主控芯片采用XC7Z100FFG900-2,基于Vivado环境开发实现。工程代码可直接编译运行,并支持向XC7Z100系列其他芯片移植,适合需要快速搭建任意波形发生器或学习ZYNQ平…

📰

内网HTTPS部署:用openssl自签名证书解决Chrome“不安全”提示

内网部署HTTPS:用openssl自签名证书,一次搞定Chrome“不安全”提示先说说我为什么折腾这事。公司内网有套业务系统,一直走HTTP,后来要对接一些对安全性有硬性要求的接口,加上审计也盯得紧,必须上HTTPS。公网…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬