LoginSignup
2
0

More than 5 years have passed since last update.

mruby-inlineドキュメント

Last updated at Posted at 2016-06-26

mrubyでメソッドをインライン化を実現するためのmrbgemです。
ソースはここにあります。
https://github.com/miura1729/mruby-inline
効果は、速くなったり、遅くなったり、場合によります。でも、将来的にはメソッドのインライン化は避けて通れない最適化だと思っています。
はっきり言ってmruby-inlineは単独では無意味ですが、色々知見を得るのに有意義だと考えています。

使い方

インライン化したいメソッドがあるクラスにInlineモジュールをincludeします。
クラス定義のメソッド定義後に、インライン化したいメソッドに対して、

make_inline_method :メソッド名

とします。これで、そのメソッドを呼び出すときにインライン化します。
たとえば、こんな感じのコードになります。

class Vec
  include Inline

  def initialize(x, y, z)
    @x = x
    @y = y
    @z = z
  end

  def vlength
    Math.sqrt(@x * @x + @y * @y + @z * @z)
  end
  make_inline_method  :vlength
end

仕組み

このmrbgemの仕組みを簡単に説明します。
make_inline_methodで指定されたメソッドは、

  • メソッドの実体(Procオブジェクト)がメソッド名をキーにしたハッシュ(inline_method_list)に格納されます
  • メソッドそのものはundefされ未定義になります

そのメソッドが呼ばれた場合、未定義になっていますので、当然method_missingが呼ばれます。method_missingメソッドでは、

  • inline_method_listからメソッド実体のProcオブジェクトを取り出し
  • そのProcオブジェクトからirep(callee_irep)を取り出します。
  • 呼び出し元のirep(caller_irep)をcallinfoから取り出します。
  • caller_irepのiseqをcallee_irepが足せるくらい大きく拡張した後で、callee_irepを後にくっつけます。この際、レジスタの番号とかをインライン化に合わせて変えます。この辺のパッチの当て方は章を代えて説明します。
  • 最後にこのメソッドを呼び出したsend命令をiseqの後ろにくっつけた命令列にjumpするようにパッチを当てます。

命令のパッチ当て

当然のことながらそのままインライン化したい命令列をくっつけただけではうまくいきません。メソッドはR0にselfが入り、続いて引数・ブロック・ローカル変数・作業レジスタと続いています。
しかし、メソッド呼び出しのお膳立てをする前は当然そうなっていません。ただ、規則性があり、R0がOP_SENDのAオペコードで示されるレジスタ番号(vm.cではaまたはaccで参照されます)になっています。そこで、regsの値をいじる代わりにR0をRaにR1をRa+1に書き換えるわけです。
書き換えるのは簡単ですが、命令によってオペランドのどこがレジスタか不規則です。そのため、命令のオペランドの型を示すデータベースを配列で持つことにしました。その配列が、opinfo.h( https://github.com/miura1729/mruby-inline/blob/master/src/opinfo.h )で定義されています。

大まかにはこれでいいのですが、これでは駄目な場合があります。命令毎に細かくパッチを当てていきます。たとえば、こんな命令です。

  • OP_RETURN
    OP_SENDで呼び出したわけではないので、OP_RETURNを呼び出すとおかしくなります。これはJMP命令に書き換えます。

  • OP_ENTER
    この命令はOP_SENDでおぜん立てされた新鮮なフレームじゃないと動かない命令です。大部分はNOPに変えても大丈夫です。大丈夫じゃない時はインライン化はあきらめてください。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0