↓でだらだらと書いてる裏で何をやってるのか簡単に説明しときます。storage-compact.h に macro support を追加しようとしたところ、諸々の理由によりこのまま使うのは良くないと判断したので、自分で別のを書き直してます。後で merge するか差し替えるかはまだ決めてない。Merge するにしてもほぼ差し替えと同じになりそうな雰囲気ですが。

Macro 共を整理した後、algorithmic な変更を加えていて、今関数型で詰まってます。FUNCP() なやつ (と CPOINTER かな) は LSB を分割して保存することになりますが、今のところ and で取り出した bit をもう一方の word に押し込んで、extraction のときに mask で取り出して or してますが:

void
store(scm_obj o, scm_func f, scm_func_typecode t)
{
  o->car = f & ~1;
  o->cdr = ((f & 1) | (t << 1)) << offset;
}

scm_func
load(scm_obj o)
{
  return o->car | ((o->cdr >> offset) & 1);
}

(tag 操作は省略) これを word 全体を xor するようにしたら、and が一つ減って嬉しかろう、と。

void
store(scm_obj o, scm_func f, scm_func_typecode t)
{
  o->cdr = ((f & 1) | (t << 1)) << offset;
  o->car = f ^ o->cdr;
}

scm_func
load(scm_obj o)
{
  return o->car ^ (o->cdr >> offset);
}

Typecode だけ set! する場合が遅くなりますが、使わないのでいいでしょう (C pointer の方は違う algorithm を使うか、aligned_pointer 型と分ける)。で、実際にやってみると初期化 code が無茶苦茶肥大化したのでさあどうしよう、というところ。定数ばっかり + 単純な代入繰り返しだから最適化が効くと思ったんだけどなあ。INIT() と FIN() を macro 化するのはいいかもしれない。