TypePHP 编译器
https://swoole.com/aot/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
6.1 KiB
76 lines
6.1 KiB
# 2026-08-03 工作日志
|
|
|
|
## TypePHP 编译性能分析(docs/COMPILATION_PERFORMANCE_ANALYSIS.md)
|
|
|
|
**任务**:分析编译实现、提升编译速度、评估 mago 替代 AST 解析。
|
|
|
|
**编译管线**(4 阶段):
|
|
1. prepare:扫描+parse(#1)+符号表+拓扑排序(SourcePipelineTrait::prepare → Preprocessor::prepareFile)
|
|
2. convert:parse(#2,重复)+NodeTraverser+生成 C++(Translator::doConvert)
|
|
3. compile:PCH + pcntl 并行(Windows 串行)
|
|
4. build:链接
|
|
|
|
**实测瓶颈**(src/ 139 文件,php-parser 5.6.1):
|
|
- 解析吞吐仅 3.18 MB/s,单遍 parse+resolve ≈ 599ms
|
|
- **每个 PHP 文件解析两次**(prepare + convert)→ 纯 PHP 解析 ~1.2s 起步
|
|
- 生成 .cc 无增量缓存(只有 phpx misc 有),writeFile 无内容比对 → mtime 必变触发全量重编
|
|
- prepare/convert 串行;Windows 无 pcntl 串行编译
|
|
- AST serialize 体积膨胀 28.8 倍(47.6MB/1.65MB),unserialize 260ms vs parse+resolve 599ms(快 2.3 倍)
|
|
|
|
**提速方案**(按 ROI):
|
|
- S1(P0) prepare/convert 合并单次解析(AST 内存/磁盘缓存)
|
|
- S2(P0) 生成 .cc 增量对象缓存 + writeFile 内容比对(key 须含公共声明头)
|
|
- S3(P0) PCH/misc 指纹轻量化(mtime 先行,内容 hash 兜底)
|
|
- S4(P1) 解析阶段 pcntl 并行
|
|
- S5(P1) Windows 并行(Msvc /MP 或 proc_open)
|
|
- S7(P2) 合并多次 NodeFinder 全树扫描
|
|
|
|
**mago 评估结论:不建议替换**。mago 是 Rust 的 PHP 工具链(lint/format/analyze),AST 是 Rust 结构 + CST 模型,与 TypePHP 深度耦合的 php-parser API(296 处引用/75 文件,依赖 NodeTraverser/NameResolver/ConstExprEvaluator/PrettyPrinter/attribute 机制)不兼容。JSON 桥接或 FFI 的成本会吃掉解析速度优势。合理定位:前置语法预检或未来原生前端路线参考。
|
|
|
|
**产物**:docs/COMPILATION_PERFORMANCE_ANALYSIS.md(完整报告)、.workbuddy/bench_ast.php(可复现基准脚本)
|
|
|
|
## 实施 S1+S2(下午追加)
|
|
|
|
**S1 合并两次解析**:
|
|
- `CompilerBase` 新增 `parseCachedAst()`(按 `$this->file` 缓存原始 AST)+ `cloneAst()`(CloningVisitor 深拷贝)
|
|
- `prepareFile()` 与 `doConvert()` 都改用它 → 每个文件只 parse 一次
|
|
- 关键约束:`RuntimeAttributeFactoryLowering`/`Visitor` 是有状态 visitor(会向 AST 追加节点),**同一棵 AST 不能二次遍历**,必须返回深拷贝
|
|
|
|
**S2 增量缓存**:
|
|
- `writeFile()` 内容比对:相同不覆盖,返回 bool(mtime 稳定,防头文件抖动)
|
|
- 新增 `hasGeneratedObjectFileCache()`:key = sha256(编译命令 + PHP ABI + 生成的 func_decl.h/data_decl.h/_arginfo.h 内容 hash)
|
|
- `isGeneratedSourceFile()`:buildDir 前缀 + .cc 扩展判断
|
|
- `compileFile()` 对生成的 .cc 走缓存;`save()`/`genExtension()` 仅实际写入时 format
|
|
- 注意:extension-<target>.cc **不应**列入 header 依赖(内容随任何类变化,会让所有 .cc 全量失效)
|
|
|
|
**实测**(302 文件合成项目,dry,3 次均值):
|
|
- 全量:基线 6011ms → 改动后 5629ms(-6.4%)
|
|
- 增量(不清理 build,第 3 次):5023ms(-16.4% 相对基线冷构建)
|
|
- dry 不含 C++ 编译,S2 完整收益需在 build 场景验证
|
|
|
|
**环境/验证要点**:
|
|
- 本机完整编译需要 `PHP_HOME=D:/git/php/tpc_v1095_windows_x86_64`(含 php8embed.lib、SDK/lib/php8ts.lib、phpx/)+ 复制 `tpc_v1095/phpx.dll` 到 `phpx/build/phpx.dll`
|
|
- `tpc_v1095/tpc.exe` 是编译自 `D:\workspace\compiler` 的二进制,本机无法运行(内嵌路径不符)
|
|
- typephp-think(554 文件)补丁后 prepare 通过,convert 阶段 `Cannot re-assign` 是仓库源码类型系统比 v1095 正式版严格(`$str` array→str),非本次改动问题
|
|
- **git 事故**:git stash 失败损坏 refs(HEAD→speed_build 指向 a92fc0df 对象缺失)。已恢复:分支指向 18decac(可用 commit),onepiece-doudizhu 示例内容在暂存区完好。备份在 `.git-backup-20260803/`,确认后删除
|
|
|
|
## git 恢复与提交(下午追加 2)
|
|
|
|
- **git stash 事故根因确认**:stash 失败不仅丢 refs,还导致 onepiece-doudizhu-win32 全部 19 个文件的 blob 对象缺失(index 引用了不存在的对象)。工作区文件完好。
|
|
- **恢复方法**:`git reset -- <dir>` 取消暂存 → `git add <dir>`(从工作区重建 blob)→ commit。已恢复为 `449afc1 add onepiece-ddz game example`(4226 行,与原提交同名)。
|
|
- **S1/S2 已提交**:`ac7813d perf: cache AST across prepare/convert and add generated object cache`(3 文件 +206/-14)。
|
|
- **最终 git fsck = 0 missing,仓库健康**。
|
|
- 遗留:`.git-backup-20260803/`(18MB,git 事故备份,确认后删)、`.workbuddy/onepiece-backup/`(文件级备份,可删)。
|
|
|
|
## code-wiki 文档生成(2026-08-04)
|
|
|
|
- 为 aot-compiler 生成了中文 AI Wiki:22 页,7 个章节(概览 / 前端解析 / 类型系统 / 代码生成 / 后端构建 / 优化性能 / 运行时边界)。
|
|
- **重要修正**:code-wiki skill 的文档写 `<workspace>/.agents/wiki/`,但 `scripts/render.py` 实际读取 `<workspace>/.workbuddy/wiki/`(`wiki_dir = os.path.join(workspace, ".workbuddy", "wiki")`)。写 catalog.xml / pages 必须放 `.workbuddy/wiki/`,否则 render 报 "catalog.xml not found"。
|
|
- 产物:`D:\git\php\aot-compiler\.workbuddy\wiki/index.html`(左侧目录导航 + 右侧 iframe,离线 Mermaid)。render 命令:`python <skill>/scripts/render.py render <workspace> --lang zh`。
|
|
|
|
## 环境结论(重要)
|
|
|
|
- **本机 MSVC 工具链不完整**:cl.exe + C++ 标准库头存在(`C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC/14.44.35207/include/cstring`),但 **Windows SDK(Windows Kits 目录)完全缺失** → 无法完成真实 C++ 编译链接,只能验证到 dry 模式(prepare+convert+生成 .cc)。
|
|
- `tpc_v1095_windows_x86_64` 是完整 PHP 构建环境:php8embed.lib、SDK/lib/php8ts.lib、phpx/(含 lib/phpx.lib);phpx.dll 需复制到 `phpx/build/phpx.dll` 才能通过校验。
|
|
- 完整编译需在装有 Windows SDK 的机器执行(用户原编译机)。
|
|
|
|
|