next up previous contents index
Next: Up: エンコーディング規則 Previous: 述語名エンコード規則

  
定数構造体のコンパイル

 

ソースコード中に、全ての要素が定数であるような構造体が出現することがある。 これを定数構造体と呼ぶ。例を以下に示す。

[1, a, 10, [2, x]]
foo([1,2], bar, 3)

プログラムを実行する際には、最終的にこれらの構造をメモリ中に置くこととなる。 Naiveには、この構造の組み立ては動的に行う(つまり、定数でなかった場合 と同様に行う)が、すべてが定数である場合には、あらかじめ静的に 構造を作成しておくことが可能であり、これは、以下の意味での最適化になる。

例えば、foo([1,2,3])という構造は以下のようにメモリ中に置かれる。

  static Const q cons_const_0[] = {  /* (1) */
    NILATOM,
    makeint(3),
  };
  static Const q cons_const_1[] = {  /* (2) */
    makecons(cons_const_0),
    makeint(2),
  };
  static Const q cons_const_2[] = {  /* (3) */
    makecons(cons_const_1),
    makeint(1),
  };
  static Const q funct_const_3[] = { /* (4) */
    makesym(functor_foo_1),
    makecons(cons_const_2),
  };

Cでは、参照される変数を 参照する側よりも先に定義する必要があるため、ボトムアップに出力される。

まず(1)で、[3] がq型の配列cons_const_0 として出力されている。 makeintによりタグを付けていること、先にCDRが出ていることに注意。

次に(2)で、その[3]へのポインタにconsタグを付加し(makecons)、CDRとし、 さらにmakeint(2)をCARとして、[2,3]が作成される。 同様に、(3)で、[1,2,3]が作成される。

最後に(4)では、fooに対してのファンクタIDと、[1,2,3]へのポインタを 並べることにより、foo([1,2,3])が生成される。実際にこの構造を利用する時 には、makefunc(funct_const_3) としてコード中で参照される。

以上で判明するように、定数構造体については、その実体はヒープ中にとられない。 KLICのGCでは、ヒープ外へのポインタ(REF, CONS, FUNCタグつきのもの)を 発見したときには、そのポインタをコピーするだけで、その先はコピーの対象と しない。よって、定数構造体についてはGC時にコピーがなされない。 つまり、長期間参照されるような定数構造体については、 GC時にコピーをしない、という最適化も行われていることになる。



Sekita Daigo
1998-05-18