VM を開発しており、コンパイルされた関数を呼び出せるようにしたいと考えています。ただし、すべての関数が異なるシグネチャを持つことになる可能性があるため、私の計画では、すべての呼び出しを 2 つの可能なシナリオに一般化することです。つまり、戻り値もパラメーターもない関数の呼び出しと、void *
パラメーターを 1 つ受け取る関数の呼び出しです。
計画は、同様に使用することですthiscall
-すべてのパラメーターは、渡されたポインターの場所に適切に配置され、パラメーターは間接的に取得されます。少なくとも IMO では、スタックからそれらを読み取るよりも遅くなるべきではありません。
したがって、代わりに:
int foo(int a, int b) { return a+b; }
私は次のようなものを持つことができます:
void foo2(void *p) {
*(int*)p = *(int*)(p + 4) + *(int*)(p + 8);
}
だから私の質問は、このアプローチを使用すると何がうまくいかない可能性があるのですか? 私がすぐに言えることは、「暗闇の中で」動作するため、オフセットを正しく計算することが重要になるということです。また、すべての一時ファイルをユーザーが提供する必要があるため、少し不便です。私の VM コンパイラがこれら 2 つの問題に対処すると仮定すると、私は主にパフォーマンスについて心配しています。通常の関数を作成したくなく、通常の関数ごとにvoid *
ラッパーを作成したくありません。すべての関数にその規則を直接使用したいので、コンパイルされたコードで使用された場合、コンパイラは関数をインライン化するのにどれほど良い仕事をするのだろうと思わずにはいられませんか? 私が見落としている他のパフォーマンスへの影響の可能性はありますか(__fastcall
レジスタを1つ増やし、間接化を1つ減らすものを除く)?