Jun Inoue
jun.l****@gmail*****
2005年 10月 14日 (金) 05:25:07 JST
On Fri, 14 Oct 2005 03:16:46 +0900 Kazuki Ohta <mover****@hct*****> wrote: > 太田です。 > > ぼちぼち進めていますが、書いている内に変更したい所が出てきたので、もぅ一度仕様を > 投げてみます。 > > /* > * Object Representation Mechanism > * > * First, we assume ScmObj "S" which contains two ScmObj "X" and > * "Y" (e.g. ScmObj S { X, Y }). > * > * (0) LSB(Least Significant Bit) of "S" is called G-bit. > * > * (1) if S == "...00G", S is ConsCell. G-bit of S->X is used as > * marking bit of GC and G-bit of S-Y is always 0 for sweeping > * phase. この文言では「sweep の最中には s->Y == 0」と読めます。あと > が抜けて る。正しくは ...marking bit of GC. The G bit of S->Y denotes the finalization semantics. For a ConsCell, S->Y's G bit is always 0. とか、 ...marking bit of GC. S->Y's G bit is always set to 0, which helps determine the finalization semantics without a pointer. とか。 > * > * (2) if S == "...01G", S is imeediate value. Imeediate value is > * separated into these types by the value of least 1 or 2 or 5 > * bits of ((unsigned int S) >> 3). > * > * S Type > * ......1|01G : Char > * ------------------------------ > * .....10|01G : Integer > * ------------------------------ > * .000000|01G : #f > * .000100|01G : #t > * .001000|01G : () > * .001100|01G : EOF > * .010000|01G : Quote > * .010100|01G : Quasiquote > * .011000|01G : Unquote > * .011100|01G : UnquoteSplicing > * .100000|01G : Unbound > * .100100|01G : Undef > * > * (3) if S == "...10G", S is Closure. G-bit of S->X is used as > * marking bit of GC and G-bit of S-Y is always 0 for sweeping > * phase. 同上。 > * (4) if S == "...11G", S is other types. Type is separated by the > * value of least 3 or 5 bits of S->Y. Anyway, G-bit of S-Y is > * always 1 for sweeping phase. 同上。 > * S->Y Type > * .....01|1 : Symbol > * .....11|1 : Continuation > * ------------------------------ > * ...0000|1 : String > * ...0010|1 : Func > * ...0100|1 : Vector > * ...0110|1 : Port > * ...1000|1 : Values > * ...1010|1 : FreeCell > * ...1100|1 : C Pointer > * ...1110|1 : C Function Pointer > */ > > [ 変更点その1 ] > まず、即値(immediate value)の部分です。char型はポインタを一つ持っているだけですが、 > アラインメントの関係上(mallocは8byteにアラインメントされたメモリアドレスを返す)ので、下 > 位4ビットを占有出来ません。そこでCharだけを特別扱いしています。 > また、なるべくintegerの取れるビット数を増やしたいと思い、Integerも特別扱いしています。 即値型に pointer を持たせると leak します。最後に消える参照が stack に あったとき、sweep で見つからないので。 Other types に押し込んでもいいでしょうけど、Unicode 系を全部 UCS-4 に べったり符号化したものに canonicalize すると即値にもできます。Emacs の src のどっかに "RMS によれば世界中の文字をあらわすには 22 bits いるかも しれないので数 bit 予約云々" とあったので、24 あれば相当先まで大丈夫で しょう。元がどの符号化方式だったかの管理はハナから schemer に押しつけて るので無問題。 その場合、SCM_CHAR_VALUE() は shift でも mask でもいけますが、最近の processor では shift と mask の性能に有意差はあるんでしょうか > 誰か Shift の方が命令が短くなる… のは CISC の x86 ぐらい… か? とか思ったけ ど、どうせ取り出した側は C string に展開したい場合が殆んどだろうし、どう せ shift することになりますね。符号無しに cast するのを忘れずに。 > [ 変更点その2 ] > 次にその他(other types)の部分です。Symbol, Continuationは共にポインタを2つ抱えてい > る為、これもまたアラインメントの関係から特別視しています。 > String->len, Vector->len, Port->type等はint型なので、S-Yに無理矢理押し込めようと > 思っています。 ちゃんと見てないので間違ってるかもしれませんが、継続の pointer の一方は jmpbuf の横に置いておけばいいのでは? ScmObj Scm_CallWithCurrentContinuation(ScmObj proc, ScmEvalState *eval_state) { struct { jmp_buf state; void *opaque; } env; ScmObj cont = SCM_FALSE; ScmObj ret = SCM_FALSE; ... } どうせ symbol は特別扱いなのでどうでもいいっちゃどうでもいいんですが、 将来ちゃんとした module unloading を実装することがあれば vcell が消える ので、やっといてもいいんじゃないかと思います。 それと len とか type は無理矢理とかじゃなくて初めから S->Y に入れるつも り…だったんですが書いてませんでしたね。失礼。 > FreeCellは廃止ですかね。 Others の ID が余れば残しましょう。 -- Jun Inoue jun.l****@gmail*****