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.
42 lines
4.7 KiB
42 lines
4.7 KiB
<!doctype html><html lang="zh"><head><meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>增量编译缓存</title>
|
|
<script src="../script/mermaid.min.js"></script>
|
|
<script>document.addEventListener('DOMContentLoaded',function(){if(window.mermaid)mermaid.initialize({startOnLoad:true});});</script>
|
|
<style>
|
|
:root{--bg:#0f1117;--fg:#e6e6e6;--muted:#9aa0aa;--accent:#6ea8fe;--card:#171a21;--border:#262b36;}
|
|
*{box-sizing:border-box}
|
|
body{margin:0;font-family:-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif;background:var(--bg);color:var(--fg);line-height:1.65}
|
|
.wrap{max-width:900px;margin:0 auto;padding:32px 24px 80px}
|
|
h1,h2,h3{color:#fff;line-height:1.3;margin-top:1.6em}
|
|
h1{border-bottom:1px solid var(--border);padding-bottom:.3em}
|
|
a{color:var(--accent);text-decoration:none}
|
|
a:hover{text-decoration:underline}
|
|
code{background:#0b0d12;padding:.15em .4em;border-radius:4px;font-size:.9em}
|
|
pre{background:#0b0d12;border:1px solid var(--border);border-radius:8px;padding:14px;overflow:auto}
|
|
pre code{background:none;padding:0}
|
|
table{border-collapse:collapse;width:100%;margin:1em 0}
|
|
th,td{border:1px solid var(--border);padding:8px 10px;text-align:left}
|
|
th{background:var(--card)}
|
|
blockquote{border-left:3px solid var(--accent);margin:1em 0;padding:.2em 1em;color:var(--muted);background:var(--card)}
|
|
hr{border:none;border-top:1px solid var(--border);margin:2em 0}
|
|
</style></head>
|
|
<body><div class="wrap"><h1>增量编译缓存</h1>
|
|
<p>TypePHP 的二次编译速度,很大程度上取决于<strong>对象文件缓存是否命中</strong>。编译器对两类源文件做内容指纹缓存:phpx 的 <code>misc</code> 源,以及编译器自己生成的 <code>.cc</code> 单元。</p>
|
|
<p>Sources: <a href="file:///D:\git\php\aot-compiler\src\Translator.php#L1116-L1292">src/Translator.php</a></p>
|
|
<h2>两类缓存</h2>
|
|
<table><thead><tr><th>方法</th><th>适用对象</th><th>缓存键组成</th></tr></thead><tbody><tr><td><code>hasMiscObjectFileCache()</code></td><td><code>phpx/src/misc/*.cc</code></td><td>编译命令 + PHP ABI(<code>PHP_VERSION_ID</code> / <code>ZEND_MODULE_API_NO</code> / <code>PHP_ZTS</code> / <code>PHP_INT_SIZE</code> 等)+ phpx 头文件 mtime</td></tr><tr><td><code>hasGeneratedObjectFileCache()</code></td><td>构建目录下的生成 <code>.cc</code></td><td>编译命令 + PHP ABI + <strong>所有生成头文件内容指纹</strong>(<code>func_decl.h</code> / <code>data_decl.h</code> / 各 <code>_arginfo.h</code>)</td></tr></tbody></table>
|
|
<p>Sources: <a href="file:///D:\git\php\aot-compiler\src\Translator.php#L1116-L1160">src/Translator.php</a> · <a href="file:///D:\git\php\aot-compiler\src\Translator.php#L1207-L1240">src/Translator.php</a></p>
|
|
<h2>缓存键构造</h2>
|
|
<pre><code>hash('sha256',
|
|
buildCompileFileCommand(source, object) // 可复现的编译命令行
|
|
. "\0" . serialize($abi) // PHP ABI 快照
|
|
[. "\0" . header . "\0" . hash_file(header)] // 仅生成单元:逐头文件内容
|
|
)</code></pre>
|
|
<p>键写入 <code><object>.typephp-cache</code> 元数据文件(<code>getMiscObjectCacheMetadataFile()</code>)。每次 <code>compileFile()</code> 先比较元数据文件中的键,再比较 <code>.o</code> 与源/头的 mtime——<strong>任一不满足即失效并重编译</strong>。</p>
|
|
<p>Sources: <a href="file:///D:\git\php\aot-compiler\src\Translator.php#L1162-L1187">src/Translator.php</a> · <a href="file:///D:\git\php\aot-compiler\src\Translator.php#L1272-L1292">src/Translator.php</a></p>
|
|
<h2>设计要点</h2>
|
|
<ul><li><strong><code>extension-<target>.cc</code> 故意不进共享头依赖</strong>:它的内容随任意类变化而改变,若纳入指纹会让每个 <code>.cc</code> 都失效,破坏增量构建。它自身作为生成单元拥有独立缓存项。</li><li><strong><code>--force</code> / <code>--profile</code> 强制失效</strong>:这两类参数会跳过全部缓存,确保 misc 文件也被重编(profiler 需 <code>PPROF_ON</code> 宏生效)。</li><li><strong>头文件依赖集排序后参与哈希</strong>,避免路径顺序差异导致误失效。</li></ul>
|
|
<p>Sources: <a href="file:///D:\git\php\aot-compiler\src\Translator.php#L1242-L1271">src/Translator.php</a> · <a href="file:///D:\git\php\aot-compiler\src\Translator.php#L1218-L1226">src/Translator.php</a></p>
|
|
<h2>相关阅读</h2>
|
|
<ul><li>缓存何时被查询 → <a href="pages/build-pipeline.html">构建流水线</a></li><li>编译命令从何而来 → <a href="pages/backend.html">编译器后端</a></li><li>整体性能分析 → <a href="pages/build-speed.html">构建速度与性能</a></li></ul></div></body></html> |