実行可能メモリ領域の管理

地味に難しい問題。
libffiは独自にアロケータを持って実行可能ページを管理している。
moshMinGWLinux/UNIXで実装方針が違っている。もちろんどっちかに統一したほうが良いし、僕は自分の実装の方が正しい方針だと考えている。

ページ単位方針

  • CPUにとってこのような保護属性を設定できるのはページが最小の単位
    • 仮にmallocで確保したヒープの属性を変更すると、その周囲の属性も変更されることになる
    • Windowsのように、複数の連続したページであっても属性の変更を保証していないOSもある*1
  • メモリ空間の管理戦略をカスタマイズ出来る
    • 生成したコードはメモリ空間の上位に纏めるといった処理が出来る。

デメリットはメモリがもったいないということで、libffiはその要求のために独自のメモリアロケータを持っている。

属性変更方針

ヒープの属性変更による実装にメリットが無いわけでもなくて、

  • mallocを自前で持つ必要がない
  • MMUの無いシステムでは単にスルーすれば良い

mallocと共通のインターフェースが使えるというのは重要な誤解で、一旦設定変更したページ属性は元に戻す必要があるページ属性を元に戻すと何か間違ったことが起こるので、一度設定した属性は元に戻すべきでない*2。(だからfreeやdeleteにアドレスを渡すことはできない)

*1:VirtualAllocで確保したページを単位として変更する必要がある。

*2:要するに同じページを共有するExecutableMemory全てが影響を受けてしまう。