Open3

Ribbon: C++をSchemeにする(準備)

okuokuokuoku

とりあえず、Schemeで書いたVMでSchemeのプログラムが実行できるところまでは来た。というわけで適当にVMを移植してみて単体動作するようにしたい。

まぁC++かな。。

C++はほぼScheme(迫真)

C++にはSchemeを作るのに必要なものがだいたい揃っている。

  • GC -- スマートポインタがある(スマートポインタはGCと呼ばないことが多いが)
  • 動的型 -- RTTIとDynamic cast
  • UTF-8文字列

ただ、単純なスマートポインタは循環参照によってメモリリークさせられるため、 アロケーションした全てのGCオブジェクトをリンクリストで繋ぎ たまに全オブジェクトを巡回して循環参照が無いか検出する必要がある。この方式はPythonやPHPが採用している。

http://dsas.blog.klab.org/archives/cat_50031085.html

(現在のPythonはGC中は双方向リンクリストの prev 側を潰してGC用のrefcountとして再利用することで、リンクリストによるオーバヘッドを2 wordに抑えている)

GCアルゴリズム

↑ の3ワード時代のアルゴリズムを実装する。これは4パスのアルゴリズムで、以下のようになる:

変数 内容
prev 前のオブジェクト
next 次のオブジェクト
gc_ref GCのrefcnt
ref スマートポインタのrefcnt
  1. 全てのオブジェクトの gc_refref に初期化する
  2. 全てのオブジェクトをスキャンし、 gc_ref を参照のぶんだけ減算する
  3. gc_ref がゼロになっていないオブジェクトと、そのオブジェクトから指されているオブジェクトをリンクリストから外す
  4. リンクリストに残ったオブジェクトはどこからも参照されていないので削除する

この "全てのオブジェクト" が本当に全てのオブジェクトでなければならないということはない。実際、Pythonは一度GCから生き残ったオブジェクトは別のリストに繋いでgenerational GC(世代別GC)としている。

このアルゴリズムの対象になるのは、いわゆるコンテナオブジェクト(他のオブジェクトを指す可能性があるオブジェクト)だけで良い。例えば、文字列やbytevector(JSで言うところのBuffer)は他のオブジェクトを指すことが無いので、単純な参照カウントだけでリークを防ぐことができる。

okuokuokuoku

型/クラスの設計

  • 数値型(64bits)
    • 0: singletonなオブジェクト(true / false / eof-object / nil)
    • 1: 整数(常に符号付)
    • 2: 浮動小数点数(double)
    • 3: 文字
  • オブジェクト(参照カウントされる)
    • 5: 非コンテナオブジェクト
      • String
      • Bytevector
    • 6: コンテナオブジェクト(GCされる)
      • HashTable
      • Rib
      • Vector

更に Value 型を用意し、スタック上にこれらの値または参照を保持できるようにする。浮動小数点数で64bitフルに必要になってしまうので、 Value 型は64bit値とその値の解釈を示すIDの両方を保持する必要がある。 ... って事はRTTI要らないじゃん。。あるいは Value の派生クラスを作ってそれで型を表現するか。。

... 実際に派生クラスで型を表現しようとすると、デストラクタを virtual に置くことになるので確実にvtblができてスタックを余計に消費することになる。まぁ後で真剣な実装を作るときの楽しみが減るから、今回は派生クラス -- いわゆる動的ポリモーフィズムで実装してみようかな。。

okuokuokuoku

そもそもGCライブラリを評価しないのか

うーん。。BoehmGCとかOlipanのような有名どころは見た方が良いのか。。?

https://chromium.googlesource.com/v8/v8/+/main/include/cppgc/

まぁパフォーマンスを気にしなければ(大問題)GCなんて一日で書けるので一旦は完全自作をコンセプトに作ってから考えても良いかもしれない。 ...であれば一旦はCで書くべきか。。

GitHubを適当に検索するだけでも色々ある。

https://github.com/m4drat/memplusplus

https://github.com/mmtk/mmtk-core

https://github.com/bullno1/ugc

https://github.com/mkirchner/gc

MMTkはRustに転向したようなのでRust版を作るときに検討することにしよう。。この中だとuGCが面白そうかな。