とりあえず、現状では末尾再帰が上手いこと動かない場合がある。理由もある程度分かっていて、RETが一回足りてない(もしくは多すぎる)。 ただ、いまいち解決方法が分からない。う~ん。
ネイティブ内でVMのスタックの状態を保つようにしたらべらぼうに遅くなった。一応やらないよりは速いかくらい。あまりに切ないなぁとは思いつつ。なぜスタックの状態を保つようにしたか?これはcall/ccとかdynamic-windとかのVMのスタックと(現状)切っても切れない関係の機能をなんとかするため。でも逆に言えば、JITコンパイル時にこれらの呼び出しが無ければCスタックだけ使ってもOKなんだよねぇ?と思っているので(ちょっと自信ない)、その辺は頑張れば最適化できそう。
以下はとりあえずメモ。(一応ソースのコメントにも書いてるけど、頭の中を整理する意味合いも含めて)
【X86】(以外はまだ手をつけてない)
- レジスタは通常のeax、ecx、edx以外にebx、esi、ediも使う。
- eaxは基本的にVMのacレジスタをエミュレート。
- ecxとedxは汎用的に基本的にいつでも使用可能(なはず)。
- ebxは引数で渡されてくるVMのインスタンスを保持
- esiはargc引数、ediはargs引数を保持。
- ただ、ediに関しては別の用途に使った方がいいかもしれない。現状ではあんまり効率よく使われていない。
- 書けるところはアドレスべた書き。
- GREF_CALLとか
- Scheme手続きの呼び出しにはVMのスタックを使用。
- 遅い(VMのスタックを整備する必要がある)
- フレームを入れたり出したりするのが致命的
- スタックに直接関係ない普通の手続きはVMのスタックを使わないべき。
- 組み込みインストラクション(CARとかCDRとか)がまだ手抜き実装。
- インライン展開して無い。Cの関数呼んでる。
- これは後回しでもいいだろう。
なんだかランタイムさえあればアセンブラ書ける気がしてきた。(気がしてるだけ)。
No comments:
Post a Comment