published on
これは何 自作コンパイラ基盤(以下面倒なのでcilk) の内部構造の解説を,気が向いた時に書いていく.
ざっくり まず,IRがある IRに対して色々最適化したりもする.mem2regとかね.今は省略 DAG(Directed Acyclic Graph)形式に変換する
なぜDAGにするの? → 木構造のほうが命令パターンマッチしやすい Combine: 命令同士を合併したりする.LLVMなら,cmpとbrをbrcondにしたり. Legalize: アーキテクチャが対応していない(命令|型)を,対応している(命令|型)に変換したりする.例えば,cilkでは,ここでアドレス同士の足し算をLEA(x86ならね)に変換したりする. Instruction Selection: 名前の示す通り,適切なマシン命令を選択する.cilkでは,Rustのマクロで簡潔に命令パターンマッチを記述できるよう目指している. マシンアセンブリ向け形式(以下MachineInst)に変換する
ここからはアーキテクチャごとにやることが大きく違うと思う ここでは,cilkがある程度まともに対応しているx86を例にとる Phi Elimination: cilkのIRはSSAだからphiが存在する.ここではphiを取り除く Two Address Conversion: a = ADD b, cのような命令を,a = COPY b と a = ADD a, c に変換する. Register Allocation: 無限個の仮想レジスタに有限個の物理レジスタを割り当てる.cilkでは,普通レジスタ割当にはグラフ彩色を利用するところだけれど,Linear Scanのような何かを利用している.何かというのは,色々いじっている間にLinear ScanなのにSpill Weightのことを考えていたりして,正直よくわからなくなっているから. Prologue&Epilogue Insertion: 関数のプロローグ・エピローグを挿入する.push rbpとか. あとは細々したことをやったりする.浮動小数点数の即値をメモリ上に配置したり. MachineInstを実際のアセンブリに変換する
完成
published on
GitHubでコミットログ見てればなんとなく進捗はわかるけど,ちゃんと文章として書きだしたほうがいいかなって.
簡単な説明: JVM作るって何 突然ですが,皆さん,JVM使ってますか?
僕は(明示的には)使ってません.ですが 3 Billion Devices Run Java と言うくらいですから,世の中はJVMに支えられて動いているんでしょう.
だとしたら,どうしますか?
JVMを一から作ってみたくなりますよね?.
作り始めた動機は,これが全てです.
現状 以下の情報は 2018/Dec/29 時点での情報です. どれくらい実用的なの ちょうど今日で,作り始めてから一週間です.実用的なものなんて作れるわけ無いです.
じゃあどれくらい動くの javacを使って作ったクラスファイルを直接実行できる. == クラスファイルの読み込み自体は(実装してない部分もあるけど)だいたいOK 地道にJVMの命令を実装している.今は約70命令実装済み. JDKの提供してくれるSystem.out.printlnとかはまだ読み込んで利用することができない.(命令が実装できてないので) なので自作した.nativeなメソッドとして実装.以下実装済み System static final PrintStream outがあるだけ PrintStream println(int) println(double) println(String) String valueOf(int) StringBuilder append(int) append(String) toString() Object 形だけだけど. いくつかサンプル 以下のコードはぜんぶ動く(はず)
static {}を使った初期化ができる.System.outを作るときに必要だった. もちろん,ただのコンストラクタもあるよ. class A { public static final int x; static { x = 123; } A() { System. Read More...
published on
この記事は何? セキュリティキャンプ 修了生進捗 #seccamp OB/OG Advent Calendar 2018 20日目。
この記事では,セキュキャンが始まるちょっと前から作り始めた自作JSエンジン rapidus の進捗と,簡単に内部構造を説明していきたいと思います.
1. 概要 TL;DR だいたいJSっぽいコードを書いて実行できる (規格にまだ沿えていない) REPLがちょっと使える Tracing-JITに部分的に対応している (うまくいくと速い) 最近,Rustで書いたDLLをrequireから使えるようになった (もはやなんでもできる!) また最近,非同期処理の実装を始めた ちょっと詳しく 1. だいたいJS だいたいJSというのは,規格に沿えていなかったり 意外と基本的な機能が抜けている,という意味です.例えば,この記事を書いている時点ではObjectオブジェクトがなかったり(作り始めた),組み込みオブジェクトの機能が足りていなかったりします.
ですが大体はJSなので,そこそこのコードは動きます.ちゃんとプロトタイプチェーンで継承的なこともできますよ.
ミラーラビン素数判定法で素数(<2^32)を判定したい! というニッチな需要にも対応できます.
function prime(n) { if (n == 2 || n == 3) return true; if ((n & 1) == 0) return false; var d = n - 1; while ((d & 1) == 0) d = Math.floor(d >> 1); for (var k = 0; k < 20; k++) { var t = d; var x = modpow(1 + Math. Read More...