ひとり勉強会

ひとり楽しく勉強会

iseq_specialized_instruction

こちらについては YARV Maniacs 【第9回】 で丸々1回をさいて解説されています。引用させていただくと、

すでに述べたように「1 + 2」のようなプログラムは Ruby では「1.+(2)」と解釈されますが、コンパイル時にチェックして、

  • 呼び出すメソッドが "+"
  • 引数の数が 1 つ
  • ブロックなどは付かない

という場合には汎用の "send" 命令ではなく、"opt_plus" 命令にコンパイルします

という最適化だそうです。これを行うコードは

static int
iseq_specialized_instruction(yarv_iseq_t *iseq, INSN *iobj)
{
  if (iobj->insn_id == BIN(send)) {
    ID mid = SYM2ID(OPERAND_AT(iobj, 0));
    int argc = FIX2INT(OPERAND_AT(iobj, 1));
    VALUE block = OPERAND_AT(iobj, 2);
    VALUE flag = OPERAND_AT(iobj, 3);

    if (block == 0 && flag == INT2FIX(0)) {
      ...
      if (argc == 1) {
        ...
        if (mid == idPLUS) {
          insn_set_specialized_instruction(iobj, BIN(opt_plus));
        }

で、まさにそのまま解説の通りでした。insn_set_specialized_instruction もそのまんまです。

static int
insn_set_specialized_instruction(INSN *iobj, int insn_id)
{
  iobj->insn_id = insn_id;
  iobj->operand_size = 0;
  return COMPILE_OK;
}

では次。