#r6rs.tex は algol60 というドキュメントクラスを使っているんですね。
#%% Modified from `report.cls' by Richard A. Kelsey. This is an attempt to
%% bring Jonathan Rees's ALGOL 60 style into the brave new world of 2e.
%% Changes marked with !!. All comments after this initial block are mine.
#higepon
素人考えだが、Scheme にはループないし、再帰ばかりだから Tracing JIT は合わない気がするのだけど。closure 単位で JIT コンパイルした方が良さそう?教えて偉い人!
##tracing jitやったことないからはっきりとはわからないけど、
#Schemeでも末尾再帰からループへの変換は容易だからそこは問題にはならないんじゃないかな。
#ただ、call/ccの存在がくせもので、呼んだ関数が必ず返ってくるとは限らない or 2度以上返ってくる可能性がある、っていうのは
#面倒な要素だと思う。
#Gaucheのjit実験ではGauche VMの構造を利用したので、末尾再帰やるためにトランポリンを利用せざるを得なかったんだけど
#そのためにVMのretで戻る先が動的に変わるのが分岐予測に悪影響を与えてたっぽい。
#とりあえず目に見える範囲でcall/retをjumpに置き換えてjitしちゃったら、そのへんの問題はなくなるから、継続の呼び出しとかが無い状況では性能が出るかもしれん。
#おっと。そんなところまで見ていただいているとは恐縮です。
#call/cc のことは全く頭にありませんでした。
#(たまたま目にしただけだけど)
#書いてて、call/ccの呼び出しによるフローの乱れはイレギュラーなんだから問題ではないような気もしてきた。
#素直に末尾再帰をjumpにしちゃうだけでtracing jitのメリットが享受できたりしないかなあ。
#ふーむ。末尾再帰じゃない再帰もある事を考えると、クロージャ単位で JIT コンパイルするのに比べて、あまり優位性がないような気もしますが。
#実装が複雑なのがちょっと嫌な感じですね。
#mzscheme の JIT コードを見ましたが挫折。
##いや、ここで言ってる「末尾再帰」は末尾呼び出しのことで、手続きの末尾位置から別の手続きを呼ぶ場合も直接入り口へのjmpにしちゃうってこと
#ああ。なるほど。誤読。
#ああでもそう簡単にはいかないか。
#前方向(逆かも)への jmp でループを検知するみたいな感じだったので
#Jmp, Jmp, Jmp, VM ret でループ終わりって感じになるのかな。
#それがうまくはまれば、複数の手続きにまたがる末尾呼び出しも綺麗にループになるんだけど
#Ypsilonのエントリであげられてるみたいにjitされない手続き呼び出しが入ってきたりすると元の木阿弥かなあ。
##詳細なレポートだ。これはありがたい。
#Tracing JIT はもう少し調査とプロトタイピングが必要そうだ。ありがとうございました。
##6:30 pm: YC will give an introduction to web scripting with mzScheme
[2] (remote presentation)
#ポールグレアム?
#いやそのYCはPLTグループの誰かだと思う。
#あ。人名なのですね。Scheme 界隈では YC といえばあの会社と言う、暗黙の了解があるのかと思っていました。
#いや、ちょっとそれは集団が違うと思う。"Paul GrahamのY Combinator" はあるていど知られてはいるけれど、いきなり"YC" で何の紹介もなしに出てくる程馴染みのあるものでもないだろうと思う。
#どっちかというと"YC"で通じる集団って起業家の集まりとかそういう方面じゃないかな。
#なるほど。なるほど。
#@ITの記事よみました(LLTV行けなかったので) かっこいいですねぇ〜 !! 書いたのは やっぱり西村さんか
#うーむ
#enamiさんのpthreadまわりのパッチがnetbasd-5枝にも適用されたのでわくわくしながらGaucheをmake testしたら、やっぱりthreadのテストで刺さる
#残念
#確実に刺さります? Linuxでも場合によっては刺さることがあるので、他の原因があることは確かなんですが。
##自分も忘れていたんですが、こっちの話のほうですね
#動作検証のためだけのパッチですが:
#Index: src/vm.c
===================================================================
--- src/vm.c (revision 6728)
+++ src/vm.c (working copy)
@@ -2270,6 +2270,13 @@
return vm->val0;
}
+static void mutex_unlock_cleanup(void *arg)
+{
+ ScmInternalMutex *lock = arg;
+
+ (void)SCM_INTERNAL_MUTEX_UNLOCK(*lock);
+}
+
static void process_queued_requests(ScmVM *vm)
{
void *data[3];
@@ -2307,6 +2314,7 @@
See Scm_ThreadStop() in ext/threads/threads.c */
if (vm->stopRequest) {
(void)SCM_INTERNAL_MUTEX_LOCK(vm->vmlock);
+ pthread_cleanup_push(mutex_unlock_cleanup, &vm->vmlock);
/* Double check, since stopRequest can be canceled between the above
two lines. */
if (vm->stopRequest) {
@@ -2318,7 +2326,7 @@
(void)SCM_INTERNAL_COND_WAIT(vm->cond, vm->vmlock);
}
}
- (void)SCM_INTERNAL_MUTEX_UNLOCK(vm->vmlock);
+ pthread_cleanup_pop(1);
}
}
#確実に刺さりますね