4

多型インラインキャッシュ(PIC)は、高価なルックアップ手順(通常はハッシュテーブルルックアップ)を避けるために、実際のメソッドをオブジェクトの型でキャッシュすることによって機能します。多型インラインキャッシュはどのように変更可能な型で動作しますか?

型オブジェクトが変更可能な場合(つまり、メソッドが実行時に別のものに変更された場合)、型の比較はどのように処理されますか?

私が思いついた考え方は、メソッドが調整されるたびに増えていく「クラスカウンタ」ですが、猿のパッチを当てた環境では非常に高価なようですそのクラスのメソッドが変更されていなくても、そのクラスのすべてのPIC。

この問題はJavaScriptに直接当てはまるため、良い解決策が必要であると確信しています.3つの大きなJavaScript仮想マシンにはすべてPICがあります。

+0

これは、災害のためのレシピのように聞こえます。 –

答えて

1

V8では、オブジェクトの「隠しクラス」(「マップ」はSELF用語である)を変更すると想定します。それはあなたの中で働くだろう猿はオブジェクト自体にパッチを当てた。

猿がクラスにパッチを当てていれば(これはJSですか?)、おそらくまれですので、すべてのPICを無効にすると思います。代わりに、新しいメソッドに直接ディスパッチするために古いメソッドを再コンパイルするかもしれません。

他の "ビッグ3"はPICを使用するとは思いません。私はリスフィッシュとトレーミーキーを意味すると思います。前者は通訳者であり、後者はトレースアプローチに焦点を当てています.PICについては何も聞いていません。実際、私はトレーモンキーがオブジェクトのために何かを冷やすとは思わないが、私は間違っている可能性がある。

0

型推論が使用される:

SpiderMonkeyのは、主にプロパティがアクセスされているかを決定するために型推論を使用します。タイプ推論がアクセスされているオブジェクトの正確な形状を見つけられない場合、SpiderMonkeyはPIC(多形インラインキャッシュ)を使用してルックアップの結果を保存します。

プロファイリングフィードバックの追加の形式は、ベースラインJITの多形インラインキャッシュです。多態インラインキャッシュは、Smalltalkコミュニティで生まれた動的ディスパッチを最適化するための古典的な手法です。 JavaScriptはなります動的型付け言語、オブジェクトの隠されたクラスに関するocassionally仮定している。もちろん、

、:

デ最適化は、型推論が失敗したときに起こるプロセスの名前です。その場合、V8は「非最適化」され、隠されたクラスのオブジェクトがチェックされているメソッド呼び出しの元のバージョンに戻る。

複数のコンパイラは仕事に、このために必要である:基本コンパイラと「オプティマイザ」:

技術的には、それは、コンパイラが実際に2つのコンパイラであることを意味しています。 (さらに、JSCとSpiderMonkeyについて話しているならば)。概念は非常に健全であり、驚異的なパフォーマンスをもたらすことができますが、ニュアンスがあります。エントリーポイントだけでなく、最適化されたコードがさまざまな場所で最適化されない可能性があります。つまり、環境(ローカル変数、引数、コンテキスト)マッピングされ、移動しました。

イオンは最適化コンパイラであり、デバッグモードのチェックでのコンパイルをサポートしていません。実際に、そのようなサポートを実装することは、その最適化が最高の無力なステップで呼び出しを行うため、疑わしいユーティリティです。デバッグモードをサポートするために、スタック上の最適化されたコードは最適化されず、ベースラインに救済されます。すなわち、スタック上のイオンフレームは、イオンコードが現在実行されているのと同じ位置に対応する再構築されたベースラインフレームで上書きされる。

デバッグが動的な非最適化を介して行われます:

私たちはより良い行うことができます。セルフ言語で具体化された90年代の夢はJavaScriptで生きています。我々は、最適化されたコードでさえもデバッグするために、スタックの置換技術を用いてSelfの動的な最適化を適応させることができる。 debug mode OSRのコアアイデアは簡単です。デバッグが必要な場合、JITedコードをスタック上で最適化して再コンパイルし、戻りアドレスをパッチします。スタックフレームに与える激しい暴力ではないにしても、それはほとんどエレガントだと言えるでしょう。でもゲッターまたはの呼び出しに、ヒープではよく知られた場所から、単純な負荷から何かにつながる可能性があり

この例では
function foo(o) { return o.f + o.g; } 

、プロパティがアクセス:

は、次のJavaScript関数を考えてみましょう。複雑なDOMトラップ。例えば、oがドキュメントオブジェクトで、fがページ内の要素の名前だった。ベースラインJITは、最初にこれらのプロパティアクセスを完全多型ディスパッチとして実行します。しかし、それがそうするように、それはそれがかかるステップを記録し、将来的に同様のアクセスを繰り返すために必要なステップのキャッシュになるように、その場所でヒープアクセスを変更します。たとえば、オブジェクトの基底からのオフセットが16のところにオブジェクトfがある場合、コードは変更され、最初に着信オブジェクトがオフセット16のプロパティfで構成されているかどうかを迅速に確認してからロードを実行します。これらのキャッシュは、生成されたマシンコードとして完全に表現されるため、インラインであると言われています。異なるオブジェクト構造に遭遇した場合、機械コードは、完全に動的なプロパティルックアップを行う前に以前に遭遇したオブジェクトタイプをスイッチオンするように修正されるため、多形性と言われています。 DFGがこのコードをコンパイルすると、インラインキャッシュが単一のオブジェクト構造に対して単相性に最適化されているかどうかがチェックされます。そうであれば、そのオブジェクト構造とそれに続く直接ロードのチェックだけが出されます。この例では、oが常に不変オフセットでプロパティfgを持つオブジェクトであった場合、DFGはoの1つのタイプチェックとそれに続く2つの直接ロードを出すだけでよいでしょう。

Data Flow Just-in-Time Compiler (DFG JIT) Optimization Pipeline

Faster-Than-Light Just-in-Time Compiler (FTL JIT) Optimization Pipeline

参照

関連する問題