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; }
では次。