JavaScriptの実行時コンパイラ(JUST-IN-TIME compiler)について

2021年4月8日JavaScript

JavaScriptは、コンパイラでもインタープリタでもなくの実行時コンパイラ(JUST-IN-TIME compiler)です。

実行時コンパイラとはなにかについてまとめました。

コンパイラ(compiler) vs インタープリタ(interpreter)

実行時コンパイラの前に、コンパイラとインタープリタについて簡単に説明します。
コンパイラ(compiler)は一度にまとめて全体のコードを機械語に翻訳してどのコンピュータにも運べるようなファイルに書きます。
このコンパイラでソースコードを機械語に翻訳するというステップのあとに、プログラムを実行します。
このようにコンパイラは2ステップになります。

インタープリタ(interpreter)はラインごとに翻訳して実行までを1ステップで行います。
そのためコンパイラとは異なり、ラインを翻訳しては実行、翻訳しては実行という動きになります。
インタープリタの問題は遅いという点です。

JavaScriptは実行時コンパイラ(JUST-IN-TIME compiler)

そしてJavaScriptはインタープリタでしたが、今のモダンなJavaScriptはハイブリッド型になっています。
それを実行時コンパイラ(JUST-IN-TIME compiler)といいます。
実行時コンパイラはコンパイラと同じく2ステップであり、全体のコードを翻訳してから実行しますが、その実行は翻訳後ただちに行われます。

JavaScriptの実行時コンパイラの動き

JavaScriptの実行時コンパイラの動きは次のようになっています。

ソースコードを解析する(Parsing)

Parsingという解析の段階で、AST(Abstract Syntax Tree、抽象構文木)というツリー状にします。
このパースは、一つ一つを切り分けて意味のある塊にします。そしてツリー状にするという流れになります。
このことにより、SyntaxError(構文エラー)を返してくれるようになります。
勘違いが起きやすいのですが、このASTとDOMのツリーは無関係です。

コンパイルする(Compilation)

パースして得られたASTをコンパイルして、01の羅列の機械語に翻訳します。

実行する(Execution)

そしてその機械語に翻訳されたコードをただちに実行します。
この実行という部分がコールスタックで行われます。

最適化する(Optimization)

そして上の実行をしている間により早く実行できるようにソースコードを最適化しています。
この最適化がモダンなV8エンジンのようにとても早い実行速度を実現している要因です。

パース、コンパイル、最適化は我々が触ることができない特別なスレッドで動いています。
つまりこれらはソースコードのメイン部分ではないところで実行されています。